Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1단계 - 자동차 경주 구현] 인치(한창희) 미션 제출합니다. #20

Merged
merged 72 commits into from
Feb 13, 2021
Merged
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
484f993
feat: init project
hchayan Feb 6, 2021
21fe6b8
feat: html id 추가
hchayan Feb 8, 2021
9238fda
test: 자동차 섹션, 횟수 섹션, 진행과정 섹션이 순서대로 보여진다 테스트 구현
hchayan Feb 8, 2021
b96b19c
test : 자동차 이름 입력 순서대로 자동차를 생성하는 테스트코드 구현
hchayan Feb 8, 2021
bcb5527
test: 입력 유효성 테스트 구현
hchayan Feb 8, 2021
895b750
test: 시도횟수보다 화살표 횟수 이하 테스트 구현
hchayan Feb 8, 2021
54a64e5
test: 우승자 출력 테스트 구현
hchayan Feb 8, 2021
8c815e8
test: 자동차 게임 리셋 테스트 구현
hchayan Feb 8, 2021
b245d23
feat: JS MVC 패턴 구조화, 메서드 설계
hchayan Feb 8, 2021
2bb1f02
test : window:alert 리팩토링
hchayan Feb 9, 2021
4620fb2
test: 인덱스값 중간변수 도입 및 중복이름 유효성 테스트 구현
hchayan Feb 9, 2021
e545664
docs: 구현 테스트 목록 작성
hchayan Feb 9, 2021
856b97c
test: 시도 횟수 입력 예외 케이스 추가
hchayan Feb 9, 2021
8de0a1e
feat : getCars, setCars, getCount, setCount 메소드 구현
hchayan Feb 9, 2021
50ee2ae
feat : showCount 메소드 구현
hchayan Feb 9, 2021
abcfa48
feat: showProcesss 메서드 구현
hchayan Feb 9, 2021
f8f46e6
feat: showResult 메서드 구현
hchayan Feb 9, 2021
1006b72
feat: resetCount, resetProcess, resetResult 메서드 구현 및 view 클래스내 메서드명 수정
hchayan Feb 9, 2021
024fb2d
refactor: template 클래스 분리
hchayan Feb 9, 2021
1fc175c
test: 테스트 파일 경로 변경
hchayan Feb 10, 2021
9a065cf
feat: handler 메서드 구현
hchayan Feb 10, 2021
7fa13ca
feat: getCarsInput, getCountInput 메서드 구현
hchayan Feb 10, 2021
93662c3
feat: manageCars 메서드 구현
hchayan Feb 10, 2021
1028d1d
feat : manageCount 메소드 구현
hchayan Feb 10, 2021
d4d428c
feat : manageResult 메소드 구현 및 주석 제거
hchayan Feb 10, 2021
b48d473
feat: statGame, play 메서드 구현
hchayan Feb 10, 2021
8f6959f
feat : goStop 메소드 구현
hchayan Feb 10, 2021
206f940
feat: getWinners 메소드 구현
hchayan Feb 10, 2021
326eade
feat : reset 메소드 구현
hchayan Feb 10, 2021
9285a4b
feat : JS 모듈화 및 핸들러 콜백 방식 변경
hchayan Feb 10, 2021
414b2d5
feat : Valid class생성 및 isCarValid 메소드 구현
hchayan Feb 10, 2021
a54b1d5
feat: isCountVaild 구현
hchayan Feb 10, 2021
6b09abc
test: count 입력 유효성 테스트 alert 메세지 변경
hchayan Feb 10, 2021
cebaaef
feat: vaild 클래스 모듈화
hchayan Feb 10, 2021
b563104
feat: 자동차 이름 공백 제거 구현
hchayan Feb 10, 2021
b1ab712
fix: 자동차 게임 수행 과정 참조 오류 해결
hchayan Feb 10, 2021
bb7febe
feat: util 클래스 생성, generateRandomNumber 메서드 구현
hchayan Feb 10, 2021
539787f
fix: DOM 참조변수명 수정 및 result template 수정
hchayan Feb 10, 2021
ae4c2a2
fix: process template 수정
hchayan Feb 10, 2021
d7075e8
fix: valid 순환방식 some으로 변경
hchayan Feb 10, 2021
a7dcb36
fix: count 입력 소수점 검사 방식 수정
hchayan Feb 10, 2021
e68b8f3
test: count 입력 양식이 숫자이기에 숫자 아닌 input 테스트 제거
hchayan Feb 10, 2021
8378157
feat: resetCar 메서드 구현
hchayan Feb 10, 2021
e1ee575
test: 다시시작버튼 클릭 테스트 방법 변경
hchayan Feb 10, 2021
6f45692
feat: html 초기 코드 작성
hchayan Feb 10, 2021
b941e8b
feat: constants 폴더 구조화 및 상수 변수 구현
hchayan Feb 10, 2021
74e3f22
feat: 에러 message 상수화
hchayan Feb 10, 2021
00baf1d
refactor: 상수 변수 객체화
hchayan Feb 10, 2021
e1609c4
refactor: 상수 변수 적용
hchayan Feb 10, 2021
7788178
refactor: 프로젝트 구조화
hchayan Feb 10, 2021
6836ad3
fix : 랜덤 최소값 수정
hchayan Feb 10, 2021
243ca54
fix : 자동차 이름 중간에 공백 허용
hchayan Feb 10, 2021
fdc4163
feat: count 공백, 문자열 입력 예외처리 구현
hchayan Feb 10, 2021
7d0f807
test: 입력 시도 횟수 공백 테스트 추가
hchayan Feb 10, 2021
66e138c
test: 선택자 단순화
hchayan Feb 10, 2021
472da37
fix: 결과 출력 템플릿 수정
hchayan Feb 10, 2021
f671b28
docs: 리드미 구현 목록 작성
hchayan Feb 10, 2021
f9f8e0e
refactor: 코드 컨벤션 수정
hchayan Feb 10, 2021
d23557c
refactor: valid 메서드 분리, 모듈화
hchayan Feb 10, 2021
f393909
refactor: 중간변수 사용
hchayan Feb 10, 2021
ebd4322
test: describe명 변경
hchayan Feb 10, 2021
7f79771
docs: 리드미 프로젝트 프리뷰 추가
hchayan Feb 10, 2021
24853fe
refactor: 코드 컨벤션 개선
hchayan Feb 10, 2021
2e8db23
test: 자주사용한 type, click, should 메서드 클래스화를 통한 재사용 구현
hchayan Feb 12, 2021
5d1244f
refactor: template 파일 layout 폴더로 이동
hchayan Feb 12, 2021
6829525
refactor: js 클래스 export 후 생성자 사용 방식으로 개선
hchayan Feb 12, 2021
bbf60c6
refactor: js 접근자 프로퍼티 적용
hchayan Feb 12, 2021
f3b9498
refactor : querySelctor 문 변수화
hchayan Feb 12, 2021
297607c
refactor: setCar 제거후 reset, moveCar, initCar 메서드 구현
hchayan Feb 12, 2021
349075b
refactor: init 메서드 이용한 생성자 사용 구현
hchayan Feb 12, 2021
a26b91b
chore: cypress 패키지 dev dependencies로 이동
hchayan Feb 12, 2021
8fea822
test: 자동차, 시도횟수 입력 과정 함수화
hchayan Feb 13, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 20 additions & 41 deletions README.md
Expand Up @@ -14,55 +14,34 @@

