From 2965877bbb5846883c05ac3a4df4456c333a746a Mon Sep 17 00:00:00 2001 From: "mingyeong:D" <63152086+Kim-Mingyeong@users.noreply.github.com> Date: Thu, 2 Nov 2023 15:42:41 +0900 Subject: [PATCH 01/10] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=ED=95=A0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..e25d42cdcf --- /dev/null +++ b/docs/README.md @@ -0,0 +1,65 @@ +# ๋ฏธ์…˜ - ๋กœ๋˜ + +## ๐Ÿ•น ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ(๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก) + +### โŒจ๏ธ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋ฐ›๊ธฐ + +- [ ] ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅ ๋ฐ›๊ธฐ +- [ ] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ ๋ฐ›๊ธฐ +- [ ] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ ๋ฐ›๊ธฐ + +#### ์˜ˆ์™ธ : "[ERROR]"๋กœ ์‹œ์ž‘ + +- [ ] ์ˆซ์ž ์™ธ์˜ ๊ฒƒ์„ ์ž…๋ ฅํ•  ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ +- [ ] 1,000์›์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์„ ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ +- [ ] ์‰ผํ‘œ(,)๋กœ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์„ ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ +- [ ] ๋กœ๋˜ ๋ฒˆํ˜ธ ์ž…๋ ฅ๋ฐ›์„ ๋•Œ 1~45์˜ ์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ + +### ๐Ÿ–จ ์ถœ๋ ฅ + +- [ ] ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ์ˆ˜๋Ÿ‰ ์ถœ๋ ฅ +- [ ] ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ ์ถœ๋ ฅ + - [ ] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ + +#### ๐ŸŽฎ ๊ฒŒ์ž„ ์ข…๋ฃŒ + +- [ ] ๋‹น์ฒจ ๋‚ด์—ญ์„ ์ถœ๋ ฅ : ๋‹น์ฒจ ๊ธฐ์ค€์— ๋”ฐ๋ฅธ ๋‹น์ฒจ๋œ ๋กœ๋˜ ๊ฐœ์ˆ˜ ์ถœ๋ ฅ +- [ ] ์ด ์ˆ˜์ต๋ฅ  ์ถœ๋ ฅ + - [ ] ์†Œ์ˆ˜์  ๋‘˜์งธ ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ + +### ๐Ÿš˜ ๊ฒŒ์ž„ ํŒ๋‹จ + +- [ ] ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๋งคํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ ๋น„๊ต + +## ๐Ÿ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ + +- [x] `Node.js` `18.17.1` ๋ฒ„์ „์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅ +- [ ] `App.js`์˜ `play` ๋ฉ”์„œ๋“œ์—์„œ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ +- [ ] `ApplicationTest` ์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์„ฑ๊ณต +- [ ] indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ +- [ ] Jest๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‚ด๊ฐ€ ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก์ด ์ •์ƒ ๋™์ž‘ํ•จ์„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋กœ ํ™•์ธ + +### ์ถ”๊ฐ€ ์š”๊ตฌ ์‚ฌํ•ญ + +- [ ] ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)์˜ ๊ธธ์ด๊ฐ€ 15๋ผ์ธ์„ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ + - [ ] ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)๊ฐ€ ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ํ•˜๋„๋ก ๊ตฌํ˜„ +- else๋ฅผ ์ง€์–‘ + (ํžŒํŠธ: if ์กฐ๊ฑด์ ˆ์—์„œ ๊ฐ’์„ returnํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด else๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋จ. + ๋•Œ๋กœ๋Š” if/else, switch๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ๊น”๋”ํ•ด ๋ณด์ผ ์ˆ˜ ์žˆ์Œ.) +- [ ] ๋„๋ฉ”์ธ ๋กœ์ง์— ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ + - [ ] ํ•ต์‹ฌ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ์ฝ”๋“œ์™€ UI๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ๋กœ์ง์„ ๊ตฌ๋ถ„ + +### ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ + +- [ ] `@woowacourse/mission-utils`์—์„œ ์ œ๊ณตํ•˜๋Š” `Random` ๋ฐ `Console` API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ + +### Lotto ํด๋ž˜์Šค + +- [ ] ์ œ๊ณต๋œ `Lotto` ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•ด ๊ตฌํ˜„ +- [ ] `numbers`์˜ `#` prefix๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Œ +- [ ] `Lotto`์— ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†์Œ + +## ๐Ÿ““ ๊ณผ์ œ ์ง„ํ–‰ ์š”๊ตฌ ์‚ฌํ•ญ + +- [x] ์ €์žฅ์†Œ๋ฅผ Fork & Clone +- [ ] ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก ์ž‘์„ฑ From 6da2a4069e13a5e3b4820d8c7b550c3250036b39 Mon Sep 17 00:00:00 2001 From: "mingyeong:D" <63152086+Kim-Mingyeong@users.noreply.github.com> Date: Thu, 2 Nov 2023 15:47:35 +0900 Subject: [PATCH 02/10] =?UTF-8?q?docs:=203=EC=A3=BC=EC=B0=A8=20=EB=AF=B8?= =?UTF-8?q?=EC=85=98=20=EB=AA=A9=ED=91=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index e25d42cdcf..0f4ecd5744 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,10 @@ # ๋ฏธ์…˜ - ๋กœ๋˜ +## ๐ŸŽฏ ๋ชฉํ‘œ + +- [ ] ํด๋ž˜์Šค(๊ฐ์ฒด)๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ์—ฐ์Šต +- [ ] ๋„๋ฉ”์ธ ๋กœ์ง์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์—ฐ์Šต + ## ๐Ÿ•น ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ(๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก) ### โŒจ๏ธ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋ฐ›๊ธฐ @@ -27,7 +32,7 @@ - [ ] ์ด ์ˆ˜์ต๋ฅ  ์ถœ๋ ฅ - [ ] ์†Œ์ˆ˜์  ๋‘˜์งธ ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ -### ๐Ÿš˜ ๊ฒŒ์ž„ ํŒ๋‹จ +### ๐ŸŽฐ ๊ฒŒ์ž„ ํŒ๋‹จ - [ ] ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๋งคํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ ๋น„๊ต From 9719a00334886fcc28067c733c289abb2585a8e0 Mon Sep 17 00:00:00 2001 From: "mingyeong:D" <63152086+Kim-Mingyeong@users.noreply.github.com> Date: Tue, 7 Nov 2023 22:08:49 +0900 Subject: [PATCH 03/10] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EB=B0=9B=EA=B3=A0=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EC=98=88=EC=99=B8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=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 --- docs/README.md | 14 +++++++------- src/App.js | 32 ++++++++++++++++++++++++++++++++ src/Lotto.js | 40 +++++++++++++++++++++++++++++++++++++++- src/message.js | 16 ++++++++++++++++ 4 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 src/message.js diff --git a/docs/README.md b/docs/README.md index 0f4ecd5744..809b5de1ec 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,16 +9,16 @@ ### โŒจ๏ธ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋ฐ›๊ธฐ -- [ ] ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅ ๋ฐ›๊ธฐ -- [ ] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ ๋ฐ›๊ธฐ -- [ ] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ ๋ฐ›๊ธฐ +- [x] ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅ ๋ฐ›๊ธฐ +- [x] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ ๋ฐ›๊ธฐ +- [x] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ ๋ฐ›๊ธฐ #### ์˜ˆ์™ธ : "[ERROR]"๋กœ ์‹œ์ž‘ -- [ ] ์ˆซ์ž ์™ธ์˜ ๊ฒƒ์„ ์ž…๋ ฅํ•  ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ -- [ ] 1,000์›์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์„ ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ -- [ ] ์‰ผํ‘œ(,)๋กœ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์„ ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ -- [ ] ๋กœ๋˜ ๋ฒˆํ˜ธ ์ž…๋ ฅ๋ฐ›์„ ๋•Œ 1~45์˜ ์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ +- [x] ์ˆซ์ž ์™ธ์˜ ๊ฒƒ์„ ์ž…๋ ฅํ•  ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ +- [x] 1,000์›์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์„ ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ + ~~ - [ ] ์‰ผํ‘œ(,)๋กœ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์„ ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ~~ +- [x] ๋กœ๋˜ ๋ฒˆํ˜ธ ์ž…๋ ฅ๋ฐ›์„ ๋•Œ 1~45์˜ ์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ### ๐Ÿ–จ ์ถœ๋ ฅ diff --git a/src/App.js b/src/App.js index c38b30d5b2..4f6f74d850 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,36 @@ +import { Random, Console } from "@woowacourse/mission-utils"; +import { GAME, ERROR } from "./message"; +import { Lotto } from "./Lotto"; + class App { + #amount; + constructor() { + this.#amount = 0; + } + + #validate(amount) { + if (isNaN(amount) || amount < 0) { + throw new Error(ERROR.NOT_NUMBER); + } + if (amount % 1000 !== 0) { + throw new Error(ERROR.INVALID_AMOUNT); + } + } + + inputPurchaseAmount = async () => { + try { + const amount = parseInt( + await Console.readLineAsync(GAME.INPUT.AMOUNT), + 10 + ); + this.#validate(amount); + this.#amount = amount; + } catch (error) { + console.error(error.message); + this.inputPurchaseAmount(); + } + }; + async play() {} } diff --git a/src/Lotto.js b/src/Lotto.js index cb0b1527e9..091fbd4a5b 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -1,3 +1,7 @@ +import { Random, Console } from "@woowacourse/mission-utils"; +import { GAME, ERROR } from "./message"; +import { App } from "./App"; + class Lotto { #numbers; @@ -8,11 +12,45 @@ class Lotto { #validate(numbers) { if (numbers.length !== 6) { - throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + throw new Error(ERROR.INVALID_ARRAY_LENGTH); + } + + for (const number of numbers) { + if (number < 1 || number > 45) { + throw new Error(ERROR.OUT_OF_RANGE); + } + } + + const uniqueNumbers = new Set(numbers); + if (uniqueNumbers.size !== numbers.length) { + throw new Error(ERROR.DUPLICATE_NUMBER); } } // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ + inputWinningNumbers = async () => { + try { + const numbers = await Console.readLineAsync(GAME.INPUT.WINNING_NUMBER); + const numbersArray = numbers.split(","); + this.#validate(numbersArray); + } catch (error) { + console.error(error.message); + this.inputWinningNumbers(); + } + }; + + inputBonusNumber = async () => { + try { + const number = parseInt( + await Console.readLineAsync(GAME.INPUT.BONUS_NUMBER), + 10 + ); + this.#validate(number); + } catch (error) { + console.error(error.message); + this.inputBonusNumber(); + } + }; } export default Lotto; diff --git a/src/message.js b/src/message.js new file mode 100644 index 0000000000..b6ffd0e6c4 --- /dev/null +++ b/src/message.js @@ -0,0 +1,16 @@ +({ + INPUT: { + AMOUNT: "๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", + WINNING_NUMBER: "๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”\n", + BONUS_NUMBER: "๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", + }, + WINNING_STATISTICS: "๋‹น์ฒจ ํ†ต๊ณ„\n---", +}); + +export const ERROR = Object.freeze({ + NOT_NUMBER: "[ERROR] 0 ์ด์ƒ์˜ ์ž์—ฐ์ˆ˜๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.", + INVALID_AMOUNT: "[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์€ 1000์› ๋‹จ์œ„๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.", + INVALID_ARRAY_LENGTH: "[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.", + OUT_OF_RANGE: "[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.", + DUPLICATE_NUMBER: "[ERROR] ์ค‘๋ณต๋œ ๋ฒˆํ˜ธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค", +}); From c323cf5f7be5e591a9cca603d892bdcc640bd5b4 Mon Sep 17 00:00:00 2001 From: "mingyeong:D" <63152086+Kim-Mingyeong@users.noreply.github.com> Date: Wed, 8 Nov 2023 00:50:16 +0900 Subject: [PATCH 04/10] =?UTF-8?q?feat:=20=EB=B0=9C=ED=96=89=ED=95=9C=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=20=EC=88=98=EB=9F=89=20=EB=B0=8F=20=EB=A1=9C?= =?UTF-8?q?=EB=98=90=20=EB=B2=88=ED=98=B8=20=EC=98=A4=EB=A6=84=EC=B0=A8?= =?UTF-8?q?=EC=88=9C=EC=9C=BC=EB=A1=9C=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 8 ++++---- src/App.js | 31 +++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/docs/README.md b/docs/README.md index 809b5de1ec..ea62f8a809 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,14 +17,14 @@ - [x] ์ˆซ์ž ์™ธ์˜ ๊ฒƒ์„ ์ž…๋ ฅํ•  ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ - [x] 1,000์›์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์„ ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ - ~~ - [ ] ์‰ผํ‘œ(,)๋กœ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์„ ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ~~ +- ~~[ ] ์‰ผํ‘œ(,)๋กœ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์„ ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ~~ - [x] ๋กœ๋˜ ๋ฒˆํ˜ธ ์ž…๋ ฅ๋ฐ›์„ ๋•Œ 1~45์˜ ์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ### ๐Ÿ–จ ์ถœ๋ ฅ -- [ ] ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ์ˆ˜๋Ÿ‰ ์ถœ๋ ฅ -- [ ] ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ ์ถœ๋ ฅ - - [ ] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ +- [x] ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ์ˆ˜๋Ÿ‰ ์ถœ๋ ฅ +- [x] ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ ์ถœ๋ ฅ + - [x] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ #### ๐ŸŽฎ ๊ฒŒ์ž„ ์ข…๋ฃŒ diff --git a/src/App.js b/src/App.js index 4f6f74d850..fbdd54698d 100644 --- a/src/App.js +++ b/src/App.js @@ -1,21 +1,21 @@ import { Random, Console } from "@woowacourse/mission-utils"; import { GAME, ERROR } from "./message"; -import { Lotto } from "./Lotto"; +import Lotto from "./Lotto"; class App { - #amount; constructor() { - this.#amount = 0; + this.amount = 0; + this.lottos = []; } - #validate(amount) { + validateAmount = (amount) => { if (isNaN(amount) || amount < 0) { throw new Error(ERROR.NOT_NUMBER); } if (amount % 1000 !== 0) { throw new Error(ERROR.INVALID_AMOUNT); } - } + }; inputPurchaseAmount = async () => { try { @@ -23,15 +23,30 @@ class App { await Console.readLineAsync(GAME.INPUT.AMOUNT), 10 ); - this.#validate(amount); - this.#amount = amount; + this.validateAmount(amount); + this.amount = amount / 1000; } catch (error) { console.error(error.message); this.inputPurchaseAmount(); } + return this.amount; + }; + + generateLottosList = (amount) => { + Console.print(`${this.amount}๊ฐœ๋ฅผ ๊ตฌ์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.\n`); + for (let i = 0; i < amount; i += 1) { + const numbers = Random.pickUniqueNumbersInRange(1, 45, 6); + numbers.sort((a, b) => a - b); + const lotto = new Lotto(numbers); + this.lottos.push(lotto); + Console.print(lotto.toString()); + } }; - async play() {} + async play() { + const amount = await this.inputPurchaseAmount(); + this.generateLottosList(amount); + } } export default App; From e427e1175ee54ef184e50bbab1b9e69cd4288ee1 Mon Sep 17 00:00:00 2001 From: "mingyeong:D" <63152086+Kim-Mingyeong@users.noreply.github.com> Date: Wed, 8 Nov 2023 20:23:05 +0900 Subject: [PATCH 05/10] =?UTF-8?q?feat:=EB=A1=9C=EB=98=90=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EB=B9=84=EA=B5=90=20=ED=9B=84=20=EB=8B=B9=EC=B2=A8?= =?UTF-8?q?=20=EA=B8=B0=EC=A4=80=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EB=8B=B9?= =?UTF-8?q?=EC=B2=A8=EB=90=9C=20=EB=A1=9C=EB=98=90=20=EA=B0=9C=EC=88=98=20?= =?UTF-8?q?=EB=B0=8F=20=EC=88=98=EC=9D=B5=EB=A5=A0=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=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 --- docs/README.md | 20 ++++++------ src/App.js | 89 ++++++++++++++++++++++++++++++++++++++------------ src/Lotto.js | 83 +++++++++++++++++++++++++++++++++++----------- src/message.js | 4 +-- 4 files changed, 145 insertions(+), 51 deletions(-) diff --git a/docs/README.md b/docs/README.md index ea62f8a809..cfac697dd8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,18 +28,18 @@ #### ๐ŸŽฎ ๊ฒŒ์ž„ ์ข…๋ฃŒ -- [ ] ๋‹น์ฒจ ๋‚ด์—ญ์„ ์ถœ๋ ฅ : ๋‹น์ฒจ ๊ธฐ์ค€์— ๋”ฐ๋ฅธ ๋‹น์ฒจ๋œ ๋กœ๋˜ ๊ฐœ์ˆ˜ ์ถœ๋ ฅ -- [ ] ์ด ์ˆ˜์ต๋ฅ  ์ถœ๋ ฅ - - [ ] ์†Œ์ˆ˜์  ๋‘˜์งธ ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ +- [x] ๋‹น์ฒจ ๋‚ด์—ญ์„ ์ถœ๋ ฅ : ๋‹น์ฒจ ๊ธฐ์ค€์— ๋”ฐ๋ฅธ ๋‹น์ฒจ๋œ ๋กœ๋˜ ๊ฐœ์ˆ˜ ์ถœ๋ ฅ +- [x] ์ด ์ˆ˜์ต๋ฅ  ์ถœ๋ ฅ + - [x] ์†Œ์ˆ˜์  ๋‘˜์งธ ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ ### ๐ŸŽฐ ๊ฒŒ์ž„ ํŒ๋‹จ -- [ ] ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๋งคํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ ๋น„๊ต +- [x] ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๋งคํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ ๋น„๊ต ## ๐Ÿ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ - [x] `Node.js` `18.17.1` ๋ฒ„์ „์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅ -- [ ] `App.js`์˜ `play` ๋ฉ”์„œ๋“œ์—์„œ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ +- [x] `App.js`์˜ `play` ๋ฉ”์„œ๋“œ์—์„œ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ - [ ] `ApplicationTest` ์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์„ฑ๊ณต - [ ] indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ - [ ] Jest๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‚ด๊ฐ€ ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก์ด ์ •์ƒ ๋™์ž‘ํ•จ์„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋กœ ํ™•์ธ @@ -56,15 +56,15 @@ ### ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ -- [ ] `@woowacourse/mission-utils`์—์„œ ์ œ๊ณตํ•˜๋Š” `Random` ๋ฐ `Console` API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ +- [x] `@woowacourse/mission-utils`์—์„œ ์ œ๊ณตํ•˜๋Š” `Random` ๋ฐ `Console` API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ ### Lotto ํด๋ž˜์Šค -- [ ] ์ œ๊ณต๋œ `Lotto` ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•ด ๊ตฌํ˜„ -- [ ] `numbers`์˜ `#` prefix๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Œ -- [ ] `Lotto`์— ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†์Œ +- [x] ์ œ๊ณต๋œ `Lotto` ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•ด ๊ตฌํ˜„ +- [x] `numbers`์˜ `#` prefix๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Œ +- [x] `Lotto`์— ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†์Œ ## ๐Ÿ““ ๊ณผ์ œ ์ง„ํ–‰ ์š”๊ตฌ ์‚ฌํ•ญ - [x] ์ €์žฅ์†Œ๋ฅผ Fork & Clone -- [ ] ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก ์ž‘์„ฑ +- [x] ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก ์ž‘์„ฑ diff --git a/src/App.js b/src/App.js index fbdd54698d..e66f3fd2b6 100644 --- a/src/App.js +++ b/src/App.js @@ -3,9 +3,12 @@ import { GAME, ERROR } from "./message"; import Lotto from "./Lotto"; class App { + #amount; + #lottos; + constructor() { - this.amount = 0; - this.lottos = []; + this.#amount = 0; + this.#lottos = []; } validateAmount = (amount) => { @@ -18,34 +21,80 @@ class App { }; inputPurchaseAmount = async () => { - try { - const amount = parseInt( - await Console.readLineAsync(GAME.INPUT.AMOUNT), - 10 - ); - this.validateAmount(amount); - this.amount = amount / 1000; - } catch (error) { - console.error(error.message); - this.inputPurchaseAmount(); + while (true) { + try { + this.#amount = Number(await Console.readLineAsync(GAME.INPUT.AMOUNT)); + this.validateAmount(this.#amount); + const count = this.#amount / 1000; + this.generateLottosList(count); + break; + } catch (error) { + console.error(error.message); + } } - return this.amount; }; - generateLottosList = (amount) => { - Console.print(`${this.amount}๊ฐœ๋ฅผ ๊ตฌ์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.\n`); - for (let i = 0; i < amount; i += 1) { + generateLottosList = (count) => { + Console.print(`${count}๊ฐœ๋ฅผ ๊ตฌ์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.\n`); + + for (let i = 0; i < count; i += 1) { const numbers = Random.pickUniqueNumbersInRange(1, 45, 6); numbers.sort((a, b) => a - b); const lotto = new Lotto(numbers); - this.lottos.push(lotto); - Console.print(lotto.toString()); + this.#lottos.push(lotto); + Console.print(`[${lotto.join(", ")}]`); + } + }; + + winningStatistics = async () => { + const winningNumbers = await this.inputWinningNumbers(); + const bonusNumber = await this.inputBonusNumber(); + const matchedCounts = []; + + for (const lotto of this.lottos) { + const { matchedNumbers, matchedBonusNumber } = lotto.matchedNumbers( + winningNumbers, + bonusNumber + ); + const matchedCount = lotto.compareNumbers( + matchedNumbers, + matchedBonusNumber + ); + matchedCounts.push(matchedCount); } + this.printWinningStatistics(matchedCounts); + this.calculateProfitRate(matchedCounts); + }; + + printWinningStatistics = (matchedCounts) => { + Console.print(GAME.WINNING_STATISTICS); + const prizeMoney = [5000, 50000, 1500000, 30000000, 2000000000]; + for (let i = 0; i < 5; i += 1) { + Console.print( + `${i + 3}๊ฐœ ์ผ์น˜ (${prizeMoney[i]}์›) - ${matchedCounts.reduce( + (acc, count) => acc + count[i], + 0 + )}๊ฐœ` + ); + } + }; + + calculateProfitRate = (matchedCounts) => { + const prizeMoney = [5000, 50000, 1500000, 30000000, 2000000000]; + let totalProfit = 0; + + for (let i = 0; i < 5; i += 1) { + totalProfit += + prizeMoney[i] * matchedCounts.reduce((acc, count) => acc + count[i], 0); + } + let profitRate = ((totalProfit / this.#amount) * 100).toFixed(1); + + Console.print(`์ด ์ˆ˜์ต๋ฅ ์€ ${profitRate}%์ž…๋‹ˆ๋‹ค.`); }; async play() { - const amount = await this.inputPurchaseAmount(); - this.generateLottosList(amount); + await this.inputPurchaseAmount(); + this.winningStatistics(); } } diff --git a/src/Lotto.js b/src/Lotto.js index 091fbd4a5b..576ad04772 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -1,6 +1,5 @@ -import { Random, Console } from "@woowacourse/mission-utils"; +import { Console } from "@woowacourse/mission-utils"; import { GAME, ERROR } from "./message"; -import { App } from "./App"; class Lotto { #numbers; @@ -27,29 +26,75 @@ class Lotto { } } + validateBonusNumber = (number, winningNumbers) => { + if (isNaN(number) || number < 0) { + throw new Error(ERROR.NOT_NUMBER); + } + if (number < 1 || number > 45) { + throw new Error(ERROR.OUT_OF_RANGE); + } + if (winningNumbers.includes(number)) { + throw new Error(ERROR.DUPLICATE_NUMBER); + } + }; + // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ inputWinningNumbers = async () => { - try { - const numbers = await Console.readLineAsync(GAME.INPUT.WINNING_NUMBER); - const numbersArray = numbers.split(","); - this.#validate(numbersArray); - } catch (error) { - console.error(error.message); - this.inputWinningNumbers(); + let numbersArray; + while (true) { + try { + const numbers = await Console.readLineAsync(GAME.INPUT.WINNING_NUMBER); + const numbersArray = numbers.split(","); + this.#validate(numbersArray); + break; + } catch (error) { + console.error(error.message); + } + } + return numbersArray; + }; + + inputBonusNumber = async (winningNumbers) => { + while (true) { + try { + const number = Number( + await Console.readLineAsync(GAME.INPUT.BONUS_NUMBER) + ); + this.validateBonusNumber(number, winningNumbers); + break; + } catch (error) { + console.error(error.message); + } } + return number; + }; + + matchedNumbers = (winningNumbers, bonusNumber) => { + const matchedNumbers = this.#numbers.filter((number) => + winningNumbers.includes(number) + ); + const matchedBonusNumber = matchedNumbers.includes(bonusNumber); + + return { matchedNumbers, matchedBonusNumber }; }; - inputBonusNumber = async () => { - try { - const number = parseInt( - await Console.readLineAsync(GAME.INPUT.BONUS_NUMBER), - 10 - ); - this.#validate(number); - } catch (error) { - console.error(error.message); - this.inputBonusNumber(); + compareNumbers = (matchedNumbers, matchedBonusNumber) => { + let matched = [0, 0, 0, 0, 0]; + const matchedCount = matchedNumbers.length; + + if (matchedCount === 6) { + matched[4] += 1; + } else if (matchedCount === 5 && matchedBonusNumber) { + matched[3] += 1; + } else if (matchedCount === 5) { + matched[2] += 1; + } else if (matchedCount === 4) { + matched[1] += 1; + } else if (matchedCount === 3) { + matched[0] += 1; } + + return matched; }; } diff --git a/src/message.js b/src/message.js index b6ffd0e6c4..be78a6953a 100644 --- a/src/message.js +++ b/src/message.js @@ -1,10 +1,10 @@ -({ +export const GAME = Object.freeze({ INPUT: { AMOUNT: "๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", WINNING_NUMBER: "๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”\n", BONUS_NUMBER: "๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", }, - WINNING_STATISTICS: "๋‹น์ฒจ ํ†ต๊ณ„\n---", + WINNING_STATISTICS: "๋‹น์ฒจ ํ†ต๊ณ„\n---\n", }); export const ERROR = Object.freeze({ From d2280264dae6c0c8b37afca437adfad34e4a648b Mon Sep 17 00:00:00 2001 From: "mingyeong:D" <63152086+Kim-Mingyeong@users.noreply.github.com> Date: Wed, 8 Nov 2023 20:29:44 +0900 Subject: [PATCH 06/10] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/App.js | 9 +-------- src/Lotto.js | 7 +------ 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/docs/README.md b/docs/README.md index cfac697dd8..9bbb5b15f6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -41,7 +41,7 @@ - [x] `Node.js` `18.17.1` ๋ฒ„์ „์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅ - [x] `App.js`์˜ `play` ๋ฉ”์„œ๋“œ์—์„œ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ - [ ] `ApplicationTest` ์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์„ฑ๊ณต -- [ ] indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ +- [x] indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ - [ ] Jest๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‚ด๊ฐ€ ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก์ด ์ •์ƒ ๋™์ž‘ํ•จ์„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋กœ ํ™•์ธ ### ์ถ”๊ฐ€ ์š”๊ตฌ ์‚ฌํ•ญ diff --git a/src/App.js b/src/App.js index e66f3fd2b6..e602fb67b3 100644 --- a/src/App.js +++ b/src/App.js @@ -52,14 +52,7 @@ class App { const matchedCounts = []; for (const lotto of this.lottos) { - const { matchedNumbers, matchedBonusNumber } = lotto.matchedNumbers( - winningNumbers, - bonusNumber - ); - const matchedCount = lotto.compareNumbers( - matchedNumbers, - matchedBonusNumber - ); + const matchedCount = lotto.compareNumbers(winningNumbers, bonusNumber); matchedCounts.push(matchedCount); } this.printWinningStatistics(matchedCounts); diff --git a/src/Lotto.js b/src/Lotto.js index 576ad04772..3760f1386a 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -69,16 +69,11 @@ class Lotto { return number; }; - matchedNumbers = (winningNumbers, bonusNumber) => { + compareNumbers = (winningNumbers, bonusNumber) => { const matchedNumbers = this.#numbers.filter((number) => winningNumbers.includes(number) ); const matchedBonusNumber = matchedNumbers.includes(bonusNumber); - - return { matchedNumbers, matchedBonusNumber }; - }; - - compareNumbers = (matchedNumbers, matchedBonusNumber) => { let matched = [0, 0, 0, 0, 0]; const matchedCount = matchedNumbers.length; From eaf6b7a78ac51f8ada57553d942151144730eb6f Mon Sep 17 00:00:00 2001 From: "mingyeong:D" <63152086+Kim-Mingyeong@users.noreply.github.com> Date: Wed, 8 Nov 2023 23:56:35 +0900 Subject: [PATCH 07/10] =?UTF-8?q?fix:=20=EA=B8=B0=EB=8A=A5=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=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 | 136 +++++++++++++++++++++++++++++++++++++++++-------- src/Lotto.js | 67 +++--------------------- src/message.js | 1 + 3 files changed, 123 insertions(+), 81 deletions(-) diff --git a/src/App.js b/src/App.js index e602fb67b3..5ed2585633 100644 --- a/src/App.js +++ b/src/App.js @@ -20,6 +20,35 @@ class App { } }; + validateWinningNumbers = (numbers) => { + if (numbers.length !== 6) { + throw new Error(ERROR.INVALID_ARRAY_LENGTH); + } + + for (const number of numbers) { + if (number < 1 || number > 45) { + throw new Error(ERROR.OUT_OF_RANGE); + } + } + + const uniqueNumbers = new Set(numbers); + if (uniqueNumbers.size !== numbers.length) { + throw new Error(ERROR.DUPLICATE_NUMBER); + } + }; + + validateBonusNumber = (number, winningNumbers) => { + if (isNaN(number) || number < 0) { + throw new Error(ERROR.NOT_NUMBER); + } + if (number < 1 || number > 45) { + throw new Error(ERROR.OUT_OF_RANGE); + } + if (winningNumbers.includes(number)) { + throw new Error(ERROR.DUPLICATE_NUMBER); + } + }; + inputPurchaseAmount = async () => { while (true) { try { @@ -29,7 +58,7 @@ class App { this.generateLottosList(count); break; } catch (error) { - console.error(error.message); + throw new Error(ERROR.INPUT); } } }; @@ -39,55 +68,122 @@ class App { for (let i = 0; i < count; i += 1) { const numbers = Random.pickUniqueNumbersInRange(1, 45, 6); - numbers.sort((a, b) => a - b); + this.#lottos.push(numbers); const lotto = new Lotto(numbers); - this.#lottos.push(lotto); - Console.print(`[${lotto.join(", ")}]`); + lotto.printLottos(); } }; - winningStatistics = async () => { + inputWinningNumbers = async () => { + while (true) { + try { + const numbers = await Console.readLineAsync(GAME.INPUT.WINNING_NUMBER); + const numbersArray = numbers + .split(",") + .map((num) => Number(num.trim())); + this.validateWinningNumbers(numbersArray); + return numbersArray; + } catch (error) { + throw new Error(ERROR.INPUT); + } + } + }; + + inputBonusNumber = async (winningNumbers) => { + while (true) { + try { + const number = Number( + await Console.readLineAsync(GAME.INPUT.BONUS_NUMBER) + ); + this.validateBonusNumber(number, winningNumbers); + return number; + } catch (error) { + throw new Error(ERROR.INPUT); + } + } + }; + + matchedNumbers = async () => { const winningNumbers = await this.inputWinningNumbers(); - const bonusNumber = await this.inputBonusNumber(); - const matchedCounts = []; + const bonusNumber = await this.inputBonusNumber(winningNumbers); - for (const lotto of this.lottos) { - const matchedCount = lotto.compareNumbers(winningNumbers, bonusNumber); - matchedCounts.push(matchedCount); + let matched = []; + this.#lottos.forEach((lotto) => { + const matchedCount = this.compareNumbers( + lotto, + winningNumbers, + bonusNumber + ); + matched.push(matchedCount); + }); + + return matched; + }; + + compareNumbers = (lotto, winningNumbers, bonusNumber) => { + let matchedCount = 0; + + lotto.forEach((number) => { + if (winningNumbers.includes(number)) { + matchedCount += 1; + } + }); + + if (matchedCount === 6) { + return 4; + } else if (matchedCount === 5 && lotto.includes(bonusNumber)) { + return 3; + } else if (matchedCount === 5) { + return 2; + } else if (matchedCount === 4) { + return 1; + } else if (matchedCount === 3) { + return 0; } + }; + + winningStatistics = async () => { + const matchedCounts = await this.matchedNumbers(); this.printWinningStatistics(matchedCounts); this.calculateProfitRate(matchedCounts); }; printWinningStatistics = (matchedCounts) => { Console.print(GAME.WINNING_STATISTICS); - const prizeMoney = [5000, 50000, 1500000, 30000000, 2000000000]; + console.log(matchedCounts); + + const prizeMoney = [ + "5,000", + "50,000", + "1,500,000", + "30,000,000", + "2,000,000,000", + ]; for (let i = 0; i < 5; i += 1) { + if (isNaN(matchedCounts[i])) { + matchedCounts[i] = 0; + } Console.print( - `${i + 3}๊ฐœ ์ผ์น˜ (${prizeMoney[i]}์›) - ${matchedCounts.reduce( - (acc, count) => acc + count[i], - 0 - )}๊ฐœ` + `${i + 3}๊ฐœ ์ผ์น˜ (${prizeMoney[i]}์›) - ${matchedCounts[i]}๊ฐœ` ); } }; calculateProfitRate = (matchedCounts) => { const prizeMoney = [5000, 50000, 1500000, 30000000, 2000000000]; - let totalProfit = 0; + let totalCost = this.#amount; for (let i = 0; i < 5; i += 1) { - totalProfit += - prizeMoney[i] * matchedCounts.reduce((acc, count) => acc + count[i], 0); + totalCost += prizeMoney[i] * matchedCounts[i]; } - let profitRate = ((totalProfit / this.#amount) * 100).toFixed(1); + const profitRate = ((totalCost / this.#amount) * 100).toFixed(1); Console.print(`์ด ์ˆ˜์ต๋ฅ ์€ ${profitRate}%์ž…๋‹ˆ๋‹ค.`); }; async play() { await this.inputPurchaseAmount(); - this.winningStatistics(); + await this.winningStatistics(); } } diff --git a/src/Lotto.js b/src/Lotto.js index 3760f1386a..e78b565850 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -1,5 +1,5 @@ import { Console } from "@woowacourse/mission-utils"; -import { GAME, ERROR } from "./message"; +import { ERROR } from "./message"; class Lotto { #numbers; @@ -26,70 +26,15 @@ class Lotto { } } - validateBonusNumber = (number, winningNumbers) => { - if (isNaN(number) || number < 0) { - throw new Error(ERROR.NOT_NUMBER); - } - if (number < 1 || number > 45) { - throw new Error(ERROR.OUT_OF_RANGE); - } - if (winningNumbers.includes(number)) { - throw new Error(ERROR.DUPLICATE_NUMBER); - } - }; - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ - inputWinningNumbers = async () => { - let numbersArray; - while (true) { - try { - const numbers = await Console.readLineAsync(GAME.INPUT.WINNING_NUMBER); - const numbersArray = numbers.split(","); - this.#validate(numbersArray); - break; - } catch (error) { - console.error(error.message); - } - } - return numbersArray; - }; - inputBonusNumber = async (winningNumbers) => { - while (true) { - try { - const number = Number( - await Console.readLineAsync(GAME.INPUT.BONUS_NUMBER) - ); - this.validateBonusNumber(number, winningNumbers); - break; - } catch (error) { - console.error(error.message); - } - } - return number; + sortAscending = () => { + this.#numbers.sort((a, b) => a - b); }; - compareNumbers = (winningNumbers, bonusNumber) => { - const matchedNumbers = this.#numbers.filter((number) => - winningNumbers.includes(number) - ); - const matchedBonusNumber = matchedNumbers.includes(bonusNumber); - let matched = [0, 0, 0, 0, 0]; - const matchedCount = matchedNumbers.length; - - if (matchedCount === 6) { - matched[4] += 1; - } else if (matchedCount === 5 && matchedBonusNumber) { - matched[3] += 1; - } else if (matchedCount === 5) { - matched[2] += 1; - } else if (matchedCount === 4) { - matched[1] += 1; - } else if (matchedCount === 3) { - matched[0] += 1; - } - - return matched; + printLottos = () => { + this.sortAscending(); + Console.print(`[${this.#numbers.join(", ")}]`); }; } diff --git a/src/message.js b/src/message.js index be78a6953a..9965032b4e 100644 --- a/src/message.js +++ b/src/message.js @@ -8,6 +8,7 @@ export const GAME = Object.freeze({ }); export const ERROR = Object.freeze({ + INPUT: "[ERROR] ์ž…๋ ฅ์„ ์‹คํŒจํ•˜์˜€์Šต๋‹ˆ๋‹ค.", NOT_NUMBER: "[ERROR] 0 ์ด์ƒ์˜ ์ž์—ฐ์ˆ˜๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.", INVALID_AMOUNT: "[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์€ 1000์› ๋‹จ์œ„๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.", INVALID_ARRAY_LENGTH: "[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.", From 29f7c65abf36ca98b106683258a4e00b8d04ee22 Mon Sep 17 00:00:00 2001 From: "mingyeong:D" <63152086+Kim-Mingyeong@users.noreply.github.com> Date: Thu, 9 Nov 2023 00:38:37 +0900 Subject: [PATCH 08/10] =?UTF-8?q?fix:=20=EB=A1=9C=EB=98=90=20=EC=88=AB?= =?UTF-8?q?=EC=9E=90=20=EB=B9=84=EA=B5=90=ED=95=A8=EB=8A=94=20matchedNumbe?= =?UTF-8?q?rs()=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/App.js | 55 ++++++++++++++++++-------------------------------- src/Lotto.js | 2 +- 3 files changed, 22 insertions(+), 37 deletions(-) diff --git a/docs/README.md b/docs/README.md index 9bbb5b15f6..cfac697dd8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -41,7 +41,7 @@ - [x] `Node.js` `18.17.1` ๋ฒ„์ „์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅ - [x] `App.js`์˜ `play` ๋ฉ”์„œ๋“œ์—์„œ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ - [ ] `ApplicationTest` ์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์„ฑ๊ณต -- [x] indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ +- [ ] indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ - [ ] Jest๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‚ด๊ฐ€ ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก์ด ์ •์ƒ ๋™์ž‘ํ•จ์„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋กœ ํ™•์ธ ### ์ถ”๊ฐ€ ์š”๊ตฌ ์‚ฌํ•ญ diff --git a/src/App.js b/src/App.js index 5ed2585633..9cd0852ee9 100644 --- a/src/App.js +++ b/src/App.js @@ -64,7 +64,7 @@ class App { }; generateLottosList = (count) => { - Console.print(`${count}๊ฐœ๋ฅผ ๊ตฌ์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.\n`); + Console.print(`${count}๊ฐœ๋ฅผ ๊ตฌ์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.`); for (let i = 0; i < count; i += 1) { const numbers = Random.pickUniqueNumbersInRange(1, 45, 6); @@ -107,39 +107,28 @@ class App { const winningNumbers = await this.inputWinningNumbers(); const bonusNumber = await this.inputBonusNumber(winningNumbers); - let matched = []; + let matched = [0, 0, 0, 0, 0]; this.#lottos.forEach((lotto) => { - const matchedCount = this.compareNumbers( - lotto, - winningNumbers, - bonusNumber - ); - matched.push(matchedCount); - }); - - return matched; - }; - - compareNumbers = (lotto, winningNumbers, bonusNumber) => { - let matchedCount = 0; - - lotto.forEach((number) => { - if (winningNumbers.includes(number)) { - matchedCount += 1; + let matchedCount = 0; + lotto.forEach((number) => { + if (winningNumbers.includes(number)) { + matchedCount += 1; + } + }); + if (matchedCount === 6) { + matched[4] += 1; + } else if (matchedCount === 5 && lotto.includes(bonusNumber)) { + matched[3] += 1; + } else if (matchedCount === 5) { + matched[2] += 1; + } else if (matchedCount === 4) { + matched[1] += 1; + } else if (matchedCount === 3) { + matched[0] += 1; } }); - if (matchedCount === 6) { - return 4; - } else if (matchedCount === 5 && lotto.includes(bonusNumber)) { - return 3; - } else if (matchedCount === 5) { - return 2; - } else if (matchedCount === 4) { - return 1; - } else if (matchedCount === 3) { - return 0; - } + return matched; }; winningStatistics = async () => { @@ -150,7 +139,6 @@ class App { printWinningStatistics = (matchedCounts) => { Console.print(GAME.WINNING_STATISTICS); - console.log(matchedCounts); const prizeMoney = [ "5,000", @@ -160,9 +148,6 @@ class App { "2,000,000,000", ]; for (let i = 0; i < 5; i += 1) { - if (isNaN(matchedCounts[i])) { - matchedCounts[i] = 0; - } Console.print( `${i + 3}๊ฐœ ์ผ์น˜ (${prizeMoney[i]}์›) - ${matchedCounts[i]}๊ฐœ` ); @@ -171,7 +156,7 @@ class App { calculateProfitRate = (matchedCounts) => { const prizeMoney = [5000, 50000, 1500000, 30000000, 2000000000]; - let totalCost = this.#amount; + let totalCost = 0; for (let i = 0; i < 5; i += 1) { totalCost += prizeMoney[i] * matchedCounts[i]; diff --git a/src/Lotto.js b/src/Lotto.js index e78b565850..dd52a1ef11 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -27,7 +27,6 @@ class Lotto { } // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ - sortAscending = () => { this.#numbers.sort((a, b) => a - b); }; @@ -35,6 +34,7 @@ class Lotto { printLottos = () => { this.sortAscending(); Console.print(`[${this.#numbers.join(", ")}]`); + console.log(this.#numbers); }; } From 0e53e3f833d10b9c1e082c9254c311a921b9cc5d Mon Sep 17 00:00:00 2001 From: "mingyeong:D" <63152086+Kim-Mingyeong@users.noreply.github.com> Date: Thu, 9 Nov 2023 00:40:52 +0900 Subject: [PATCH 09/10] =?UTF-8?q?refactor:=20matchedNumbers()=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EA=B5=AC=EC=A1=B0=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/App.js b/src/App.js index 9cd0852ee9..a7feaeb107 100644 --- a/src/App.js +++ b/src/App.js @@ -108,24 +108,18 @@ class App { const bonusNumber = await this.inputBonusNumber(winningNumbers); let matched = [0, 0, 0, 0, 0]; + this.#lottos.forEach((lotto) => { - let matchedCount = 0; - lotto.forEach((number) => { - if (winningNumbers.includes(number)) { - matchedCount += 1; - } - }); - if (matchedCount === 6) { - matched[4] += 1; - } else if (matchedCount === 5 && lotto.includes(bonusNumber)) { + const matchedCount = lotto.filter((number) => + winningNumbers.includes(number) + ).length; + + if (matchedCount === 6) matched[4] += 1; + else if (matchedCount === 5 && lotto.includes(bonusNumber)) { matched[3] += 1; - } else if (matchedCount === 5) { - matched[2] += 1; - } else if (matchedCount === 4) { - matched[1] += 1; - } else if (matchedCount === 3) { - matched[0] += 1; - } + } else if (matchedCount === 5) matched[2] += 1; + else if (matchedCount === 4) matched[1] += 1; + else if (matchedCount === 3) matched[0] += 1; }); return matched; From 707d78dce6146b4ba0a01262dea9eb30895d1f08 Mon Sep 17 00:00:00 2001 From: "mingyeong:D" <63152086+Kim-Mingyeong@users.noreply.github.com> Date: Thu, 9 Nov 2023 00:55:42 +0900 Subject: [PATCH 10/10] =?UTF-8?q?refactor:console.log=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/Lotto.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index cfac697dd8..9bbb5b15f6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -41,7 +41,7 @@ - [x] `Node.js` `18.17.1` ๋ฒ„์ „์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅ - [x] `App.js`์˜ `play` ๋ฉ”์„œ๋“œ์—์„œ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ - [ ] `ApplicationTest` ์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์„ฑ๊ณต -- [ ] indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ +- [x] indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ - [ ] Jest๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‚ด๊ฐ€ ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก์ด ์ •์ƒ ๋™์ž‘ํ•จ์„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋กœ ํ™•์ธ ### ์ถ”๊ฐ€ ์š”๊ตฌ ์‚ฌํ•ญ diff --git a/src/Lotto.js b/src/Lotto.js index dd52a1ef11..01a5f2aeee 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -34,7 +34,6 @@ class Lotto { printLottos = () => { this.sortAscending(); Console.print(`[${this.#numbers.join(", ")}]`); - console.log(this.#numbers); }; }