From 8a2b23e741c4f3282f5a1dab7eb5e255958ebea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Mon, 28 Oct 2024 20:59:46 +0900 Subject: [PATCH 01/14] =?UTF-8?q?[docs]=20:=20README=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index e078fd41f..20c545e0b 100644 --- a/README.md +++ b/README.md @@ -1 +1,30 @@ # javascript-racingcar-precourse +# 자동차 경주 + +## 과제 진행 요구 사항 +미션은 자동차 경주 저장소를 포크하고 클론하는 것으로 시작한다. +기능을 구현하기 전 README.md에 구현할 기능 목록을 정리해 추가한다. +Git의 커밋 단위는 앞 단계에서 README.md에 정리한 기능 목록 단위로 추가한다. +AngularJS Git Commit Message Conventions을 참고해 커밋 메시지를 작성한다. +자세한 과제 진행 방법은 프리코스 진행 가이드 문서를 참고한다. + +# 기능 요구 사항 + +[] 입력 받기 + - ',' 기준으로 이름 입력 (5자 이하) + - 시도 횟수 입력 +[] 자동차 경주 게임 + - n번 전진 시도 + - 이름별로 무작위 값 >= 4 인 경우 전진 + - 출력 +[] 최종 우승자 출력 +[] ERROR 출력 + +주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. +각 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. +자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다. +사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. +전진하는 조건은 0에서 9 사이에서 무작위 값을 구한 후 무작위 값이 4 이상일 경우이다. +자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다. +우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다. +사용자가 잘못된 값을 입력할 경우 "[ERROR]"로 시작하는 메시지와 함께 Error를 발생시킨 후 애플리케이션은 종료되어야 한다. \ No newline at end of file From de7b83c5d131b0758e39f0c7e51154940f1fc933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Mon, 28 Oct 2024 21:23:53 +0900 Subject: [PATCH 02/14] =?UTF-8?q?[feat]=20(View)=20:=20input=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 15 +++++++++------ src/App.js | 9 ++++++++- src/View.js | 22 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 src/View.js diff --git a/README.md b/README.md index 20c545e0b..e5757e600 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,17 @@ AngularJS Git Commit Message Conventions을 참고해 커밋 메시지를 작성 # 기능 요구 사항 -[] 입력 받기 - - ',' 기준으로 이름 입력 (5자 이하) - - 시도 횟수 입력 -[] 자동차 경주 게임 - - n번 전진 시도 +[] 자동차 이름 입력 받기 + [] ',' 기준으로 이름 입력 (5자 이하) + [] 에러처리 +[] 시도 횟수 입력 + [] 유효한 숫자 아닌 경우 에러처리 +[] 자동차 경주 + [] n번 전진 시도 - 이름별로 무작위 값 >= 4 인 경우 전진 - - 출력 + - 해당 결과 출력 [] 최종 우승자 출력 + [] 공동 우승 처리 [] ERROR 출력 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. diff --git a/src/App.js b/src/App.js index 091aa0a5d..1aa917107 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,12 @@ +import View from "./View.js"; + class App { - async run() {} + #input = new View(); + async run() { + const names = await this.#input.readInputCar(); + const raceCount = await this.#input.readInputRaceCar(); + + } } export default App; diff --git a/src/View.js b/src/View.js new file mode 100644 index 000000000..0331176f2 --- /dev/null +++ b/src/View.js @@ -0,0 +1,22 @@ +import { Console } from "@woowacourse/mission-utils"; + +class View { + + constructor() { + this.carInputMessage = "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)\n"; + this.raceCount = "시도할 횟수는 몇 회인가요?\n"; + } + + + async readInputCar() { + const carNames = await Console.readLineAsync(this.carInputMessage); + return carNames; + } + + async readInputRaceCount() { + const raceCount = await Console.readLineAsync(this.carInputMessage); + return raceCount; + } +} + +export default View; \ No newline at end of file From 51f1d7a4fd7baaa1481bd9836e2d2cdea4306d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Mon, 28 Oct 2024 21:53:52 +0900 Subject: [PATCH 03/14] =?UTF-8?q?[feat](View)=20:=20=ED=9A=9F=EC=88=98=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20=EC=9E=98?= =?UTF-8?q?=EB=AA=BB=EB=90=9C=20=EC=9E=85=EB=A0=A5=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 20 ++++++++++---------- src/App.js | 3 +-- src/View.js | 22 +++++++++++++++------- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index e5757e600..b3b009516 100644 --- a/README.md +++ b/README.md @@ -10,18 +10,18 @@ AngularJS Git Commit Message Conventions을 참고해 커밋 메시지를 작성 # 기능 요구 사항 -[] 자동차 이름 입력 받기 - [] ',' 기준으로 이름 입력 (5자 이하) - [] 에러처리 -[] 시도 횟수 입력 - [] 유효한 숫자 아닌 경우 에러처리 -[] 자동차 경주 - [] n번 전진 시도 +- [x] 자동차 이름, 횟수 입력 받기 + - [x] ',' 기준으로 이름 입력 (5자 이하) + - [x] 자연수 숫자 입력받기 + - [x] 잘못된 값 입력시 에러처리 + - [x] 유효한 숫자 아닌 경우 에러처리 +- [ ] 자동차 경주 + - [ ] n번 전진 시도 - 이름별로 무작위 값 >= 4 인 경우 전진 - 해당 결과 출력 -[] 최종 우승자 출력 - [] 공동 우승 처리 -[] ERROR 출력 +- [ ] 최종 우승자 출력 + - [ ] 공동 우승 처리 +- [ ] ERROR 출력 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. 각 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. diff --git a/src/App.js b/src/App.js index 1aa917107..b89983cc9 100644 --- a/src/App.js +++ b/src/App.js @@ -4,8 +4,7 @@ class App { #input = new View(); async run() { const names = await this.#input.readInputCar(); - const raceCount = await this.#input.readInputRaceCar(); - + const raceCount = await this.#input.readInputRaceCount(); } } diff --git a/src/View.js b/src/View.js index 0331176f2..80819e762 100644 --- a/src/View.js +++ b/src/View.js @@ -1,20 +1,28 @@ import { Console } from "@woowacourse/mission-utils"; class View { + #inputCarNameRegx = /^([a-zA-z]{1,5})(,[a-zA-Z]{1,5})*$/ - constructor() { - this.carInputMessage = "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)\n"; - this.raceCount = "시도할 횟수는 몇 회인가요?\n"; - } - + #carInputMessage = "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)\n"; + #raceCount = "시도할 횟수는 몇 회인가요?\n"; async readInputCar() { - const carNames = await Console.readLineAsync(this.carInputMessage); + const carNames = await Console.readLineAsync(this.#carInputMessage); + + if (!this.#inputCarNameRegx.test(carNames)){ + throw new Error("[ERROR] : 잘못된 이름 입력\n"); + } + return carNames; } async readInputRaceCount() { - const raceCount = await Console.readLineAsync(this.carInputMessage); + const raceCountStr = await Console.readLineAsync(this.#raceCount); + const raceCount = Number(raceCountStr); + if (raceCount==NaN || raceCount <= 0){ + throw new Error("[ERROR] : 잘못된 숫자 입력\n"); + } + return raceCount; } } From 0c75478890b7e23a31b250446259648303b543f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Mon, 28 Oct 2024 21:59:46 +0900 Subject: [PATCH 04/14] =?UTF-8?q?[refactor](View)=20:=20readInputCar?= =?UTF-8?q?=EC=9D=98=20return=EA=B0=92=EC=9D=84=20=EB=AC=B8=EC=9E=90?= =?UTF-8?q?=EC=97=B4=EC=97=90=EC=84=9C=20=EB=B0=B0=EC=97=B4=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 2 +- src/View.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/App.js b/src/App.js index b89983cc9..fa6a3a520 100644 --- a/src/App.js +++ b/src/App.js @@ -3,7 +3,7 @@ import View from "./View.js"; class App { #input = new View(); async run() { - const names = await this.#input.readInputCar(); + const carNames = await this.#input.readInputCar(); const raceCount = await this.#input.readInputRaceCount(); } } diff --git a/src/View.js b/src/View.js index 80819e762..2cb3858ed 100644 --- a/src/View.js +++ b/src/View.js @@ -7,12 +7,13 @@ class View { #raceCount = "시도할 횟수는 몇 회인가요?\n"; async readInputCar() { - const carNames = await Console.readLineAsync(this.#carInputMessage); + const carNamesStr = await Console.readLineAsync(this.#carInputMessage); - if (!this.#inputCarNameRegx.test(carNames)){ + if (!this.#inputCarNameRegx.test(carNamesStr)){ throw new Error("[ERROR] : 잘못된 이름 입력\n"); } + const carNames = carNamesStr.split(','); return carNames; } From c9edb4c115c88d14c37323798d9ef65436b5c26f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Mon, 28 Oct 2024 22:06:33 +0900 Subject: [PATCH 05/14] =?UTF-8?q?[feat]=20(Car)=20:=20Car=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=A0=80=EC=9E=A5=ED=95=A0=20class=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Car.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/Car.js diff --git a/src/Car.js b/src/Car.js new file mode 100644 index 000000000..fcfda567c --- /dev/null +++ b/src/Car.js @@ -0,0 +1,19 @@ +class Car { + #forwadCount=0; + + constructor(name) { + const name = name; + } + + forward(random) { + if (random >= 4 ){ + this.#forwadCount++; + } + } + + getForwardCount() { + return this.#forwadCount; + } +} + +export default Car; \ No newline at end of file From af859f2222b77c33ac7cd9a13d0af082bd6c24f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Mon, 28 Oct 2024 22:18:50 +0900 Subject: [PATCH 06/14] =?UTF-8?q?[feat]=20:=20class=20Race=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 14 ++++++++++++++ src/Car.js | 7 ++++++- src/Race.js | 20 ++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/Race.js diff --git a/src/App.js b/src/App.js index fa6a3a520..847785c1e 100644 --- a/src/App.js +++ b/src/App.js @@ -1,10 +1,24 @@ import View from "./View.js"; +import Car from "./Car.js"; +import Race from "./Race.js"; class App { #input = new View(); + #race = new Race(); + async run() { const carNames = await this.#input.readInputCar(); const raceCount = await this.#input.readInputRaceCount(); + + this.#race.setRaceCount(raceCount); + + // Race 객체에 Car객체 추가 + carNames.forEach(carName => { + this.#race.addRacingCar(new Car(carName)); + }); + + this.#race.getCars(); + } } diff --git a/src/Car.js b/src/Car.js index fcfda567c..fcc6b1e91 100644 --- a/src/Car.js +++ b/src/Car.js @@ -1,8 +1,9 @@ class Car { #forwadCount=0; + #name; constructor(name) { - const name = name; + this.#name = name; } forward(random) { @@ -11,6 +12,10 @@ class Car { } } + getName() { + return this.#name; + } + getForwardCount() { return this.#forwadCount; } diff --git a/src/Race.js b/src/Race.js new file mode 100644 index 000000000..a2632af88 --- /dev/null +++ b/src/Race.js @@ -0,0 +1,20 @@ +class Race { + #cars = []; + #raceCount; + + constructor() { + } + + addRacingCar(car) { + this.#cars.push(car); + } + + setRaceCount(raceCount) { + this.#raceCount = raceCount; + } + + + +} + +export default Race; \ No newline at end of file From 8e64b7e3af68b976dfb91b59600f3b6a40f2a66a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Mon, 28 Oct 2024 22:28:57 +0900 Subject: [PATCH 07/14] =?UTF-8?q?[feat](Race,=20View)=20:=20=ED=9A=9F?= =?UTF-8?q?=EC=88=98=20=EC=A0=84=EC=A7=84=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++--- src/App.js | 5 ++++- src/Car.js | 6 ++---- src/Race.js | 18 ++++++++++++++++++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b3b009516..976d21fed 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,8 @@ AngularJS Git Commit Message Conventions을 참고해 커밋 메시지를 작성 - [x] 잘못된 값 입력시 에러처리 - [x] 유효한 숫자 아닌 경우 에러처리 - [ ] 자동차 경주 - - [ ] n번 전진 시도 - - 이름별로 무작위 값 >= 4 인 경우 전진 - - 해당 결과 출력 + - [x] 전진 기능 구현 + - [ ] 결과 출력 기능 구현 - [ ] 최종 우승자 출력 - [ ] 공동 우승 처리 - [ ] ERROR 출력 diff --git a/src/App.js b/src/App.js index 847785c1e..9066a4a3e 100644 --- a/src/App.js +++ b/src/App.js @@ -17,7 +17,10 @@ class App { this.#race.addRacingCar(new Car(carName)); }); - this.#race.getCars(); + for (let count=0; count < this.#race.raceCount; count ++){ + this.#race.racing(); + } + } } diff --git a/src/Car.js b/src/Car.js index fcc6b1e91..c96cea73c 100644 --- a/src/Car.js +++ b/src/Car.js @@ -6,10 +6,8 @@ class Car { this.#name = name; } - forward(random) { - if (random >= 4 ){ - this.#forwadCount++; - } + forward() { + this.#forwadCount++; } getName() { diff --git a/src/Race.js b/src/Race.js index a2632af88..c62c62df6 100644 --- a/src/Race.js +++ b/src/Race.js @@ -1,3 +1,5 @@ +import { Random } from "@woowacourse/mission-utils"; + class Race { #cars = []; #raceCount; @@ -13,6 +15,22 @@ class Race { this.#raceCount = raceCount; } + racing() { + this.#cars.forEach(car => { + const random = Random.pickNumberInRange(0, 9); + car.forward(random); + }) + } + + getRaceCount(){ + return this.#raceCount; + } + + showRacingResult() { + + } + + } From cd443dee4403345a5261d8aaf1594508cdd64a50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Mon, 28 Oct 2024 22:57:57 +0900 Subject: [PATCH 08/14] =?UTF-8?q?[feat](Race)=20:=20=EC=A4=91=EA=B0=84=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=EC=B6=9C=EB=A0=A5=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- src/App.js | 5 +++-- src/Car.js | 6 ++++-- src/Race.js | 22 ++++++++++++---------- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 976d21fed..95732d851 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ AngularJS Git Commit Message Conventions을 참고해 커밋 메시지를 작성 - [x] 자연수 숫자 입력받기 - [x] 잘못된 값 입력시 에러처리 - [x] 유효한 숫자 아닌 경우 에러처리 -- [ ] 자동차 경주 +- [x] 자동차 경주 - [x] 전진 기능 구현 - - [ ] 결과 출력 기능 구현 + - [x] 결과 출력 기능 구현 - [ ] 최종 우승자 출력 - [ ] 공동 우승 처리 - [ ] ERROR 출력 diff --git a/src/App.js b/src/App.js index 9066a4a3e..dd69da9e6 100644 --- a/src/App.js +++ b/src/App.js @@ -17,11 +17,12 @@ class App { this.#race.addRacingCar(new Car(carName)); }); - for (let count=0; count < this.#race.raceCount; count ++){ + for (let count=0; count < this.#race.getRaceCount(); count ++){ this.#race.racing(); + this.#race.showRacingResult(); + } - } } diff --git a/src/Car.js b/src/Car.js index c96cea73c..715358edd 100644 --- a/src/Car.js +++ b/src/Car.js @@ -6,8 +6,10 @@ class Car { this.#name = name; } - forward() { - this.#forwadCount++; + forward(random) { + if (random >= 4) { + this.#forwadCount++; + } } getName() { diff --git a/src/Race.js b/src/Race.js index c62c62df6..a46456f76 100644 --- a/src/Race.js +++ b/src/Race.js @@ -1,11 +1,10 @@ -import { Random } from "@woowacourse/mission-utils"; +import { Random, Console } from "@woowacourse/mission-utils"; class Race { #cars = []; + #winners = []; #raceCount; - constructor() { - } addRacingCar(car) { this.#cars.push(car); @@ -15,24 +14,27 @@ class Race { this.#raceCount = raceCount; } + getRaceCount() { + return this.#raceCount; + } + racing() { this.#cars.forEach(car => { const random = Random.pickNumberInRange(0, 9); + // 4 이상일 경우 전진 car.forward(random); }) } - getRaceCount(){ - return this.#raceCount; - } - showRacingResult() { - + // name : --- 형식으로 출력 + this.#cars.forEach( car => { + Console.print(car.getName() + ' : ' + '-'.repeat(car.getForwardCount())); + }) + Console.print(''); } - - } export default Race; \ No newline at end of file From eef518f41112d7fbc9a96cd4edb5266071cdc3e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Mon, 28 Oct 2024 22:59:26 +0900 Subject: [PATCH 09/14] =?UTF-8?q?[feat](Race)=20:=20=EC=9A=B0=EC=8A=B9?= =?UTF-8?q?=EC=9E=90=20=EA=B2=B0=EC=A0=95=20=EB=B0=8F=20=EC=9A=B0=EC=8A=B9?= =?UTF-8?q?=EC=9E=90=20=EC=B6=9C=EB=A0=A5=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- src/App.js | 3 +++ src/Race.js | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 95732d851..6aa5efa19 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,9 @@ AngularJS Git Commit Message Conventions을 참고해 커밋 메시지를 작성 - [x] 자동차 경주 - [x] 전진 기능 구현 - [x] 결과 출력 기능 구현 -- [ ] 최종 우승자 출력 - - [ ] 공동 우승 처리 -- [ ] ERROR 출력 +- [x] 최종 우승자 출력 + - [x] 공동 우승 처리 +- [x] ERROR 출력 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. 각 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. diff --git a/src/App.js b/src/App.js index dd69da9e6..ac7bfa61c 100644 --- a/src/App.js +++ b/src/App.js @@ -23,6 +23,9 @@ class App { } + this.#race.Winner(); + this.#race.showWinner(); + } } diff --git a/src/Race.js b/src/Race.js index a46456f76..7e486ce6b 100644 --- a/src/Race.js +++ b/src/Race.js @@ -34,6 +34,25 @@ class Race { Console.print(''); } + Winner() { + let max = 0; + this.#cars.forEach(car => { + let forwardCount = car.getForwardCount(); + if (max < forwardCount) { + max = forwardCount; + } + }) + + this.#cars.forEach(car => { + if (car.getForwardCount() == max){ + this.#winners.push(car.getName()); + } + }) + } + + showWinner() { + Console.print('최종 우승자 : ' + this.#winners.join(',')); + } } From 7a9191b8adc7b1088412121c996ec3e640c2c2f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Mon, 28 Oct 2024 23:08:19 +0900 Subject: [PATCH 10/14] =?UTF-8?q?[feat]=20:=20Test=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 ------- __tests__/Test.js | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 __tests__/Test.js diff --git a/README.md b/README.md index 6aa5efa19..c1b0a8127 100644 --- a/README.md +++ b/README.md @@ -21,12 +21,3 @@ AngularJS Git Commit Message Conventions을 참고해 커밋 메시지를 작성 - [x] 최종 우승자 출력 - [x] 공동 우승 처리 - [x] ERROR 출력 - -주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. -각 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. -자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다. -사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. -전진하는 조건은 0에서 9 사이에서 무작위 값을 구한 후 무작위 값이 4 이상일 경우이다. -자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다. -우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다. -사용자가 잘못된 값을 입력할 경우 "[ERROR]"로 시작하는 메시지와 함께 Error를 발생시킨 후 애플리케이션은 종료되어야 한다. \ No newline at end of file diff --git a/__tests__/Test.js b/__tests__/Test.js new file mode 100644 index 000000000..d5b6465ee --- /dev/null +++ b/__tests__/Test.js @@ -0,0 +1,60 @@ +import App from "../src/App.js"; +import { MissionUtils } from "@woowacourse/mission-utils"; + +const mockQuestions = (inputs) => { + MissionUtils.Console.readLineAsync = jest.fn(); + + MissionUtils.Console.readLineAsync.mockImplementation(() => { + const input = inputs.shift(); + return Promise.resolve(input); + }); +}; + +const mockRandoms = (numbers) => { + MissionUtils.Random.pickNumberInRange = jest.fn(); + + numbers.reduce((acc, number) => { + return acc.mockReturnValueOnce(number); + }, MissionUtils.Random.pickNumberInRange); +}; + +const getLogSpy = () => { + const logSpy = jest.spyOn(MissionUtils.Console, "print"); + logSpy.mockClear(); + return logSpy; +}; + +describe("자동차 경주", () => { + test("기능 테스트", async () => { + // given + const MOVING_FORWARD = 4; + const STOP = 3; + const inputs = ["dao,bazzi", "1"]; + const logs = ["dao : -", "bazzi : ", "최종 우승자 : dao"]; + const logSpy = getLogSpy(); + + mockQuestions(inputs); + mockRandoms([MOVING_FORWARD, STOP]); + + // when + const app = new App(); + await app.run(); + + // then + logs.forEach((log) => { + expect(logSpy).toHaveBeenCalledWith(expect.stringContaining(log)); + }); + }); + + test("예외 테스트", async () => { + // given + const inputs = ["pazzi,dao,,json"]; + mockQuestions(inputs); + + // when + const app = new App(); + + // then + await expect(app.run()).rejects.toThrow("[ERROR]"); + }); +}); From 2b64eb7685dbd4ddd9b42468d49bcdc01e3ae5ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Sat, 2 Nov 2024 17:37:42 +0900 Subject: [PATCH 11/14] =?UTF-8?q?style=20:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=AA=85?= =?UTF-8?q?=ED=99=95=ED=95=9C=20=ED=91=9C=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/Test.js | 2 +- src/App.js | 8 ++++---- src/Car.js | 6 +++--- src/Race.js | 2 +- src/View.js | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/__tests__/Test.js b/__tests__/Test.js index d5b6465ee..2c5591e99 100644 --- a/__tests__/Test.js +++ b/__tests__/Test.js @@ -48,7 +48,7 @@ describe("자동차 경주", () => { test("예외 테스트", async () => { // given - const inputs = ["pazzi,dao,,json"]; + const inputs = ["bazzi,dao,,json"]; mockQuestions(inputs); // when diff --git a/src/App.js b/src/App.js index ac7bfa61c..a565338b3 100644 --- a/src/App.js +++ b/src/App.js @@ -9,7 +9,7 @@ class App { async run() { const carNames = await this.#input.readInputCar(); const raceCount = await this.#input.readInputRaceCount(); - + this.#race.setRaceCount(raceCount); // Race 객체에 Car객체 추가 @@ -17,15 +17,15 @@ class App { this.#race.addRacingCar(new Car(carName)); }); - for (let count=0; count < this.#race.getRaceCount(); count ++){ + for (let count = 0; count < this.#race.getRaceCount(); count++) { this.#race.racing(); this.#race.showRacingResult(); - + } this.#race.Winner(); this.#race.showWinner(); - + } } diff --git a/src/Car.js b/src/Car.js index 715358edd..a43a4f5fd 100644 --- a/src/Car.js +++ b/src/Car.js @@ -1,5 +1,5 @@ class Car { - #forwadCount=0; + #forwardCount=0; #name; constructor(name) { @@ -8,7 +8,7 @@ class Car { forward(random) { if (random >= 4) { - this.#forwadCount++; + this.#forwardCount++; } } @@ -17,7 +17,7 @@ class Car { } getForwardCount() { - return this.#forwadCount; + return this.#forwardCount; } } diff --git a/src/Race.js b/src/Race.js index 7e486ce6b..e0c635aff 100644 --- a/src/Race.js +++ b/src/Race.js @@ -34,7 +34,7 @@ class Race { Console.print(''); } - Winner() { + getWinner() { let max = 0; this.#cars.forEach(car => { let forwardCount = car.getForwardCount(); diff --git a/src/View.js b/src/View.js index 2cb3858ed..b1477241a 100644 --- a/src/View.js +++ b/src/View.js @@ -1,7 +1,7 @@ import { Console } from "@woowacourse/mission-utils"; class View { - #inputCarNameRegx = /^([a-zA-z]{1,5})(,[a-zA-Z]{1,5})*$/ + #inputCarNameRegex = /^([a-zA-z]{1,5})(,[a-zA-Z]{1,5})*$/ #carInputMessage = "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)\n"; #raceCount = "시도할 횟수는 몇 회인가요?\n"; @@ -9,7 +9,7 @@ class View { async readInputCar() { const carNamesStr = await Console.readLineAsync(this.#carInputMessage); - if (!this.#inputCarNameRegx.test(carNamesStr)){ + if (!this.#inputCarNameRegex.test(carNamesStr)){ throw new Error("[ERROR] : 잘못된 이름 입력\n"); } From 0296e944dde267400e959a29f5b7f3f9de948e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Sat, 2 Nov 2024 17:45:05 +0900 Subject: [PATCH 12/14] =?UTF-8?q?style=20:=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EB=B0=8F=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Car.js | 2 +- src/View.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Car.js b/src/Car.js index a43a4f5fd..330311cb7 100644 --- a/src/Car.js +++ b/src/Car.js @@ -8,7 +8,7 @@ class Car { forward(random) { if (random >= 4) { - this.#forwardCount++; + this.#forwardCount += 1; } } diff --git a/src/View.js b/src/View.js index b1477241a..9cd505a22 100644 --- a/src/View.js +++ b/src/View.js @@ -20,7 +20,7 @@ class View { async readInputRaceCount() { const raceCountStr = await Console.readLineAsync(this.#raceCount); const raceCount = Number(raceCountStr); - if (raceCount==NaN || raceCount <= 0){ + if (raceCount.isNaN() || raceCount <= 0){ throw new Error("[ERROR] : 잘못된 숫자 입력\n"); } From ac177d0212f2fe12904fba1128c7310fd32f5062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Sat, 2 Nov 2024 17:53:27 +0900 Subject: [PATCH 13/14] =?UTF-8?q?style=20:=20=EB=B3=80=EC=88=98=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 2 +- src/OutView.js | 8 ++++++++ src/Race.js | 12 +++--------- 3 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 src/OutView.js diff --git a/src/App.js b/src/App.js index a565338b3..649dd268c 100644 --- a/src/App.js +++ b/src/App.js @@ -23,7 +23,7 @@ class App { } - this.#race.Winner(); + this.#race.determineWinner(); this.#race.showWinner(); } diff --git a/src/OutView.js b/src/OutView.js new file mode 100644 index 000000000..9417667ae --- /dev/null +++ b/src/OutView.js @@ -0,0 +1,8 @@ + +class OutView { + + + +} + +export default OutView \ No newline at end of file diff --git a/src/Race.js b/src/Race.js index e0c635aff..b70e1de25 100644 --- a/src/Race.js +++ b/src/Race.js @@ -34,17 +34,11 @@ class Race { Console.print(''); } - getWinner() { - let max = 0; - this.#cars.forEach(car => { - let forwardCount = car.getForwardCount(); - if (max < forwardCount) { - max = forwardCount; - } - }) + determineWinner() { + const max = Math.max(...this.#cars.map(car => car.getForwardCount())); this.#cars.forEach(car => { - if (car.getForwardCount() == max){ + if (car.getForwardCount() === max){ this.#winners.push(car.getName()); } }) From 414d5a3029ba5eb0e38ad3955c1d6c797f5ecdec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=84=9D=EC=B0=AC?= Date: Sat, 2 Nov 2024 18:00:28 +0900 Subject: [PATCH 14/14] =?UTF-8?q?refactor=20:=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20App=20->=20OutView=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 4 ++++ src/OutView.js | 4 ++++ src/Race.js | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/App.js b/src/App.js index 649dd268c..310590fc7 100644 --- a/src/App.js +++ b/src/App.js @@ -1,10 +1,12 @@ import View from "./View.js"; import Car from "./Car.js"; import Race from "./Race.js"; +import OutView from "./OutView.js"; class App { #input = new View(); #race = new Race(); + #output = new OutView(); async run() { const carNames = await this.#input.readInputCar(); @@ -25,7 +27,9 @@ class App { this.#race.determineWinner(); this.#race.showWinner(); + const winners = this.#race.getWinner(); + this.#output.showWinner(winners); } } diff --git a/src/OutView.js b/src/OutView.js index 9417667ae..fda73a101 100644 --- a/src/OutView.js +++ b/src/OutView.js @@ -1,6 +1,10 @@ +import { Console } from "@woowacourse/mission-utils"; class OutView { + showWinner(winners) { + Console.print(`최종 우승자 : ${winners.join(',')}`); + } } diff --git a/src/Race.js b/src/Race.js index b70e1de25..74e68819a 100644 --- a/src/Race.js +++ b/src/Race.js @@ -44,8 +44,8 @@ class Race { }) } - showWinner() { - Console.print('최종 우승자 : ' + this.#winners.join(',')); + getWinner() { + return this.#winners; } }