## 🔥 Projects!
<p align="middle">
<img width="400" src="https://techcourse-storage.s3.ap-northeast-2.amazonaws.com/7c76e809d82a4a3aa0fd78a86be25427">
<img width="500" src="./documents/preview.gif">
</p>

### 🎯 step1
- [ ] 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다.
- [ ] 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다.
- [ ] 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다.
- [ ] 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다.
- [ ] 전진하는 조건은 0에서 9 사이에서 random 값을 구한 후 random 값이 4 이상일 경우 전진하고, 3 이하의 값이면 멈춘다.
- [ ] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다.
- [ ] 우승자가 여러명일 경우 ,를 이용하여 구분한다.

### 🎯🎯 step2
- [ ] 자동차 경주 게임의 턴이 진행 될 때마다 1초의 텀(progressive 재생)을 두고 진행한다.
- [ ] 애니메이션 구현을 위해 setInterval, setTimeout, requestAnimationFrame 을 활용한다.
- [ ] 정상적으로 게임의 턴이 다 동작된 후에는 결과를 보여주고, 2초 후에 축하의 alert 메세지를 띄운다.
- [ ] 위 기능들이 정상적으로 동작하는지 Cypress를 이용해 테스트한다.
### 🧾 구현 테스트 목록
- [x] 자동차 이름을 입력하고 확인 버튼을 누르면 시도 횟수 입력 영역이 보여진다
- [x] 시도 횟수를 입력하고 확인 버튼 클릭하면 자동차 게임 진행 영역이 보여진다
- [x] 자동차 이름을 입력한 순서대로 자동차들을 생성한다
- [x] 시도 횟수보다 화살표의 개수가 적거나 같아야한다
- [x] 가장 많은 화살표를 가지고 있는 자동차의 이름이 우승자에 있어야 한다
- [x] 다시 시작하기 버튼을 누르면 자동차 입력 영역만 보이고, 입력값이 초기화된다
- [x] 자동차 이름이 5글자를 초과하면 안된다
- [x] 자동차 이름이 공백이면 안된다
- [x] 자동차 이름이 중복이면 안된다
- [x] 입력한 시도 횟수가 자연수가 아니면 안된다

