diff --git a/README.md b/README.md index e078fd41..da3c56c5 100644 --- a/README.md +++ b/README.md @@ -1 +1,66 @@ # javascript-racingcar-precourse + +## 자동차 경주 게임 구현 + +기능 요구 사항 + +주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. +각 자동차에 이름을 부여할 수 있다. (input) +전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. + +자동차 이름은 쉼표(,)를 기준으로 구분/ 이름은 5자 이하만 가능 +사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. (input) + +전진하는 조건은 0~9사이에서 무작위 값을 구한 후 무작위 값이 4 이상일 경우 + +자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있음 +우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분 +사용자가 잘못된 값을 입력할 경우 "[ERROR]"로 시작하는 메시지와 함께 Error를 발생시킨 후 애플리케이션은 종료 + +------------- + +입출력 요구 사항 +입력 +경주할 자동차 이름(이름은 쉼표(,) 기준으로 구분) +pobi,woni,jun +시도할 횟수 +5 +출력 +차수별 실행 결과 +pobi : -- +woni : ---- +jun : --- +단독 우승자 안내 문구 +최종 우승자 : pobi +공동 우승자 안내 문구 +최종 우승자 : pobi, jun + +실행 결과 예시 +경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분) +pobi,woni,jun +시도할 횟수는 몇 회인가요? +5 + +실행 결과 +pobi : - +woni : +jun : - + +pobi : -- +woni : - +jun : -- + +pobi : --- +woni : -- +jun : --- + +pobi : ---- +woni : --- +jun : ---- + +pobi : ----- +woni : ---- +jun : ----- + +최종 우승자 : pobi, jun +--- \ No newline at end of file diff --git a/src/App.js b/src/App.js index 091aa0a5..924dd946 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,42 @@ +import { Console } from "@woowacourse/mission-utils"; +import{ carGame } from "./carGame.js"; + class App { - async run() {} + async run() { + + try { + + const nameInput = await Console.readLineAsync("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분) \n") + this.parseNames(nameInput); + + const countInput = await Console.readLineAsync("시도할 횟수는 몇 회인가요? \n") + + await carGame.start(nameInput, countInput); + + + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + const out = msg.startsWith("[ERROR]") ? msg : "[ERROR]"; + Console.print(out); + throw new Error(out); + + } + } + + parseNames(input) { + if (typeof input !== "string") throw new Error ("[ERROR] 입력 형식 오류"); + const names = input.split(",").map((s) => s.trim()); + if (names.length === 0 || names.some((n) => n.length === 0)){ + throw new Error("[ERROR] 이름은 빈 값일 수 없음"); + } + + for (const n of names) { + if (n.length < 1 || n.length > 5) { + throw new Error("[ERROR] 각 이름은 1~5자여야 함"); + } + } + } } + export default App; diff --git a/src/carGame.js b/src/carGame.js new file mode 100644 index 00000000..4acf36fe --- /dev/null +++ b/src/carGame.js @@ -0,0 +1,58 @@ +import { Console, Random } from "@woowacourse/mission-utils"; + +const MOVE_THRESHOLD = 4; +const MIN_RANDOM = 0; +const MAX_RANDOM = 9; + +export const carGame = { + + async start(namesInput, tryCountInput) { + const names = String(namesInput) + .split(",") + .map((s) => s.trim()) + .filter((s) => s.length > 0); + + + let tryCount = parseInt(String(tryCountInput), 10); + if(!Number.isFinite(tryCount) || tryCount < 1){ + tryCount = 1; + } + + if (names.length === 0) { + Console.print("\n실행결과"); + Console.print("최종 우승자 : "); + return; + }; + + const distances = {}; + names.forEach(name => (distances[name] = 0)); + + + Console.print("\n실행결과"); + + + // 게임 시작 + for(let i = 0; i < tryCount; i += 1) { + names.forEach((name) => { + const r = Random.pickNumberInRange(MIN_RANDOM, MAX_RANDOM); + if (r >= MOVE_THRESHOLD) distances[name] += 1; + }); + + carGame.printRoundResult(names, distances); + } + + // 우승자 + const max = Math.max(...names.map((n) => distances[n])); + const winners = names.filter((n) => distances[n] === max); + Console.print(`최종 우승자 : ${winners.join(", ")}`); +}, + + // 자동차 상태 + printRoundResult (names,distances){ + for (const name of names) { + const dash = "-".repeat(distances[name]); + Console.print(`${name} : ${dash}`); + } + Console.print(""); + }, +};