diff --git a/README.md b/README.md index b168a180..4c58dde9 100644 --- a/README.md +++ b/README.md @@ -1 +1,27 @@ # javascript-planetlotto-precourse + +# javascript-planetlotto-precourse + +## ๐Ÿ›ก๏ธ (ํ–‰์„ฑ๋กœ๋˜) + +์„ค๋ช… : +์ฃผ์–ด์ง„ view๋ฅผ ๊ฐ€์ง€๊ณ  ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„์„ ํ•  ๊ฒƒ์ธ๊ฐ€? + +๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๋งŒ๋“ค์–ด ๋†“์€ ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ  ์ดํ•ด๋ฅผ ํ•œ ๋’ค, ์–ด๋–ป๊ฒŒ ๊ทธ ๋‹ค์Œ์„ ์ด์–ด๋‚˜๊ฐˆ ๊ฒƒ์ธ๊ฐ€๊ฐ€ main ํฌ์ธํŠธ์ž„ +๋‚ฏ์„  ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด์„œ ์ž˜ ์ ์‘ํ•ด๋ณด๋„๋ก ํ•˜์ž! + +### (๋ฉ”์„œ๋“œ์„ค๋ช…) + +- [x] **printPurchasedLottos ์„ค๋ช…:** ์ผ๊ธ‰ ์ปฌ๋ ‰์…˜์„ ์ด์šฉํ•ด์•ผํ•˜์ง€๋งŒ, ์บก์Аํ™”๋ฅผ ํ•˜๋ฉด ์•ˆ ๋จ + ์ˆซ์ž ๋ฐฐ์—ด์„ ๋ฌธ์ž์—ด๋กœ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ์กฐ์‹ฌํ•ด์•ผํ•จ +- [x] **printResult ์„ค๋ช…:** ๊ฒฐ๊ณผ๋ฅผ ๋‹ด๋Š” ๋ฐฐ์—ด์ด ์žˆ์–ด์•ผํ•จ + +- [x] **askWinningLotto ์„ค๋ช…:** ์ˆซ์ž ๋ฐฐ์—ด์ด๊ธฐ ๋–„๋ฌธ์— ๋น„๊ต์— ์œ ์˜ํ•˜์ž + +### (๋ฉ”์„œ๋“œ์„ค๋ช…) + +- [x] **1** ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค. +- [x] **2** ๋กœ๋˜ ๋ฒˆํ˜ธ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์„œ ์ผ๊ธ‰ ์ปฌ๋ ‰์…˜ํ™”๋ฅผ ์‹œ์ผœ ๋กœ๋˜ ํ‹ฐ์ผ“์„ ์ƒ์„ฑํ•œ๋‹ค. +- [x] **3** ํ˜•์‹์— ๋งž๊ฒŒ ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€, ๋กœ๋˜ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. +- [x] ๊ฒฐ๊ณผ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•œ๋‹ค. +- [x] ์ €์žฅํ•œ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ์ถœ๋ ฅํ•œ๋‹ค. diff --git a/src/App.js b/src/App.js index 091aa0a5..dc828e25 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,74 @@ +import { InputView } from "./view.js"; +import { OutputView } from "./view.js"; +import { Console } from "@woowacourse/mission-utils"; +import LottoManager from "./model/LottoManager.js"; +import Validate from "./model/Validate.js"; +import ResultManager from "./model/ResultManager.js"; class App { - async run() {} -} + async run() { + const lottoList = await this.addPurChaseMoney(); + const winningNumber = await this.addWinningLottoNumber(lottoList); + const bonusNumber = await this.addbonusNumber(winningNumber); + //[5] ์–ผ๋งˆ๋‚˜ ๋งž์ท„๋Š”์ง€ ๊ณ„์‚ฐ -> ๋ฆฌ์ŠคํŠธ๋กœ ๊ด€๋ฆฌ + const resultManager = new ResultManager(); + resultManager.calculateIncom(lottoList, winningNumber, bonusNumber); + //[6] ๊ณ„์‚ฐ ๊ฒฐ๊ณผ ์ถœ๋ ฅ + const resultList = resultManager.getResultList(); + + // Console.print(`ํ…Œ์ŠคํŠธ์šฉ ์ถœ๋ ฅ: ${resultList}`); + + for (const num of resultList) { + OutputView.getCount(num); + } + OutputView.printResult(); + } + async addPurChaseMoney() { + while (true) { + try { + // [1] ๊ตฌ์ž…๊ธˆ์•ก ์ž…๋ ฅ + const purChaseMoney = await InputView.askAmount(); + const lottoManager = new LottoManager(); + const tryNumber = lottoManager.calculateTryNumber(purChaseMoney); + //[2] ๋กœ๋˜ ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ + lottoManager.makeLottoList(tryNumber); + const lottoList = lottoManager.getLottoList(); + //[3] outputView๋ฅผ ํ™œ์šฉํ•ด์„œ ๋ช‡๊ฐœ๋ฅผ ์ถœ๋ ฅํ–ˆ๋Š”์ง€ ์ถœ๋ ฅ + Console.print(""); + OutputView.printPurchasedLottos(lottoList); + return lottoList; + } catch (error) { + Console.print(error.message); + } + } + } + + async addWinningLottoNumber() { + while (true) { + try { + //[4] ์‚ฌ์šฉ์ž์—๊ฒŒ ๋กœ๋˜ ๋ฒˆํ˜ธ ์ž…๋ ฅ -> ์ˆซ์ž ๋ฐฐ์—ด๋กœ ์ž…๋ ฅ ๋จ + Console.print(""); + const winningLottoNumber = await InputView.askWinningLotto(); + Validate.winningNumber(winningLottoNumber); + // Console.print(`ํ…Œ์ŠคํŠธ ์œ„๋‹๋„˜๋ฒ„ : ${winningLottoNumber}`); + Console.print(""); + return winningLottoNumber; + } catch (error) { + Console.print(error.message); + } + } + } + + async addbonusNumber(lottoList, winningLottoNumber) { + while (true) { + try { + const bonusNumber = await InputView.askBonusNumber(); + Validate.bonusNumber(lottoList, bonusNumber); + return bonusNumber; + } catch (error) { + Console.print(error.message); + } + } + } +} export default App; diff --git a/src/model/LottoManager.js b/src/model/LottoManager.js new file mode 100644 index 00000000..ba9c3dd4 --- /dev/null +++ b/src/model/LottoManager.js @@ -0,0 +1,54 @@ +import { Random } from "@woowacourse/mission-utils"; + +class LottoManager { + #tryNumber; + #lottoList; + constructor() { + this.#tryNumber; + this.#lottoList = []; + } + calculateTryNumber(purChaseMoney) { + this.validateMoney(purChaseMoney); + return purChaseMoney / 500; // ์ด๋”ฐ ์ˆ˜์ •ํ•ด์•ผํ•จ + } + makeLottoList(tryNumber) { + for (let index = 0; index < tryNumber; index++) { + this.#lottoList[index] = this.makeRandomVariavle(); + } + } + getLottoList() { + return this.#lottoList; + } + + makeRandomVariavle() { + const lottoNumber = Random.pickUniqueNumbersInRange(1, 30, 5).sort( + (a, b) => a - b + ); + return lottoNumber; + } + + validateMoney(purChaseMoney) { + const testPurchaseMoney = purChaseMoney.toString().split(""); + if (!purChaseMoney) + throw new Error("[ERROR] ๊ตฌ์ž…๊ธˆ์•ก์€ ๋“ค์–ด์˜ค์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."); + if (testPurchaseMoney[0] === "0") + throw new Error("[ERROR] ๋งจ ์•ž์ž๋ฆฌ์— 0์ด ์กด์žฌํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค."); + testPurchaseMoney.forEach((num) => { + if (Number.isNaN(Number(num))) + throw new Error("[ERROR] ๋ฌธ์ž๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค."); + }); + if (testPurchaseMoney.includes(" ")) + throw new Error("[ERROR] ๋ฌธ์ž์— ๊ณต๋ฐฑ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค."); + const integerNumner = Number(purChaseMoney); + if (Number.isNaN(integerNumner)) + throw new Error("[ERROR] ๊ตฌ์ž…๊ธˆ์•ก์€ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + if (!Number.isInteger(integerNumner)) + throw new Error("[ERROR] ๊ตฌ์ž…๊ธˆ์•ก์€ ์ •์ˆ˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + if (integerNumner <= 0) + throw new Error("[ERROR] ๊ตฌ์ž…๊ธˆ์•ก์€ 0๋ณด๋‹ค ์ปค์•ผํ•ฉ๋‹ˆ๋‹ค."); + if (integerNumner % 500 !== 0) { + throw new Error("[ERROR] ๊ตฌ์ž…๊ธˆ์•ก์€ 500์› ๋‹จ์œ„์—ฌ์•ผํ•ฉ๋‹ˆ๋‹ค."); + } + } +} +export default LottoManager; diff --git a/src/model/ResultManager.js b/src/model/ResultManager.js new file mode 100644 index 00000000..bf9f771c --- /dev/null +++ b/src/model/ResultManager.js @@ -0,0 +1,56 @@ +import { Console } from "@woowacourse/mission-utils"; + +class ResultManager { + #resultList; + + static lottoPrizeIndex = { + 0: { index: 0 }, // ํ•„์š” + 1: { index: 0 }, // ํ•„์š” + 1: { index: 0 }, // ํ•„์š” + 2: { index: 0 }, + "2b": { index: 1 }, // ํ•„์š” + 3: { index: 0 }, + "3b": { index: 2 }, // ํ•„์š” + 4: { index: 3 }, // ํ•„์š” + "4b": { index: 3 }, // ํ•„์š” + 5: { index: 4 }, // ํ•„์š” + }; + + constructor() { + this.#resultList = [0, 0, 0, 0, 0, 0]; + } + calculateIncom(lottoList, inputWinningNumber, bonusNumber) { + const integerBonus = Number(bonusNumber); + const winningNumber = inputWinningNumber.map(Number); + Console.print(`ํ™•์ธ์šฉ ${winningNumber}`); + + for (const lotto of lottoList) { + // const lotto = lottoString.split(", "); + const match = winningNumber.filter((num) => lotto.includes(num)).length; + + const prizeIndex = ResultManager.lottoPrizeIndex[match]; + + // Console.print(prizeIndex.index); + + if (!prizeIndex) continue; + else if (prizeIndex.index === 3 && lotto.includes(integerBonus)) { + this.#resultList[prizeIndex.index] += 1; + } else if (prizeIndex.index === 3 && lotto.includes(integerBonus)) + this.#resultList[prizeIndex.index] += 1; + else if (prizeIndex.index === 4 && !lotto.includes(integerBonus)) + this.#resultList[3] += 1; + else if (prizeIndex.index === 4 && lotto.includes(integerBonus)) + this.#resultList[4] += 1; + else if (prizeIndex.index === 5) this.#resultList[5] += 1; + else if (prizeIndex) { + this.#resultList[prizeIndex.index] += 1; + } + } + } + + getResultList() { + return this.#resultList; + } +} + +export default ResultManager; diff --git a/src/model/Validate.js b/src/model/Validate.js new file mode 100644 index 00000000..2e842412 --- /dev/null +++ b/src/model/Validate.js @@ -0,0 +1,33 @@ +class Validate { + static winningNumber(winningNumber) { + winningNumber.forEach((num) => { + if (num < 0 || num > 30) + throw new Error("[ERROR] ์ˆซ์ž ๋ฒ”์œ„๊ฐ€ ํ‹€๋ ธ์Šต๋‹ˆ๋‹ค."); + if (Number.isNaN(num)) + throw new Error("[ERROR] ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๋ฌธ์ž๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค."); + if (!Number.isInteger(num)) { + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์ •์ˆ˜๋กœ ์ž…๋ ฅ๋ฐ›์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + }); + if (winningNumber.includes("")) + throw new Error(`[ERROR] ๊ณต๋ฐฑ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.`); + if (winningNumber.length !== 5) + throw new Error(`[ERROR] 5์ž๋ฆฌ ์ˆ˜๋ฅผ ์ž…๋ ฅ ๋ฐ›์•„์•ผํ•ฉ๋‹ˆ๋‹ค.`); + const testSetNumber = new Set(winningNumber); + if (testSetNumber.size !== winningNumber.length) + throw new Error(`[ERROR] ์ค‘๋ณต๊ฐ’์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.`); + } + + static bonusNumber(winningLottoNumber, bonusNumber) { + const integerNumber = Number(bonusNumber); + if (integerNumber < 0 || integerNumber > 46) + throw new Error("[ERROR] ์ˆซ์ž ๋ฒ”์œ„๊ฐ€ ํ‹€๋ ธ์Šต๋‹ˆ๋‹ค."); + if (winningLottoNumber.includes(integerNumber)) + throw new Error("[ERROR] ๋ณด๋„ˆ์Šค๋ฒˆํ˜ธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค."); + if (!Number.isInteger(integerNumber)) { + throw new Error("[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” ์ •์ˆ˜๋ฅผ ์ž…๋ ฅ ๋ฐ›์•„์•ผํ•ฉ๋‹ˆ๋‹ค."); + } + } +} + +export default Validate;