<br>

## ⚙️ Before Started

#### <img alt="Tip" src="https://img.shields.io/static/v1.svg?label=&message=Tip&style=flat-square&color=673ab8"> 로컬에서 서버 띄워서 손쉽게 static resources 변경 및 확인하는 방법

로컬에서 웹서버를 띄워 html, css, js 등을 실시간으로 손쉽게 테스트해 볼 수 있습니다. 이를 위해서는 우선 npm이 설치되어 있어야 합니다. 구글에 `npm install` 이란 키워드로 각자의 운영체제에 맞게끔 npm을 설치해주세요. 이후 아래의 명령어를 통해 실시간으로 웹페이지를 테스트해볼 수 있습니다.

```
npm install -g live-server
```

실행은 아래의 커맨드로 할 수 있습니다.

```
live-server 폴더명
```
### 🎯 구현 목록
- [x] 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다.
- [x] 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다.
- [x] 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다.
- [x] 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다.
- [x] 전진하는 조건은 0에서 9 사이에서 random 값을 구한 후 random 값이 4 이상일 경우 전진하고, 3 이하의 값이면 멈춘다.
- [x] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다.
- [x] 우승자가 여러명일 경우 ,를 이용하여 구분한다.

<br>

## 👏 Contributing

만약 미션 수행 중에 개선사항이 보인다면, 언제든 자유롭게 PR을 보내주세요.

<br>

## 🐞 Bug Report

버그를 발견한다면, [Issues](https://github.com/woowacourse/javascript-racingcar/issues) 에 등록 후 @eastjun에게 dm을 보내주세요.

<br>

## 📝 License

Expand Down
1 change: 1 addition & 0 deletions cypress.json
@@ -0,0 +1 @@
{}
5 changes: 5 additions & 0 deletions cypress/fixtures/example.json
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}
130 changes: 130 additions & 0 deletions cypress/integration/racingcar.spec.js
@@ -0,0 +1,130 @@
describe("ui-play", () => {
before(() => {
cy.visit("http://localhost:5500/");
});

it("자동차 섹션을 입력하고 버튼을 클릭하면 횟수 영역이 보여진다", () => {
cy.get("#car-input").type("a,b,c,d");
cy.get("#car-btn").click();
cy.get("#count").should("have.css", "display", "block");
});

it("시도 횟수를 입력하고 버튼을 클릭하면 진행 영역이 보여진다", () => {
cy.get("#count-input").type(5);
cy.get("#count-btn").click();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#***-input을 입력하고 #***-btn을 클릭하는 동작이 중복되는 것 같습니다 😄
해당 일련된 동작을 제공하는 함수를 만들어보는 건 어떨까요?

cy.get("#process").should("have.css", "display", "block");
});

it("자동차 이름을 입력한 순서대로 자동차들을 생성한다", () => {
const cars = ["a", "b", "c", "d"];
cy.get(".car-player").each((v, i, arr) => {
cy.get(v).should("have.text", cars[i]);
});
});

it("시도 횟수보다 화살표의 개수가 적거나 같아야한다", () => {
cy.get(".process-car").each(v => {
if (v.find(".forward-icon").length > 0) {
cy.get(v).find(".forward-icon").its("length").should("be.lte", 5);
}
});
});

it("가장많은 화살표를 가지고 있는 차의 이름이 우승자에 있어야 한다", () => {
let largestCount = 0;
cy.get(".process-car")
.each(v => {
if (v.find(".forward-icon").length > largestCount) {
largestCount = v.find(".forward-icon").length;
}
})
.then(() => {
cy.get(".process-car").each(v => {
if (v.find(".forward-icon").length === largestCount) {
const winner = v.find(".car-player")[0].outerText;
cy.get("#result-winner").contains(winner);
}
});
});
});

it("다시 시작하기 버튼을 클릭하면 자동차 섹션만 보이고, 입력 값이 초기화된다", () => {
cy.get("#reset-btn").click();
cy.get("#count").should("have.css", "display", "none");
cy.get("#process").should("have.css", "display", "none");
cy.get("#result").should("have.css", "display", "none");
cy.get("#process").children().should("not.exist");
cy.get("#car-input").should("have.value", "");
});
});

