diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..f662a331d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,15 @@ +1. 자동차의 이름을 입력받는 기능 +1-1. 자동차의 이름은 ","로 구분되어야 한다. +1-2. 자동차의 이름에 공백이 들어가서는 안 된다. +1-3. 자동차가 최소 2개 이상일 때(자동차의 이름이 두 개 이상일 때) 경주가 시작된다. +1-4. 자동차의 이름은 최대 5자이다. +1-5. 자동차의 이름은 중복될 수 없다. + +2. 이동 횟수를 입력받는 기능 +2-1. 이동 횟수는 0보다 커야한다. +2-2. 이동 횟수 입력값에 공백이 있어서는 안 된다. +2-3. 이동 횟수 입력값에 숫자가 아닌 문자가 들어가선 안 된다. + +3. 각 이동 회차마다 자동차를 이동하고 상태를 출력하는 기능 +4. 회차가 마무리되고 우승자를 판별하는 기능 +5. 우승자를 출력하는 기능 \ No newline at end of file diff --git a/src/App.js b/src/App.js index c38b30d5b..169c8fb10 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,87 @@ +import { MissionUtils } from "@woowacourse/mission-utils"; + class App { - async play() {} + + nameValidation(input) { + let names = new Map(); + const inputArray = input.split(","); + if (input.includes(' ')) throw new Error("[ERROR] 공백을 제외하고 입력해주세요."); + if (input.includes(',,')) throw new Error("[ERROR] 쉼표가 연달아 입력되었습니다."); + if (inputArray.length <= 1) throw new Error("[ERROR] 2개 이상의 자동차가 있어야 시작할 수 있습니다."); + inputArray.forEach((item) => { + if (item.length > 5) throw new Error("[ERROR] 5자 이하로 입력해주세요."); + if (names.has(item)) throw new Error("[ERROR] 중복된 이름이 있습니다."); + names.set(item, ""); + }); + return names; + } + + roundValidation(input) { + let rounds = 0; + if (input === "") throw new Error("[ERROR] 입력값이 없습니다."); + if (input.includes(' ')) throw new Error("[ERROR] 공백을 제외하고 입력해주세요."); + if (isNaN(input)) throw new Error("[ERROR] 숫자만 입력해주세요."); + const stringArray = Array.from(input); + stringArray.forEach((elements) => { + rounds = (rounds * 10) + parseInt(elements); + }); + return rounds; + } + + async playerInput() { + try{ + const nameinput = await MissionUtils.Console.readLineAsync('경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)\n'); + const names = this.nameValidation(nameinput); + const numberinput = await MissionUtils.Console.readLineAsync('시도할 횟수는 몇 회인가요?'); + const rounds = this.roundValidation(numberinput); + return [names, rounds]; + } catch(error){ + MissionUtils.Console.print(error.message); + throw new Error(); + } + } + + diceLogic(names, rounds) { + let i = rounds; + while(i != 0) { + names.forEach((value, key, map) => { + const num = MissionUtils.Random.pickNumberInRange(0, 9); + if (num >= 4) map.set(key, value+"-"); + MissionUtils.Console.print(`${key} : ${map.get(key)}`); + }); + i -= 1; + } + const winners = this.whoWin(names); + return winners; + } + + whoWin (names){ + const winners = []; + const ranking = Array.from(names); + ranking.sort((a, b) => b[1].length - a[1].length); + ranking.forEach((value, index, array) => { + if (index === 0) winners.push(value[0]); + if (index > 0 && array[0][1] === value[1]) winners.push(value[0]); + } + ); + return winners; + } + + announceWinner (winners){ + const announce = winners.join(', '); + MissionUtils.Console.print(`최종 우승자 : ${announce}`); + } + + async play() { + try { + const stuffs = await this.playerInput(); + const winners = await this.diceLogic(stuffs[0], stuffs[1]); + this.announceWinner(winners); + } catch (error){} + } } +const app = new App(); +app.play(); + export default App;