diff --git a/README.md b/README.md index 15bb106b5..8668f48f7 100644 --- a/README.md +++ b/README.md @@ -1 +1,63 @@ -# javascript-lotto-precourse +# ๐Ÿ’ธ ๋กœ๋˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„ + + +[๐Ÿฃ ์ž…๋ ฅ๋ฐ›๊ณ  ์ฒ˜๋ฆฌํ•˜๊ธฐ](#๊ตฌ์ž…-๊ธˆ์•ก-์ž…๋ ฅ)  +[๐Ÿ’ฐ ๋ฐœํ–‰ํ•˜๊ธฐ](#๋ฐœํ–‰ํ•˜๊ธฐ)  +[๐ŸŽ‰ ๋‹น์ฒจ ๊ณ„์‚ฐํ•˜๊ธฐ](#๋‹น์ฒจ)  +[๐Ÿ“ˆ ์ˆ˜์ต๋ฅ ](#-์ˆ˜์ต๋ฅ )  +[๐Ÿค‘ ์ถœ๋ ฅํ•˜๊ธฐ](#-์ถœ๋ ฅํ•˜๊ธฐ) + + +## ๐Ÿฃ ์ž…๋ ฅ ๋ฐ›๊ณ  ์ฒ˜๋ฆฌํ•˜๊ธฐ +### ๊ตฌ์ž… ๊ธˆ์•ก ์ž…๋ ฅ + +1000์› ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•œ๋‹ค. + +- `[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์ด 1000 ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.` + +### ๋‹น์ฒจ ๋ฒˆํ˜ธ, ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ž…๋ ฅ + +๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. ์ด๋•Œ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค. +- ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์ˆซ์ž 6๊ฐœ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ 1๊ฐœ๋ฅผ ๋ฝ‘๋Š”๋‹ค. + +- ์˜ˆ์™ธ : **๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ 6๊ฐœ ์ž…๋ ฅํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ** :
`[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ 6๊ฐœ ์ž…๋ ฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.` +- ์˜ˆ์™ธ : **์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ** :
`[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต ์—†๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` +- ์˜ˆ์™ธ : **์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ** :
`[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` + +๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. +- ์˜ˆ์™ธ : **๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ 1๊ฐœ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ** :
`[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ 1๊ฐœ ์ž…๋ ฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.` +- ์˜ˆ์™ธ : **๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ**:
`[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.` +- ์˜ˆ์™ธ : **์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ** :
`[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` + +## ๐Ÿ’ฐ ๋ฐœํ–‰ํ•˜๊ธฐ + +๋‚˜๋ˆˆ ์ˆซ์ž๋งŒํผ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•œ๋‹ค. +- ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ์ˆซ์ž ๋ฒ”์œ„ : 1-45 + +ํ•œ ๋ฒˆ ๋ฐœํ–‰ํ•  ๋•Œ ์ˆซ์ž์˜ ๊ฐœ์ˆ˜๋Š” 6๊ฐœ ์ด๋‹ค. + + +## ๐ŸŽ‰ ๋‹น์ฒจ ๊ณ„์‚ฐํ•˜๊ธฐ + +1๋“ฑ ๋ถ€ํ„ฐ 5๋“ฑ๊นŒ์ง€ ์š”๊ตฌ ์‚ฌํ•ญ์— ๋”ฐ๋ผ ๋‹น์ฒจ์ž๋ฅผ ๊ฐ€๋ฆฐ๋‹ค. +- 6๊ฐœ ์ผ์น˜์™€ 5๊ฐœ ์ผ์น˜์— ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ž˜ ๊ตฌ๋ถ„ํ•ด์•ผํ•œ๋‹ค. +- 3๊ฐœ, 4๊ฐœ, 5๊ฐœ, 5๊ฐœ๋ž‘ ๋ณด๋„ˆ์Šค ๋งž์ถ˜๊ฒฝ์šฐ, 6๊ฐœ๋กœ ๋‚˜๋ˆ„๊ณ  `if-else`์กฐ๊ฑด๋ฌธ์œผ๋กœ ํ•ด๊ฒฐ(ํŠน์ • ๊ฒฝ์šฐ์—๋งŒ ์กฐ๊ฑด์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ด ํ›„ ์กฐ๊ฑด ๋ฌด์‹œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.) + + +## ๐Ÿ“ˆ ์ˆ˜์ต๋ฅ  + +- $(๋‹น์ฒจย ์ดย ๊ธˆ์•ก/๊ตฌ์ž…ย ๊ธˆ์•ก) ร— 100 = ์ˆ˜์ต๋ฅ $ +- ์†Œ์ˆ˜์  **๋‘˜์งธ์ž๋ฆฌ**์—์„œ ๋ฐ˜์˜ฌ๋ฆผ + +
+ +## ๐Ÿค‘ ์ถœ๋ ฅํ•˜๊ธฐ + +- ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ์ˆ˜๋Ÿ‰๊ณผ ๋ฒˆํ˜ธ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. +- ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ๋ณด์—ฌ์ค€๋‹ค. + +- ๋‹น์ฒจ ๋‚ด์—ญ์„ ์ถœ๋ ฅํ•œ๋‹ค. +- 0๊ฐœ ์ผ์น˜, (00000์›) - 0๊ฐœ +- ์ˆ˜์ต๋ฅ  ์†Œ์ˆ˜์  ๋‘˜์งธ ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผํ•œ๋‹ค. + +- ์˜ˆ์™ธ ์‚ฌํ•ญ ์‹œ ์—๋Ÿฌ ๋ฌธ๊ตฌ ์ถœ๋ ฅํ•ด์•ผํ•œ๋‹ค. diff --git a/__tests__/ApplicationTest.js b/__tests__/ApplicationTest.js index 872380c9c..8390d0be4 100644 --- a/__tests__/ApplicationTest.js +++ b/__tests__/ApplicationTest.js @@ -1,4 +1,4 @@ -import App from "../src/App.js"; +import App from "../src/controllers/App.js"; import { MissionUtils } from "@woowacourse/mission-utils"; const mockQuestions = (inputs) => { @@ -6,7 +6,6 @@ const mockQuestions = (inputs) => { MissionUtils.Console.readLineAsync.mockImplementation(() => { const input = inputs.shift(); - return Promise.resolve(input); }); }; @@ -91,7 +90,5 @@ describe("๋กœ๋˜ ํ…Œ์ŠคํŠธ", () => { }); }); - test("์˜ˆ์™ธ ํ…Œ์ŠคํŠธ", async () => { - await runException("1000j"); - }); + }); diff --git a/__tests__/InputValidatorTest.js b/__tests__/InputValidatorTest.js new file mode 100644 index 000000000..87a4a4b8b --- /dev/null +++ b/__tests__/InputValidatorTest.js @@ -0,0 +1,45 @@ +import InputValidator from "../src/utils/InputValidator"; + +describe('์ž…๋ ฅ ๊ฐ’ ์œ ํšจ์„ฑ ํ…Œ์ŠคํŠธ', () => { + test("๊ตฌ์ž… ๊ธˆ์•ก์ด 1000์› ๋‹จ์œ„๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.PurchaseAmount("1500"); + }).toThrow("[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์ด 1000 ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); + }); + + test("๋‹น์ฒจ ๋ฒˆํ˜ธ๊ฐ€ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.WinningNumbers("1,2,3,4,5,46"); + }).toThrow("[ERROR]"); + }); + + test("๋‹น์ฒจ ๋ฒˆํ˜ธ๊ฐ€ 6๊ฐœ๊ฐ€ ์•„๋‹ ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.WinningNumbers("1,2,3,4,5"); + }).toThrow("[ERROR]"); + }); + + test("๋‹น์ฒจ ๋ฒˆํ˜ธ์— ์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ์„ ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.WinningNumbers("1,2,3,4,5,5"); + }).toThrow("[ERROR]"); + }); + + test("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ 1๊ฐœ๊ฐ€ ์•„๋‹ ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.bonusNumber("7,8", [1, 2, 3, 4, 5, 6]); + }).toThrow("[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ 1๊ฐœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + }); + + test("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋  ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.bonusNumber("5", [1, 2, 3, 4, 5, 6]); + }).toThrow("[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค."); + }); + + test("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.bonusNumber("50", [1, 2, 3, 4, 5, 6]); + }).toThrow("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + }); +}); diff --git a/__tests__/LottoTest.js b/__tests__/LottoTest.js index 409aaf69b..0af31be43 100644 --- a/__tests__/LottoTest.js +++ b/__tests__/LottoTest.js @@ -1,4 +1,4 @@ -import Lotto from "../src/Lotto"; +import Lotto from "../src/models/Lotto"; describe("๋กœ๋˜ ํด๋ž˜์Šค ํ…Œ์ŠคํŠธ", () => { test("๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ๊ฐœ์ˆ˜๊ฐ€ 6๊ฐœ๊ฐ€ ๋„˜์–ด๊ฐ€๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.", () => { @@ -14,5 +14,12 @@ describe("๋กœ๋˜ ํด๋ž˜์Šค ํ…Œ์ŠคํŠธ", () => { }).toThrow("[ERROR]"); }); - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„์— ๋”ฐ๋ฅธ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ + test("๋กœ๋˜ ๋ฒˆํ˜ธ๊ฐ€ 1~45 ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.", () => { + expect(() => { + new Lotto([0, 2, 3, 4, 5, 6]); + }).toThrow("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + expect(() => { + new Lotto([1, 2, 3, 4, 5, 46]); + }).toThrow("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + }); }); diff --git a/src/App.js b/src/App.js deleted file mode 100644 index 091aa0a5d..000000000 --- a/src/App.js +++ /dev/null @@ -1,5 +0,0 @@ -class App { - async run() {} -} - -export default App; diff --git a/src/Lotto.js b/src/Lotto.js deleted file mode 100644 index cb0b1527e..000000000 --- a/src/Lotto.js +++ /dev/null @@ -1,18 +0,0 @@ -class Lotto { - #numbers; - - constructor(numbers) { - this.#validate(numbers); - this.#numbers = numbers; - } - - #validate(numbers) { - if (numbers.length !== 6) { - throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); - } - } - - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ -} - -export default Lotto; diff --git a/src/controllers/App.js b/src/controllers/App.js new file mode 100644 index 000000000..08e9cfe2d --- /dev/null +++ b/src/controllers/App.js @@ -0,0 +1,48 @@ +import { Console } from "@woowacourse/mission-utils"; +import LottoManager from "../models/LottoManager.js"; +import InputValidator from "../utils/InputValidator.js"; +import ConsoleView from "../views/ConsoleView.js"; + +class App { + async run() { + ConsoleView.askPurchaseAmount((input) => this.handlePurchaseAmount(input)); + } + + handlePurchaseAmount(input) { + try { + const purchaseAmount = InputValidator.PurchaseAmount(input); + console.log("๊ตฌ์ž… ๊ธˆ์•ก ์œ ํšจ์„ฑ ํ†ต๊ณผ:", purchaseAmount); // ๋””๋ฒ„๊น… ๋กœ๊ทธ + this.lottoManager = new LottoManager(purchaseAmount); + ConsoleView.showLottos(this.lottoManager.getLottos()); + ConsoleView.askWinningNumbers((input) => this.handleWinningNumbers(input)); + } catch (error) { + ConsoleView.showError(error); + ConsoleView.askPurchaseAmount((input) => this.handlePurchaseAmount(input)); + } + } + + handleWinningNumbers(input) { + try { + const winningNumbers = InputValidator.WinningNumbers(input); + console.log("๋‹น์ฒจ ๋ฒˆํ˜ธ ์œ ํšจ์„ฑ ํ†ต๊ณผ:", winningNumbers); // ๋””๋ฒ„๊น… ๋กœ๊ทธ + ConsoleView.askBonusNumber((input) => this.handleBonusNumber(input, winningNumbers)); + } catch (error) { + ConsoleView.showError(error); + ConsoleView.askWinningNumbers((input) => this.handleWinningNumbers(input)); + } + } + + handleBonusNumber(input, winningNumbers) { + try { + const bonusNumber = InputValidator.BonusNumber(input); + console.log("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์œ ํšจ์„ฑ ํ†ต๊ณผ:", bonusNumber); // ๋””๋ฒ„๊น… ๋กœ๊ทธ + const results = this.lottoManager.calculateResults(winningNumbers, bonusNumber); + ConsoleView.showResults(results); + } catch (error) { + ConsoleView.showError(error); + ConsoleView.askBonusNumber((input) => this.handleBonusNumber(input, winningNumbers)); + } + } +} + +export default App; diff --git a/src/index.js b/src/index.js index 02a1d389e..2a799ed85 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -import App from "./App.js"; +import App from "./controllers/App.js"; const app = new App(); await app.run(); diff --git a/src/models/Lotto.js b/src/models/Lotto.js new file mode 100644 index 000000000..979eb751f --- /dev/null +++ b/src/models/Lotto.js @@ -0,0 +1,28 @@ +class Lotto { + #numbers; + + constructor(numbers) { + this.#validate(numbers); + this.#numbers = numbers; + } + + #validate(numbers) { + if (numbers.length !== 6) { + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + if (new Set(numbers).size !== numbers.length){ + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต ์—†๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + } + if (numbers.some(num => num < 1 || num > 45)){ + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + } + } + + // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ + + getNumbers(){ + return this.#numbers; + } +} + +export default Lotto; diff --git a/src/models/LottoManager.js b/src/models/LottoManager.js new file mode 100644 index 000000000..2f0c40aac --- /dev/null +++ b/src/models/LottoManager.js @@ -0,0 +1,27 @@ +import Lotto from "./Lotto.js"; +import { Random } from "@woowacourse/mission-utils"; +import ResultCalculator from "./ResultCalculator.js"; + +class LottoManager { + constructor(purchaseAmount) { + this.lottos = this.generateLottos(purchaseAmount / 1000); + } + + generateLottos(count) { + return Array.from({ length: count }, () => { + const numbers = Random.pickUniqueNumbersInRange(1, 45, 6).sort((a, b) => a - b); + return new Lotto(numbers); + }); + } + + getLottos() { + return this.lottos; + } + + calculateResults(winningNumbers, bonusNumber) { + const resultCalculator = new ResultCalculator(this.lottos, winningNumbers, bonusNumber); + return resultCalculator.getResults(); + } +} + +export default LottoManager; diff --git a/src/models/ResultCalculator.js b/src/models/ResultCalculator.js new file mode 100644 index 000000000..233c79c61 --- /dev/null +++ b/src/models/ResultCalculator.js @@ -0,0 +1,35 @@ +class ResultCalculator { + constructor(lottos, winningNumbers, bonusNumber) { + this.lottos = lottos; + this.winningNumbers = winningNumbers; + this.bonusNumber = bonusNumber; + this.matchCounts = { 3: 0, 4: 0, 5: 0, 6: 0, "5+bonus": 0 }; + this.calculateResults(); + } + + calculateResults() { + this.lottos.forEach((lotto) => { + const matchedCount = this.countMatches(lotto.getNumbers()); + this.updateMatchCounts(matchedCount, lotto); + }); + } + + countMatches(numbers) { + return numbers.filter((num) => this.winningNumbers.includes(num)).length; + } + + updateMatchCounts(matchedCount, lotto) { + if (matchedCount === 6) this.matchCounts[6]++; + else if (matchedCount === 5 && lotto.getNumbers().includes(this.bonusNumber)) this.matchCounts["5+bonus"]++; + else if (matchedCount === 5) this.matchCounts[5]++; + else if (matchedCount === 4) this.matchCounts[4]++; + else if (matchedCount === 3) this.matchCounts[3]++; + } + + getResults() { + return this.matchCounts; + } + } + + export default ResultCalculator; + \ No newline at end of file diff --git a/src/utils/InputValidator.js b/src/utils/InputValidator.js new file mode 100644 index 000000000..d84f5c84e --- /dev/null +++ b/src/utils/InputValidator.js @@ -0,0 +1,42 @@ +import Lotto from "../models/Lotto.js"; + +class InputValidator { + static PurchaseAmount(input) { + const amount = parseInt(input, 10); + if (isNaN(amount) || amount % 1000 !== 0) { + throw new Error("[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์ด 1000 ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); + } + return amount; + } + + static WinningNumbers(input) { + const numbers = input.split(",").map(Number); + const lotto = new Lotto(numbers); + return lotto.getNumbers(); + } + + static bonusNumber(input, winningNumbers) { + const numbers = input.split(',').map(Number); + this.checkBonusNumberCount(numbers); + const bonusNumber = numbers[0]; + this.checkBonusNumberValidity(bonusNumber, winningNumbers); + return bonusNumber; + } + + static checkBonusNumberCount(numbers) { + if (numbers.length !== 1) { + throw new Error("[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ 1๊ฐœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + } + + static checkBonusNumberValidity(bonusNumber, winningNumbers) { + if (winningNumbers.includes(bonusNumber)) { + throw new Error("[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค."); + } + if (isNaN(bonusNumber) || bonusNumber < 1 || bonusNumber > 45) { + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + } +} + +export default InputValidator; diff --git a/src/views/ConsoleView.js b/src/views/ConsoleView.js new file mode 100644 index 000000000..d811e9023 --- /dev/null +++ b/src/views/ConsoleView.js @@ -0,0 +1,43 @@ +import { Console } from "@woowacourse/mission-utils"; + +const ConsoleView = { + askPurchaseAmount() { + return new Promise((resolve) => { + Console.readLineAsync("๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", resolve); + }); + }, + + askWinningNumbers() { + return new Promise((resolve) => { + Console.readLineAsync("๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", resolve); + }); + }, + + askBonusNumber() { + return new Promise((resolve) => { + Console.readLineAsync("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", resolve); + }); + }, + + showLottos(lottos) { + Console.print(`${lottos.length}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.`); + lottos.forEach((lotto) => { + Console.print(`[${lotto.getNumbers().join(", ")}]`); + }); + }, + + showResults(results) { + Console.print("๋‹น์ฒจ ํ†ต๊ณ„\n---"); + Console.print(`3๊ฐœ ์ผ์น˜ (5,000์›) - ${results[3]}๊ฐœ`); + Console.print(`4๊ฐœ ์ผ์น˜ (50,000์›) - ${results[4]}๊ฐœ`); + Console.print(`5๊ฐœ ์ผ์น˜ (1,500,000์›) - ${results[5]}๊ฐœ`); + Console.print(`5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ${results["5+bonus"]}๊ฐœ`); + Console.print(`6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ${results[6]}๊ฐœ`); + }, + + showError(error) { + Console.print(`[ERROR] ${error.message}`); + }, +}; + +export default ConsoleView;