describe("ui-input-vaild-check", () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

입력 테스트 (비즈니스), 레이아웃 테스트를 나눈 것은 아주 센스있는 코딩인 것 같습니다 😄 👍 👍

beforeEach(() => {
cy.visit("http://localhost:5500/");
cy.window()
.then(win => cy.stub(win, "alert"))
.as("alertStub");
});

it("자동차 이름이 5글자 초과하면 alert 출력", () => {
cy.get("#car-input").type("overFive,a,b,c,d");
cy.get("#car-btn").click();
cy.get("@alertStub").should(
"be.calledWith",
"자동차 이름의 길이는 최대 5글자 입니다."
);
});

it("자동차 이름에 공백 있으면 alert 출력", () => {
cy.get("#car-input").type("a,b,,c,d");
cy.get("#car-btn").click();
cy.get("@alertStub").should(
"be.calledWith",
"자동차 이름은 공백이 될 수 없습니다."
);
});

it("자동차 이름에 중복 있으면 alert 출력", () => {
cy.get("#car-input").type("a,b,a,c,d");
cy.get("#car-btn").click();
cy.get("@alertStub").should(
"be.calledWith",
"자동차 이름은 중복이 될 수 없습니다."
);
});

it("입력한 시도 횟수가 공백이면 alert 출력", () => {
cy.get("#car-input").type("a,b,c,d");
cy.get("#car-btn").click();
cy.get("#count").should("have.css", "display", "block");
cy.get("#count-btn").click();
cy.get("@alertStub").should(
"be.calledWith",
"시도 횟수는 공백 혹은 문자가 될 수 없습니다."
);
});

it("입력한 시도 횟수가 0 이하면 alert 출력", () => {
cy.get("#car-input").type("a,b,c,d");
cy.get("#car-btn").click();
cy.get("#count").should("have.css", "display", "block");
cy.get("#count-input").type(-1);
cy.get("#count-btn").click();
cy.get("@alertStub").should(
"be.calledWith",
"시도 횟수는 0보다 작거나 같을 수 없습니다."
);
});

it("입력한 시도 횟수가 소수면 alert 출력", () => {
cy.get("#car-input").type("a,b,c,d");
cy.get("#car-btn").click();
cy.get("#count").should("have.css", "display", "block");
cy.get("#count-input").type(4.21);
cy.get("#count-btn").click();
cy.get("@alertStub").should(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Input -> btn -> should 와 같은 패턴이 많이 보이네요~ 이런 것도 함수로 제공하면 좋을 것 같습니다 :)
아래와 같이 짤 수도 있겠네요!

class CypressWrapper {
  type = (name, value) => {
    try {
       this._getCy(name).type(value)
    } catch (err) {
      new Error(err)
    }

    return this
  }

  click = (name, params) {
    try {
      this._getCy(name).click(params)
    } catch (err) { 
      new Error(err)
    }
    return this
  }

  should(name, ...param) {
    try {
      this._getCy(name).should(...param)
    } catch(err) {
      new Error(err)
    }

    return this
  }

  _getCy(name) {
    return cy.get(name)
  }
}

const cw = new CypressWrapper()

function testCar() {
  cw
    .type('#car-input', 'a,b,c,d')
    .click('#car-btn')
    .should('@count', 'have.css', 'display', 'block');
}

describe('ui-input-vaild-check', () => {
  ...
  it("입력한 시도 횟수가 소수면 alert 출력", () => {
    testCar()
    cw
      .type('#count-input', 4.21)
      .click('#count-btn')
      .should('@alertStub', 'be.calledWith', '시도 횟수는 소수가 될 수 없습니다.')
  })
})

"be.calledWith",
"시도 횟수는 소수가 될 수 없습니다."
);
});
});
21 changes: 21 additions & 0 deletions cypress/plugins/index.js
@@ -0,0 +1,21 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}
25 changes: 25 additions & 0 deletions cypress/support/commands.js
@@ -0,0 +1,25 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
20 changes: 20 additions & 0 deletions cypress/support/index.js
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'

// Alternatively you can use CommonJS syntax:
// require('./commands')
Binary file added documents/preview.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 14 additions & 45 deletions index.html
Expand Up @@ -16,60 +16,29 @@ <h1 class="text-center">🏎️ 자동차 경주 게임</h1>
예시) EAST, WEST, SOUTH, NORTH
</p>
</section>
<section>
<div class="d-flex">
<input type="text" class="w-100 mr-2" placeholder="자동차 이름" />
<button type="button" class="btn btn-cyan">확인</button>
</div>
</section>
<section class="mt-5">
<p>시도할 횟수를 입력해주세요.</p>
<section id="car">
<div class="d-flex">
<input type="number" class="w-100 mr-2" placeholder="시도 횟수" />
<button type="button" class="btn btn-cyan">확인</button>
<input
type="text"
id="car-input"
class="w-100 mr-2"
placeholder="자동차 이름"
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

input 태그의 다양한 속성들을 이용해 사용자의 입력에 대한 접근을 제한해보면 어떨까요?

/>
<button type="button" id="car-btn" class="btn btn-cyan">
확인
</button>
</div>
</section>
<section id="count" class="mt-5"></section>
</div>
</div>
<div class="d-flex justify-center mt-5">
<section class="mt-4">
<div class="d-flex">
<div>
<div class="car-player mr-2">EAST</div>
<div class="forward-icon mt-2">⬇️️</div>
<div class="forward-icon mt-2">⬇️️</div>
</div>
<div>
<div class="car-player mr-2">WEST</div>
<div class="forward-icon mt-2">⬇️️</div>
</div>
<div>
<div class="car-player mr-2">SOUTH</div>
<div class="d-flex justify-center mt-4">
<div class="relative spinner-container">
<span class="material spinner"></span>
</div>
</div>
</div>
<div>
<div class="car-player mr-2">NORTH</div>
<div class="d-flex justify-center mt-4">
<div class="relative spinner-container">
<span class="material spinner"></span>
</div>
</div>
</div>
</div>
</section>
<section id="process" class="mt-4"></section>
</div>
<div class="d-flex justify-center mt-5">
<section>
<h2>🏆 최종 우승자: EAST, WEST 🏆</h2>
<div class="d-flex justify-center">
<button type="button" class="btn btn-cyan">다시 시작하기</button>
</div>
</section>
<section id="result"></section>
</div>
</div>
<script type="module" src="src/js/index.js"></script>
</body>
</html>
5 changes: 5 additions & 0 deletions package.json
@@ -0,0 +1,5 @@
{
"dependencies": {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cypress는 빌드에 연관있는 툴은 아니므로, --dev 옵션을 주어 devDependencies로 이관하는게 좋지 않을까요?

"cypress": "^6.4.0"
}
}
22 changes: 22 additions & 0 deletions src/js/constants/constant.js
@@ -0,0 +1,22 @@
export const RANDOM = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수를 별도의 파일에 저장하는 기법은 아주 좋은 방법입니다 👍 👍

MAX_NUM: 9,
MIN_NUM: 0,
};

export const INIT = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

init 값도 여기서 조절할 수 있게 되니 좋아보이네요!

CARS: [],
FORWARD: 0,
COUNT: 0,
};
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

클래스에 대한 init을 상수로 관리하는 건 상황에 따라 다르겠지만,
무작정 사용하지 말고, 다시 한번 생각해보고 사용해보면 좋을꺼 같아요!


export const GAME = {
FORWARD_STANDARD_NUM: 4,
GO_NUM: 1,
STOP_NUM: 0,
};

export const VALID = {
CARNAME_MAX_LENGTH: 5,
CARNAME_MIN_LENGTH: 1,
COUNT_MIN_NUM: 1,
};
9 changes: 9 additions & 0 deletions src/js/constants/message.js
@@ -0,0 +1,9 @@
export const ERROR_MESSAGE = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메시지도 별도로 저장하니 좋은 것 같습니다! 👍 👍

OVER_CARNAME_MAX_LENGTH: "자동차 이름의 길이는 최대 5글자 입니다.",
BLANK_CARNAME: "자동차 이름은 공백이 될 수 없습니다.",
DUPLICATE_CARNAME: "자동차 이름은 중복이 될 수 없습니다.",

ZERO_OR_MINUS_COUNT: "시도 횟수는 0보다 작거나 같을 수 없습니다.",
ISNAN_COUNT: "시도 횟수는 공백 혹은 문자가 될 수 없습니다.",
FLOAT_COUNT: "시도 횟수는 소수가 될 수 없습니다.",
};