From 51ae201209320fea6492b49a5401d9a7ad6860ff Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Thu, 31 Oct 2024 18:47:59 +0900 Subject: [PATCH 01/21] =?UTF-8?q?docs:=20README.md=EC=97=90=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=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 --- README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/README.md b/README.md index 15bb106b5..b605e8ddd 100644 --- a/README.md +++ b/README.md @@ -1 +1,36 @@ # javascript-lotto-precourse + +# 기능 목록 + +## 입력 + +- [ ] 1,000원 단위로 로또 구입 금액을 입력받는다. + - [ ] 잘못된 값을 입력할 경우 "[ERROR]"로 시작하는 메시지와 함께 `Error`를 발생시킨다. 잘못된 값은 아래에 해당한다. + - [ ] 1,000원 미만인 경우 + - [ ] 1,000원으로 나누어 떨어지지 않는 경우 + - [ ] 에러 발생 후, 해당 지점부터 다시 입력받는다. +- [ ] 로또발행 내역이 출력된 후, 쉼표(,)를 기준으로 6개의 당첨 번호를 입력받는다. + - [ ] 예외처리 `Error` 예외의 경우는 밑에 해당한다. + - [ ] 1~45 사이의 숫자가 아닌 경우 +- [ ] 당첨번호 입력받은 후, 보너스 번호를 입력받는다. + - [ ] 예외처리 `Error` + - [ ] 1~45 사이의 숫자가 아닌 경우 + +## 출력 + +- [ ] 발행한 로또 수량을 출력한다. +- [ ] 오름차순 정렬된 로또 번호들을 로또 수량만큼 출력한다. +- [ ] 계산되어 반환된 당첨내역을 출력한다. +- [ ] 계산되어 반환된 수익률을 출력한다. + +## 핵심 기능 + +- [ ] 입력받은 로또 구입 금액에 해당하는 만큼 로또를 발행한다. (로또 1장은 1,000원이다) + - [ ] 로또 1장 당 1~45 사이의 중복되지 않는 6개의 숫자를 뽑는다. +- [ ] 사용자가 구매한 로또 번호와, 당첨 번호를 비교해 당첨내역을 계산해 반환한다. + - [ ] 1등: 6개 번호 일치 / 2,000,000,000원 + - [ ] 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원 + - [ ] 3등: 5개 번호 일치 / 1,500,000원 + - [ ] 4등: 4개 번호 일치 / 50,000원 + - [ ] 5등: 3개 번호 일치 / 5,000원 +- [ ] 소수점 둘째 자리에서 반올림 한 수익률을 계산해 반환한다. From 0575702a60802094f30def792bf762b533041bce Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Thu, 31 Oct 2024 20:14:33 +0900 Subject: [PATCH 02/21] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EA=B5=AC?= =?UTF-8?q?=EC=9E=85=20=EA=B8=88=EC=95=A1=20=EC=9E=85=EB=A0=A5=EB=B0=9B?= =?UTF-8?q?=EB=8A=94=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 --- README.md | 7 +++---- src/App.js | 26 +++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b605e8ddd..b54b9bae9 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,10 @@ ## 입력 -- [ ] 1,000원 단위로 로또 구입 금액을 입력받는다. +- [x] 1,000원 단위로 로또 구입 금액을 입력받는다. - [ ] 잘못된 값을 입력할 경우 "[ERROR]"로 시작하는 메시지와 함께 `Error`를 발생시킨다. 잘못된 값은 아래에 해당한다. - - [ ] 1,000원 미만인 경우 - - [ ] 1,000원으로 나누어 떨어지지 않는 경우 - - [ ] 에러 발생 후, 해당 지점부터 다시 입력받는다. + - [x] 1,000원으로 나누어 떨어지지 않는 경우 = 1,000원 미만인 경우 + - [x] 에러 발생 후, 해당 지점부터 다시 입력받는다. - [ ] 로또발행 내역이 출력된 후, 쉼표(,)를 기준으로 6개의 당첨 번호를 입력받는다. - [ ] 예외처리 `Error` 예외의 경우는 밑에 해당한다. - [ ] 1~45 사이의 숫자가 아닌 경우 diff --git a/src/App.js b/src/App.js index 091aa0a5d..c241be00c 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,29 @@ +import { MissionUtils } from "@woowacourse/mission-utils"; +import Lotto from "./Lotto.js"; +const GUIDE_MESSAGE_INPUT_COST = "구입금액을 입력해 주세요.\n"; +const ERROR_MESSAGE_INVALID_COST = + "[ERROR] 입력하신 금액이 1,000원 단위가 아닙니다. 다시"; + class App { - async run() {} + async run() { + let isValid = false; + let lottoCost = 0; + + while (!isValid) { + try { + lottoCost = Number( + await MissionUtils.Console.readLineAsync(GUIDE_MESSAGE_INPUT_COST) + ); + if (lottoCost % 1000 !== 0) { + throw new Error(ERROR_MESSAGE_INVALID_COST); + } + + isValid = true; + } catch (error) { + console.error(error.message); + } + } + } } export default App; From 3d1bdd41285e95ca32f492f84b91e9c2ed846b2b Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Thu, 31 Oct 2024 22:00:48 +0900 Subject: [PATCH 03/21] =?UTF-8?q?feat:=20=EC=9E=85=EB=A0=A5=EB=B0=9B?= =?UTF-8?q?=EC=9D=80=20=EA=B8=88=EC=95=A1=20=EB=A7=8C=ED=81=BC=20=EB=A1=9C?= =?UTF-8?q?=EB=98=90=20=EB=B0=9C=ED=96=89=ED=95=98=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=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 --- README.md | 5 +++-- src/App.js | 25 +++++++++++++------------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b54b9bae9..e33164ac9 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,9 @@ ## 핵심 기능 -- [ ] 입력받은 로또 구입 금액에 해당하는 만큼 로또를 발행한다. (로또 1장은 1,000원이다) - - [ ] 로또 1장 당 1~45 사이의 중복되지 않는 6개의 숫자를 뽑는다. +- [x] 입력받은 로또 구입 금액에 해당하는 만큼 로또를 발행한다. (로또 1장은 1,000원이다) + - [x] 로또 1장 당 1~45 사이의 중복되지 않는 6개의 숫자를 뽑는다. + - [ ] 숫자들을 오름차순 정렬한다. - [ ] 사용자가 구매한 로또 번호와, 당첨 번호를 비교해 당첨내역을 계산해 반환한다. - [ ] 1등: 6개 번호 일치 / 2,000,000,000원 - [ ] 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원 diff --git a/src/App.js b/src/App.js index c241be00c..8e8ad6b24 100644 --- a/src/App.js +++ b/src/App.js @@ -6,22 +6,23 @@ const ERROR_MESSAGE_INVALID_COST = class App { async run() { + let lottoCost; let isValid = false; - let lottoCost = 0; while (!isValid) { - try { - lottoCost = Number( - await MissionUtils.Console.readLineAsync(GUIDE_MESSAGE_INPUT_COST) - ); - if (lottoCost % 1000 !== 0) { - throw new Error(ERROR_MESSAGE_INVALID_COST); - } - - isValid = true; - } catch (error) { - console.error(error.message); + lottoCost = Number( + await MissionUtils.Console.readLineAsync(GUIDE_MESSAGE_INPUT_COST) + ); + if (lottoCost % 1000 !== 0) { + throw new Error(ERROR_MESSAGE_INVALID_COST); } + isValid = true; + } + + const lottoCnt = lottoCost / 1000; + let lottoNumbers = []; + for (let i = 0; i < lottoCnt; i++) { + lottoNumbers[i] = MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6); } } } From 440dc375e242f71bd83ab9d5dc2bbda25ca2dfda Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Thu, 31 Oct 2024 22:01:51 +0900 Subject: [PATCH 04/21] =?UTF-8?q?feat:=20=EB=B0=9C=ED=96=89=EB=90=9C=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=20=EC=88=AB=EC=9E=90=EB=93=A4=20=EC=98=A4?= =?UTF-8?q?=EB=A6=84=EC=B0=A8=EC=88=9C=20=EC=A0=95=EB=A0=AC=ED=95=98?= =?UTF-8?q?=EB=8A=94=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 --- README.md | 2 +- src/App.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e33164ac9..065b81fad 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ - [x] 입력받은 로또 구입 금액에 해당하는 만큼 로또를 발행한다. (로또 1장은 1,000원이다) - [x] 로또 1장 당 1~45 사이의 중복되지 않는 6개의 숫자를 뽑는다. - - [ ] 숫자들을 오름차순 정렬한다. + - [x] 숫자들을 오름차순 정렬한다. - [ ] 사용자가 구매한 로또 번호와, 당첨 번호를 비교해 당첨내역을 계산해 반환한다. - [ ] 1등: 6개 번호 일치 / 2,000,000,000원 - [ ] 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원 diff --git a/src/App.js b/src/App.js index 8e8ad6b24..3455a018f 100644 --- a/src/App.js +++ b/src/App.js @@ -23,6 +23,9 @@ class App { let lottoNumbers = []; for (let i = 0; i < lottoCnt; i++) { lottoNumbers[i] = MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6); + lottoNumbers[i].sort((a, b) => { + return a - b; + }); } } } From e6fd46af9c150a759604c7b9580d4a41810b6ba0 Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Thu, 31 Oct 2024 22:04:55 +0900 Subject: [PATCH 05/21] =?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=EC=95=88=EB=82=B4=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/App.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 065b81fad..79314dfbb 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ ## 출력 -- [ ] 발행한 로또 수량을 출력한다. +- [x] 발행한 로또 수량을 출력한다. - [ ] 오름차순 정렬된 로또 번호들을 로또 수량만큼 출력한다. - [ ] 계산되어 반환된 당첨내역을 출력한다. - [ ] 계산되어 반환된 수익률을 출력한다. diff --git a/src/App.js b/src/App.js index 3455a018f..29ea9e516 100644 --- a/src/App.js +++ b/src/App.js @@ -27,6 +27,8 @@ class App { return a - b; }); } + + MissionUtils.Console.print(`\n${lottoCnt}개를 구매했습니다.`); } } From 4cecb5099beb163f7ce1d77bc433582af8680922 Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Thu, 31 Oct 2024 22:07:00 +0900 Subject: [PATCH 06/21] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=EB=93=A4=EC=9D=84=20=EB=A1=9C=EB=98=90=20=EC=88=98?= =?UTF-8?q?=EB=9F=89=EB=A7=8C=ED=81=BC=20=EC=B6=9C=EB=A0=A5=ED=95=98?= =?UTF-8?q?=EB=8A=94=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 --- README.md | 2 +- src/App.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 79314dfbb..2c9e2a172 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ ## 출력 - [x] 발행한 로또 수량을 출력한다. -- [ ] 오름차순 정렬된 로또 번호들을 로또 수량만큼 출력한다. +- [x] 오름차순 정렬된 로또 번호들을 로또 수량만큼 출력한다. - [ ] 계산되어 반환된 당첨내역을 출력한다. - [ ] 계산되어 반환된 수익률을 출력한다. diff --git a/src/App.js b/src/App.js index 29ea9e516..ce1ebe262 100644 --- a/src/App.js +++ b/src/App.js @@ -29,6 +29,10 @@ class App { } MissionUtils.Console.print(`\n${lottoCnt}개를 구매했습니다.`); + + lottoNumbers.forEach((eachLotto) => { + MissionUtils.Console.print(`[${eachLotto.join(", ")}]`); + }); } } From 468d759e9a17d23832e16a1fff3cc9e2d9fc72a3 Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Thu, 31 Oct 2024 22:18:01 +0900 Subject: [PATCH 07/21] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=EA=B0=80=20?= =?UTF-8?q?=EA=B3=A0=EB=A5=B8=206=EA=B0=9C=EC=9D=98=20=EB=8B=B9=EC=B2=A8?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EC=9E=85=EB=A0=A5=EB=B0=9B=EB=8A=94=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 --- README.md | 2 +- src/App.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2c9e2a172..660abc60d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ - [ ] 잘못된 값을 입력할 경우 "[ERROR]"로 시작하는 메시지와 함께 `Error`를 발생시킨다. 잘못된 값은 아래에 해당한다. - [x] 1,000원으로 나누어 떨어지지 않는 경우 = 1,000원 미만인 경우 - [x] 에러 발생 후, 해당 지점부터 다시 입력받는다. -- [ ] 로또발행 내역이 출력된 후, 쉼표(,)를 기준으로 6개의 당첨 번호를 입력받는다. +- [x] 로또발행 내역이 출력된 후, 쉼표(,)를 기준으로 6개의 당첨 번호를 입력받는다. - [ ] 예외처리 `Error` 예외의 경우는 밑에 해당한다. - [ ] 1~45 사이의 숫자가 아닌 경우 - [ ] 당첨번호 입력받은 후, 보너스 번호를 입력받는다. diff --git a/src/App.js b/src/App.js index ce1ebe262..26e407d4c 100644 --- a/src/App.js +++ b/src/App.js @@ -33,6 +33,11 @@ class App { lottoNumbers.forEach((eachLotto) => { MissionUtils.Console.print(`[${eachLotto.join(", ")}]`); }); + + let userPickedNumbers = []; + userPickedNumbers = await MissionUtils.Console.readLineAsync( + "\n당첨 번호를 입력해 주세요.\n" + ); } } From 4108f5c900dfb0c4a1273217fa9a1a811d65b549 Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Fri, 1 Nov 2024 13:57:05 +0900 Subject: [PATCH 08/21] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=EA=B5=AC?= =?UTF-8?q?=EC=9E=85=EA=B8=88=EC=95=A1=20=EC=9E=85=EB=A0=A5=EA=B0=92?= =?UTF-8?q?=EC=9D=B4=20=EC=88=AB=EC=9E=90=EA=B0=80=20=EC=95=84=EB=8B=8C=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/App.js | 36 ++++++++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 660abc60d..89e0a7559 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ - [x] 1,000원 단위로 로또 구입 금액을 입력받는다. - [ ] 잘못된 값을 입력할 경우 "[ERROR]"로 시작하는 메시지와 함께 `Error`를 발생시킨다. 잘못된 값은 아래에 해당한다. - [x] 1,000원으로 나누어 떨어지지 않는 경우 = 1,000원 미만인 경우 + - [x] 입력값이 숫자가 아닌 경우 - [x] 에러 발생 후, 해당 지점부터 다시 입력받는다. - [x] 로또발행 내역이 출력된 후, 쉼표(,)를 기준으로 6개의 당첨 번호를 입력받는다. - [ ] 예외처리 `Error` 예외의 경우는 밑에 해당한다. diff --git a/src/App.js b/src/App.js index 26e407d4c..2cf8086b0 100644 --- a/src/App.js +++ b/src/App.js @@ -1,8 +1,15 @@ import { MissionUtils } from "@woowacourse/mission-utils"; import Lotto from "./Lotto.js"; +const LOTTO_COST_MIN = 1000; +const LOTTO_NUMBER_MIN = 1; +const LOTTO_NUMBER_MAX = 45; +const LOTTO_NUMBER_COUNT = 6; const GUIDE_MESSAGE_INPUT_COST = "구입금액을 입력해 주세요.\n"; +const GUIDE_MESSAGE_INPUT_USER_PICKED_NUMBERS = + "\n당첨 번호를 입력해 주세요.\n"; const ERROR_MESSAGE_INVALID_COST = "[ERROR] 입력하신 금액이 1,000원 단위가 아닙니다. 다시"; +const ERROR_MESSAGE_NOT_NUMBER = "[ERROR] 입력값이 숫자가 아닙니다. 다시"; class App { async run() { @@ -10,19 +17,28 @@ class App { let isValid = false; while (!isValid) { - lottoCost = Number( - await MissionUtils.Console.readLineAsync(GUIDE_MESSAGE_INPUT_COST) - ); - if (lottoCost % 1000 !== 0) { - throw new Error(ERROR_MESSAGE_INVALID_COST); + try { + lottoCost = Number(await this.getLottoCost()); + if (isNaN(lottoCost)) { + throw new Error(ERROR_MESSAGE_NOT_NUMBER); + } else if (lottoCost % LOTTO_COST_MIN !== 0) { + throw new Error(ERROR_MESSAGE_INVALID_COST); + } + isValid = true; + } catch (error) { + MissionUtils.Console.print(error.message); } - isValid = true; } + isValid = false; const lottoCnt = lottoCost / 1000; let lottoNumbers = []; for (let i = 0; i < lottoCnt; i++) { - lottoNumbers[i] = MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6); + lottoNumbers[i] = MissionUtils.Random.pickUniqueNumbersInRange( + LOTTO_NUMBER_MIN, + LOTTO_NUMBER_MAX, + LOTTO_NUMBER_COUNT + ); lottoNumbers[i].sort((a, b) => { return a - b; }); @@ -35,9 +51,9 @@ class App { }); let userPickedNumbers = []; - userPickedNumbers = await MissionUtils.Console.readLineAsync( - "\n당첨 번호를 입력해 주세요.\n" - ); + } + getLottoCost() { + return MissionUtils.Console.readLineAsync(GUIDE_MESSAGE_INPUT_COST); } } From ad3611ed3ff57d28214d31484ed50a36df1c5d77 Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:03:20 +0900 Subject: [PATCH 09/21] =?UTF-8?q?refactor:=20=EB=8B=B9=EC=B2=A8=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=9E=85=EB=A0=A5=EB=B0=9B=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=EC=9D=84=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=A1=9C=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/App.js b/src/App.js index 2cf8086b0..a735ceea2 100644 --- a/src/App.js +++ b/src/App.js @@ -51,10 +51,16 @@ class App { }); let userPickedNumbers = []; + userPickedNumbers = await this.getUserPickedNumbers(); } getLottoCost() { return MissionUtils.Console.readLineAsync(GUIDE_MESSAGE_INPUT_COST); } + getUserPickedNumbers() { + return MissionUtils.Console.readLineAsync( + GUIDE_MESSAGE_INPUT_USER_PICKED_NUMBERS + ); + } } export default App; From 0e362c6f551edda2ca53cd2f50df31449775b2fc Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:09:25 +0900 Subject: [PATCH 10/21] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=EB=B2=88?= =?UTF-8?q?=ED=98=B8=EB=A5=BC=20=EA=B5=AC=EB=B6=84=EC=9E=90(,)=20=EA=B8=B0?= =?UTF-8?q?=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EB=B6=84=EB=A6=AC=ED=95=B4=20?= =?UTF-8?q?=EB=B0=B0=EC=97=B4=EC=97=90=20=EC=A0=80=EC=9E=A5=ED=95=98?= =?UTF-8?q?=EB=8A=94=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 --- README.md | 2 ++ src/App.js | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 89e0a7559..fed243146 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ - [x] 입력받은 로또 구입 금액에 해당하는 만큼 로또를 발행한다. (로또 1장은 1,000원이다) - [x] 로또 1장 당 1~45 사이의 중복되지 않는 6개의 숫자를 뽑는다. - [x] 숫자들을 오름차순 정렬한다. +- [x] 입력받은 당첨 번호 문자열을 구분자(,)를 기준으로 배열에 저장한다. +- [ ] 구분자로 분리된 당첨 번호 문자열 배열을 숫자형으로 변환한다. - [ ] 사용자가 구매한 로또 번호와, 당첨 번호를 비교해 당첨내역을 계산해 반환한다. - [ ] 1등: 6개 번호 일치 / 2,000,000,000원 - [ ] 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원 diff --git a/src/App.js b/src/App.js index a735ceea2..1a8bfbbc7 100644 --- a/src/App.js +++ b/src/App.js @@ -51,7 +51,9 @@ class App { }); let userPickedNumbers = []; - userPickedNumbers = await this.getUserPickedNumbers(); + userPickedNumbers = this.splitUserPickedNumbers( + await this.getUserPickedNumbers() + ); } getLottoCost() { return MissionUtils.Console.readLineAsync(GUIDE_MESSAGE_INPUT_COST); @@ -61,6 +63,9 @@ class App { GUIDE_MESSAGE_INPUT_USER_PICKED_NUMBERS ); } + splitUserPickedNumbers(userPickedStr) { + return userPickedStr.split(","); + } } export default App; From d6bd8bc574b0124bed41089a8d9a926c9fb710eb Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:10:13 +0900 Subject: [PATCH 11/21] =?UTF-8?q?feat:=20=EB=B6=84=EB=A6=AC=EB=90=9C=20?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=EC=97=B4=20=EB=8B=B9=EC=B2=A8=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EB=B0=B0=EC=97=B4=EC=9D=84=20=EC=88=AB=EC=9E=90?= =?UTF-8?q?=ED=98=95=EC=9C=BC=EB=A1=9C=20=EB=B3=80=ED=99=98=ED=95=98?= =?UTF-8?q?=EB=8A=94=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 --- README.md | 2 +- src/App.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fed243146..e427940a7 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ - [x] 로또 1장 당 1~45 사이의 중복되지 않는 6개의 숫자를 뽑는다. - [x] 숫자들을 오름차순 정렬한다. - [x] 입력받은 당첨 번호 문자열을 구분자(,)를 기준으로 배열에 저장한다. -- [ ] 구분자로 분리된 당첨 번호 문자열 배열을 숫자형으로 변환한다. +- [x] 구분자로 분리된 당첨 번호 문자열 배열을 숫자형으로 변환한다. - [ ] 사용자가 구매한 로또 번호와, 당첨 번호를 비교해 당첨내역을 계산해 반환한다. - [ ] 1등: 6개 번호 일치 / 2,000,000,000원 - [ ] 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원 diff --git a/src/App.js b/src/App.js index 1a8bfbbc7..324cc50b2 100644 --- a/src/App.js +++ b/src/App.js @@ -53,7 +53,7 @@ class App { let userPickedNumbers = []; userPickedNumbers = this.splitUserPickedNumbers( await this.getUserPickedNumbers() - ); + ).map(Number); } getLottoCost() { return MissionUtils.Console.readLineAsync(GUIDE_MESSAGE_INPUT_COST); From f252127d684a2cb787899823384b539e8d039ce7 Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Sun, 3 Nov 2024 20:13:28 +0900 Subject: [PATCH 12/21] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EC=97=90=20=EB=B2=88=ED=98=B8=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Lotto.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Lotto.js b/src/Lotto.js index cb0b1527e..7820ad999 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -1,3 +1,8 @@ +import { MissionUtils } from "@woowacourse/mission-utils"; +const LOTTO_NUMBER_MIN = 1; +const LOTTO_NUMBER_MAX = 45; +const LOTTO_NUMBER_COUNT = 6; + class Lotto { #numbers; @@ -12,7 +17,17 @@ class Lotto { } } - // TODO: 추가 기능 구현 + getNumbers() { + return this.#numbers; + } + + static generateRandomNumbers() { + return MissionUtils.Random.pickUniqueNumbersInRange( + LOTTO_NUMBER_MIN, + LOTTO_NUMBER_MAX, + LOTTO_NUMBER_COUNT + ).sort((a, b) => a - b); + } } export default Lotto; From a1bc27871c174e12be468c25b9f2354dbe3c9162 Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Sun, 3 Nov 2024 20:20:04 +0900 Subject: [PATCH 13/21] =?UTF-8?q?refactor:=20=EB=A1=9C=EB=98=90=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EC=9D=98=20=EB=B2=88=ED=98=B8=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=A9=94=EC=84=9C=EB=93=9C=20=ED=98=B8?= =?UTF-8?q?=EC=B6=9C=EB=A1=9C=20App.js=20=EC=BD=94=EB=93=9C=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/App.js b/src/App.js index 324cc50b2..4d07b12c5 100644 --- a/src/App.js +++ b/src/App.js @@ -1,9 +1,6 @@ import { MissionUtils } from "@woowacourse/mission-utils"; import Lotto from "./Lotto.js"; const LOTTO_COST_MIN = 1000; -const LOTTO_NUMBER_MIN = 1; -const LOTTO_NUMBER_MAX = 45; -const LOTTO_NUMBER_COUNT = 6; const GUIDE_MESSAGE_INPUT_COST = "구입금액을 입력해 주세요.\n"; const GUIDE_MESSAGE_INPUT_USER_PICKED_NUMBERS = "\n당첨 번호를 입력해 주세요.\n"; @@ -31,17 +28,12 @@ class App { } isValid = false; - const lottoCnt = lottoCost / 1000; + const lottoCnt = lottoCost / LOTTO_COST_MIN; let lottoNumbers = []; for (let i = 0; i < lottoCnt; i++) { - lottoNumbers[i] = MissionUtils.Random.pickUniqueNumbersInRange( - LOTTO_NUMBER_MIN, - LOTTO_NUMBER_MAX, - LOTTO_NUMBER_COUNT - ); - lottoNumbers[i].sort((a, b) => { - return a - b; - }); + const randomNumbers = Lotto.generateRandomNumbers(); + + lottoNumbers.push(new Lotto(randomNumbers)); } MissionUtils.Console.print(`\n${lottoCnt}개를 구매했습니다.`); @@ -55,14 +47,17 @@ class App { await this.getUserPickedNumbers() ).map(Number); } + getLottoCost() { return MissionUtils.Console.readLineAsync(GUIDE_MESSAGE_INPUT_COST); } + getUserPickedNumbers() { return MissionUtils.Console.readLineAsync( GUIDE_MESSAGE_INPUT_USER_PICKED_NUMBERS ); } + splitUserPickedNumbers(userPickedStr) { return userPickedStr.split(","); } From 3fb0a0df4ed2d2e2771f9361f89b2cef12e35129 Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Sun, 3 Nov 2024 22:07:42 +0900 Subject: [PATCH 14/21] =?UTF-8?q?feat:=20=EB=B3=B4=EB=84=88=EC=8A=A4?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EC=9E=85=EB=A0=A5=EB=B0=9B=EB=8A=94=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 --- README.md | 2 +- src/App.js | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e427940a7..036e6fa5a 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ - [x] 로또발행 내역이 출력된 후, 쉼표(,)를 기준으로 6개의 당첨 번호를 입력받는다. - [ ] 예외처리 `Error` 예외의 경우는 밑에 해당한다. - [ ] 1~45 사이의 숫자가 아닌 경우 -- [ ] 당첨번호 입력받은 후, 보너스 번호를 입력받는다. +- [x] 당첨번호 입력받은 후, 보너스 번호를 입력받는다. - [ ] 예외처리 `Error` - [ ] 1~45 사이의 숫자가 아닌 경우 diff --git a/src/App.js b/src/App.js index 4d07b12c5..e7fab4084 100644 --- a/src/App.js +++ b/src/App.js @@ -4,6 +4,8 @@ const LOTTO_COST_MIN = 1000; const GUIDE_MESSAGE_INPUT_COST = "구입금액을 입력해 주세요.\n"; const GUIDE_MESSAGE_INPUT_USER_PICKED_NUMBERS = "\n당첨 번호를 입력해 주세요.\n"; +const GUIDE_MESSAGE_INPUT_USER_PICKED_BONUS_NUMBER = + "\n보너스 번호를 입력해 주세요.\n"; const ERROR_MESSAGE_INVALID_COST = "[ERROR] 입력하신 금액이 1,000원 단위가 아닙니다. 다시"; const ERROR_MESSAGE_NOT_NUMBER = "[ERROR] 입력값이 숫자가 아닙니다. 다시"; @@ -46,6 +48,8 @@ class App { userPickedNumbers = this.splitUserPickedNumbers( await this.getUserPickedNumbers() ).map(Number); + + let userPickedBonusNum = await this.getUserPickedBonusNumber(); } getLottoCost() { @@ -61,6 +65,12 @@ class App { splitUserPickedNumbers(userPickedStr) { return userPickedStr.split(","); } + + getUserPickedBonusNumber() { + return MissionUtils.Console.readLineAsync( + GUIDE_MESSAGE_INPUT_USER_PICKED_BONUS_NUMBER + ); + } } export default App; From 3c747ce8b21ff35ba289424f00bb1d1c5baedfbb Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Sun, 3 Nov 2024 22:16:14 +0900 Subject: [PATCH 15/21] =?UTF-8?q?Feat:=20=EB=A1=9C=EB=98=90=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EC=97=90=20=EC=A0=90=EC=88=98=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=ED=95=B4=20=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 13 ++++++++----- src/App.js | 9 ++++++++- src/Lotto.js | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 036e6fa5a..a57381970 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,12 @@ - [x] 입력받은 당첨 번호 문자열을 구분자(,)를 기준으로 배열에 저장한다. - [x] 구분자로 분리된 당첨 번호 문자열 배열을 숫자형으로 변환한다. - [ ] 사용자가 구매한 로또 번호와, 당첨 번호를 비교해 당첨내역을 계산해 반환한다. - - [ ] 1등: 6개 번호 일치 / 2,000,000,000원 - - [ ] 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원 - - [ ] 3등: 5개 번호 일치 / 1,500,000원 - - [ ] 4등: 4개 번호 일치 / 50,000원 - - [ ] 5등: 3개 번호 일치 / 5,000원 + + - [x] 점수를 계산한다. + + - [x] 1등: 6개 번호 일치(6점) + - [x] 2등: 5개 번호(5점) + 보너스 번호 일치(true) + - [x] 3등: 5개 번호 일치(5점) + - [x] 4등: 4개 번호 일치(4점) + - [x] 5등: 3개 번호 일치(3점) - [ ] 소수점 둘째 자리에서 반올림 한 수익률을 계산해 반환한다. diff --git a/src/App.js b/src/App.js index e7fab4084..8eb493a4e 100644 --- a/src/App.js +++ b/src/App.js @@ -41,7 +41,7 @@ class App { MissionUtils.Console.print(`\n${lottoCnt}개를 구매했습니다.`); lottoNumbers.forEach((eachLotto) => { - MissionUtils.Console.print(`[${eachLotto.join(", ")}]`); + MissionUtils.Console.print(`[${eachLotto.getNumbers().join(", ")}]`); }); let userPickedNumbers = []; @@ -50,6 +50,13 @@ class App { ).map(Number); let userPickedBonusNum = await this.getUserPickedBonusNumber(); + + let score = Lotto.getScore( + userPickedNumbers, + lottoNumbers, + userPickedBonusNum + ); + console.log(score); } getLottoCost() { diff --git a/src/Lotto.js b/src/Lotto.js index 7820ad999..6f3d82314 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -28,6 +28,24 @@ class Lotto { LOTTO_NUMBER_COUNT ).sort((a, b) => a - b); } + + static getScore(userPickedNumbers, lottoNumbers, userPickedBonusNum) { + let score = 0; + let bonus = false; + + userPickedNumbers.forEach((userNumber) => { + for (let i = 0; i < lottoNumbers.length; i++) { + lottoNumbers[i].getNumbers().forEach((winNum) => { + if (userNumber === winNum) { + score++; + } else if (userPickedBonusNum === winNum) { + bonus = true; + } + }); + } + }); + return [score, bonus]; + } } export default Lotto; From c845797b37f8828df687a81973d6380800e45801 Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Sun, 3 Nov 2024 22:47:48 +0900 Subject: [PATCH 16/21] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EC=97=90=20=EB=8B=B9=EC=B2=A8=EA=B8=88?= =?UTF-8?q?=EC=95=A1=20=EA=B3=84=EC=82=B0=ED=95=B4=20=EB=93=B1=EC=88=98?= =?UTF-8?q?=EC=99=80=20=ED=95=A8=EA=BB=98=20=EB=B0=98=ED=99=98=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +++++++- src/App.js | 3 ++- src/Lotto.js | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a57381970..43c600a9e 100644 --- a/README.md +++ b/README.md @@ -39,4 +39,10 @@ - [x] 3등: 5개 번호 일치(5점) - [x] 4등: 4개 번호 일치(4점) - [x] 5등: 3개 번호 일치(3점) -- [ ] 소수점 둘째 자리에서 반올림 한 수익률을 계산해 반환한다. + + - [x] 당첨금액을 계산해 등수와 함께 반환한다. + - [x] 1등 : 2,000,000,000원 + - [x] 2등 : 30,000,000원 + - [x] 3등 : 1,500,000원 + - [x] 4등 : 50,000원 + - [x] 5등 : 5,000원 diff --git a/src/App.js b/src/App.js index 8eb493a4e..4d32755cb 100644 --- a/src/App.js +++ b/src/App.js @@ -56,7 +56,8 @@ class App { lottoNumbers, userPickedBonusNum ); - console.log(score); + + const result = Lotto.getResult(score); } getLottoCost() { diff --git a/src/Lotto.js b/src/Lotto.js index 6f3d82314..b1cb22996 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -2,6 +2,10 @@ import { MissionUtils } from "@woowacourse/mission-utils"; const LOTTO_NUMBER_MIN = 1; const LOTTO_NUMBER_MAX = 45; const LOTTO_NUMBER_COUNT = 6; +const SECOND_PRIZE = ["2등", 30000000]; +const FOURTH_PRIZE = ["4등", 50000]; +const FIFTH_PRIZE = ["5등", 5000]; +const NO_PRIZE = ["꽝", 0]; class Lotto { #numbers; @@ -46,6 +50,17 @@ class Lotto { }); return [score, bonus]; } + + static getResult(scoreObj) { + const score = scoreObj[0]; + const bonus = scoreObj[1]; + if (score === 6) return FIRST_PRIZE; + else if (score === 5 && bonus) return SECOND_PRIZE; + else if (score === 5) return THIRD_PRIZE; + else if (score === 4) return FOURTH_PRIZE; + else if (score === 3) return FIFTH_PRIZE; + else return NO_PRIZE; + } } export default Lotto; From a3f56a001aa2f540877e55fc92128425b1a5a0f1 Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:40:56 +0900 Subject: [PATCH 17/21] =?UTF-8?q?refactor:=20=EC=9E=98=EB=AA=BB=EB=90=9C?= =?UTF-8?q?=20=EC=9E=90=EB=A3=8C=ED=98=95=EC=9D=B4=EC=97=88=EB=8D=98=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=98=AC=EB=B0=94=EB=A5=B4=EA=B2=8C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index 4d32755cb..a5d09aa5d 100644 --- a/src/App.js +++ b/src/App.js @@ -49,7 +49,7 @@ class App { await this.getUserPickedNumbers() ).map(Number); - let userPickedBonusNum = await this.getUserPickedBonusNumber(); + let userPickedBonusNum = Number(await this.getUserPickedBonusNumber()); let score = Lotto.getScore( userPickedNumbers, From 3f6dfe377be801faa964b2c306bdd97d34f842b9 Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:47:41 +0900 Subject: [PATCH 18/21] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EC=9D=98=20=EB=8B=B9=EC=B2=A8=EA=B8=88?= =?UTF-8?q?=EC=95=A1=20=EA=B3=84=EC=82=B0=ED=95=B4=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getResult() -> getCounts() --- src/App.js | 2 +- src/Lotto.js | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/App.js b/src/App.js index a5d09aa5d..26ab8d029 100644 --- a/src/App.js +++ b/src/App.js @@ -57,7 +57,7 @@ class App { userPickedBonusNum ); - const result = Lotto.getResult(score); + let counts = Lotto.getCounts(score); } getLottoCost() { diff --git a/src/Lotto.js b/src/Lotto.js index b1cb22996..b70f9c9c2 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -2,10 +2,11 @@ import { MissionUtils } from "@woowacourse/mission-utils"; const LOTTO_NUMBER_MIN = 1; const LOTTO_NUMBER_MAX = 45; const LOTTO_NUMBER_COUNT = 6; +const FIRST_PRIZE = ["1등", 2000000000]; const SECOND_PRIZE = ["2등", 30000000]; +const THIRD_PRIZE = ["3등", 1500000]; const FOURTH_PRIZE = ["4등", 50000]; const FIFTH_PRIZE = ["5등", 5000]; -const NO_PRIZE = ["꽝", 0]; class Lotto { #numbers; @@ -19,6 +20,11 @@ class Lotto { if (numbers.length !== 6) { throw new Error("[ERROR] 로또 번호는 6개여야 합니다."); } + + const numberSet = new Set(numbers); + if (numberSet.size !== 6) { + throw new Error("[ERROR] 로또 번호에는 중복된 숫자가 없어야 합니다."); + } } getNumbers() { From e61ec7c007516c3156d586af7cb4d6f26b2d2cef Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:50:57 +0900 Subject: [PATCH 19/21] =?UTF-8?q?refactor:=20=EB=A1=9C=EB=98=90=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EC=9D=98=20=EC=A0=90=EC=88=98=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=ED=95=B4=20=EA=B0=9D=EC=B2=B4=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B0=80=EB=8F=85=EC=84=B1=20=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - return되는 자료형을 배열에서, 키 값으로 한눈에 알아보기 쉽게 객체로 변경 - 이전에는 로또 몇 장을 사던, 첫번째 장만 점수계산하는 로직이어서 문제가 많았음. 제대로 동작하게 구현 완료 --- src/Lotto.js | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Lotto.js b/src/Lotto.js index b70f9c9c2..c573df5ee 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -40,21 +40,31 @@ class Lotto { } static getScore(userPickedNumbers, lottoNumbers, userPickedBonusNum) { - let score = 0; - let bonus = false; + let scores = []; + lottoNumbers.forEach((lottoSet) => { + const winNum = lottoSet.getNumbers(); // 로또세트 순서대로 하나 가져오기 + let score = 0; // 각 로또세트 별 점수 세고 계속 초기화되는 i 이터레이터 + let isBonusMatched = 0; - userPickedNumbers.forEach((userNumber) => { - for (let i = 0; i < lottoNumbers.length; i++) { - lottoNumbers[i].getNumbers().forEach((winNum) => { - if (userNumber === winNum) { - score++; - } else if (userPickedBonusNum === winNum) { - bonus = true; - } - }); + // 사용자 번호와 로또 번호 비교 + userPickedNumbers.forEach((userNumber) => { + if (winNum.includes(userNumber)) { + score++; + } + }); + + // 보너스 번호 확인 + if (winNum.includes(userPickedBonusNum)) { + isBonusMatched = 1; } + + // 점수 객체를 scores 배열에 추가 + scores.push({ score, isBonusMatched }); }); return [score, bonus]; + + return scores; // {점수, 보너스여부(1)} 객체가 한 칸씩 들어가있는 배열 반환 + } } static getResult(scoreObj) { From 1fbb247e3ea9babd8643cd9e904c1d655eb4c228 Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Mon, 4 Nov 2024 23:06:07 +0900 Subject: [PATCH 20/21] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=EA=B3=84=EC=82=B0=ED=95=98=EA=B3=A0=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=ED=95=98=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +++--- src/App.js | 10 +++++++++ src/Lotto.js | 63 +++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 43c600a9e..2bc618b75 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,8 @@ - [x] 발행한 로또 수량을 출력한다. - [x] 오름차순 정렬된 로또 번호들을 로또 수량만큼 출력한다. -- [ ] 계산되어 반환된 당첨내역을 출력한다. -- [ ] 계산되어 반환된 수익률을 출력한다. +- [x] 계산되어 반환된 당첨내역을 출력한다. +- [x] 계산되어 반환된 수익률을 출력한다. ## 핵심 기능 @@ -40,9 +40,10 @@ - [x] 4등: 4개 번호 일치(4점) - [x] 5등: 3개 번호 일치(3점) - - [x] 당첨금액을 계산해 등수와 함께 반환한다. + - [x] 당첨금액을 계산해 반환한다. - [x] 1등 : 2,000,000,000원 - [x] 2등 : 30,000,000원 - [x] 3등 : 1,500,000원 - [x] 4등 : 50,000원 - [x] 5등 : 5,000원 + - [x] 소수점 둘째 자리에서 반올림 한 수익률을 계산해 반환한다. diff --git a/src/App.js b/src/App.js index 26ab8d029..3428c6029 100644 --- a/src/App.js +++ b/src/App.js @@ -58,6 +58,16 @@ class App { ); let counts = Lotto.getCounts(score); + + // 당첨 내역 반환된거 출력 + let resultMessage = Lotto.getResultMessage(...counts); + MissionUtils.Console.print(`${resultMessage}`); + + let totalPrizeMoney = Lotto.calculateTotalPrizeMoney(counts); + + const profitRatio = Lotto.getProfitRatio(lottoCost, totalPrizeMoney); + // 수익률 반환된거 출력 + MissionUtils.Console.print(`총 수익률은 ${profitRatio}%입니다.`); } getLottoCost() { diff --git a/src/Lotto.js b/src/Lotto.js index c573df5ee..b54fd832e 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -61,21 +61,64 @@ class Lotto { // 점수 객체를 scores 배열에 추가 scores.push({ score, isBonusMatched }); }); - return [score, bonus]; return scores; // {점수, 보너스여부(1)} 객체가 한 칸씩 들어가있는 배열 반환 } + + static getCounts(scoreObj) { + let count3 = 0, + count4 = 0, + count5 = 0, + countBonus = 0, + count6 = 0; + + scoreObj.forEach(({ score, isBonusMatched }) => { + if (score === 6) count6++; + else if (score === 5 && isBonusMatched) countBonus++; + else if (score === 5) count5++; + else if (score === 4) count4++; + else if (score === 3) count3++; + }); + + return [count3, count4, count5, countBonus, count6]; + } + + static getResultMessage(count3, count4, count5, countB, count6) { + const RESULT_MESSAGE = `당첨 통계\n---\n + 3개 일치 (5,000원) - ${count3}개\n + 4개 일치 (50,000원) - ${count4}개\n + 5개 일치 (1,500,000원) - ${count5}개\n + 5개 일치, 보너스 볼 일치 (30,000,000원) - ${countB}개\n + 6개 일치 (2,000,000,000원) - ${count6}개\n`; + return RESULT_MESSAGE; } - static getResult(scoreObj) { - const score = scoreObj[0]; - const bonus = scoreObj[1]; - if (score === 6) return FIRST_PRIZE; - else if (score === 5 && bonus) return SECOND_PRIZE; - else if (score === 5) return THIRD_PRIZE; - else if (score === 4) return FOURTH_PRIZE; - else if (score === 3) return FIFTH_PRIZE; - else return NO_PRIZE; + static calculateTotalPrizeMoney(countArr) { + let totalPrizeMoney = 0; + for (let i = 0; i < countArr.length; i++) { + if (i === 0) { + totalPrizeMoney += FIFTH_PRIZE[1] * countArr[i]; + } else if (i === 1) { + totalPrizeMoney += FOURTH_PRIZE[1] * countArr[i]; + } else if (i === 2) { + totalPrizeMoney += THIRD_PRIZE[1] * countArr[i]; + } else if (i === 3) { + totalPrizeMoney += SECOND_PRIZE[1] * countArr[i]; + } else if (i === 4) { + totalPrizeMoney += FIRST_PRIZE[1] * countArr[i]; + } else totalPrizeMoney = 0; + } + + return totalPrizeMoney; + } + + static getProfitRatio(lottoCost, prize) { + let ratio = prize / lottoCost; + ratio = Math.trunc(ratio * 10000); + ratio = Math.round(ratio); + ratio = ratio / 100; + + return ratio; } } From 0ed47bc0fe688bf039933068d627d276e1354670 Mon Sep 17 00:00:00 2001 From: Doi Kim <154426332+d0ikim@users.noreply.github.com> Date: Mon, 4 Nov 2024 23:52:14 +0900 Subject: [PATCH 21/21] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EB=8B=B9?= =?UTF-8?q?=EC=B2=A8=EB=B2=88=ED=98=B8=20=EB=B0=8F=20=EB=B3=B4=EB=84=88?= =?UTF-8?q?=EC=8A=A4=EB=B2=88=ED=98=B8=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +++--- __tests__/LottoTest.js | 19 ++++++---- src/App.js | 78 ++++++++++++++++++++++++++++++++++-------- src/Lotto.js | 37 +++++++++++--------- 4 files changed, 105 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 2bc618b75..e9e40af12 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,14 @@ - [x] 입력값이 숫자가 아닌 경우 - [x] 에러 발생 후, 해당 지점부터 다시 입력받는다. - [x] 로또발행 내역이 출력된 후, 쉼표(,)를 기준으로 6개의 당첨 번호를 입력받는다. - - [ ] 예외처리 `Error` 예외의 경우는 밑에 해당한다. - - [ ] 1~45 사이의 숫자가 아닌 경우 + - [x] 예외처리 `Error` 예외의 경우는 밑에 해당한다. + - [x] 1~45 사이의 숫자가 아닌 경우 + - [x] 중복된 번호가 있는 경우 + - [x] 6개의 번호를 입력받지 않은 경우 - [x] 당첨번호 입력받은 후, 보너스 번호를 입력받는다. - - [ ] 예외처리 `Error` - - [ ] 1~45 사이의 숫자가 아닌 경우 + - [x] 예외처리 `Error` + - [x] 1~45 사이의 숫자가 아닌 경우 + - [x] 당첨번호 안에 이미 보너스 번호가 있는 경우 ## 출력 diff --git a/__tests__/LottoTest.js b/__tests__/LottoTest.js index 409aaf69b..076df9655 100644 --- a/__tests__/LottoTest.js +++ b/__tests__/LottoTest.js @@ -7,12 +7,19 @@ describe("로또 클래스 테스트", () => { }).toThrow("[ERROR]"); }); - // TODO: 테스트가 통과하도록 프로덕션 코드 구현 - test("로또 번호에 중복된 숫자가 있으면 예외가 발생한다.", () => { - expect(() => { - new Lotto([1, 2, 3, 4, 5, 5]); - }).toThrow("[ERROR]"); + test("로또 번호에 중복된 숫자가 있다면 true를 리턴한다.", () => { + expect(Lotto.hasDuplicatedLottoNumber([1, 2, 3, 4, 5, 5])).toBe(true); + }); + + test("로또 번호에 중복된 숫자가 없다면 false를 리턴한다.", () => { + expect(Lotto.hasDuplicatedLottoNumber([1, 2, 3, 4, 5, 6])).toBe(false); }); - // TODO: 추가 기능 구현에 따른 테스트 코드 작성 + test("번호에 1과 45 사이의 값이 아니면 true를 반환한다.", () => { + expect(Lotto.isValidLottoNumberRange([46])).toBe(false); + }); + + test("번호에 1과 45 사이의 값이 있으면 false를 반환한다.", () => { + expect(Lotto.isValidLottoNumberRange([4])).toBe(true); + }); }); diff --git a/src/App.js b/src/App.js index 3428c6029..2b4399105 100644 --- a/src/App.js +++ b/src/App.js @@ -1,26 +1,33 @@ import { MissionUtils } from "@woowacourse/mission-utils"; import Lotto from "./Lotto.js"; + const LOTTO_COST_MIN = 1000; -const GUIDE_MESSAGE_INPUT_COST = "구입금액을 입력해 주세요.\n"; +const GUIDE_MESSAGE_INPUT_COST = "구입금액을 입력해 주세요. (ex: 2000)\n"; const GUIDE_MESSAGE_INPUT_USER_PICKED_NUMBERS = - "\n당첨 번호를 입력해 주세요.\n"; + "\n당첨 번호를 입력해 주세요. (ex: 1,2,3,4,5,6)\n"; const GUIDE_MESSAGE_INPUT_USER_PICKED_BONUS_NUMBER = - "\n보너스 번호를 입력해 주세요.\n"; + "\n보너스 번호를 입력해 주세요. (ex: 7)\n"; const ERROR_MESSAGE_INVALID_COST = "[ERROR] 입력하신 금액이 1,000원 단위가 아닙니다. 다시"; const ERROR_MESSAGE_NOT_NUMBER = "[ERROR] 입력값이 숫자가 아닙니다. 다시"; +const ERROR_MESSAGE_NOT_IN_VALID_RANGE = + "[ERROR] 입력값이 로또 번호 범위에 있지 않습니다. 다시"; +const ERROR_MESSAGE_DUPLICATED_LOTTO_NUMBER = + "[ERROR] 중복된 로또 번호가 있습니다. 다시"; +const ERROR_MESSAGE_NOT_SIX_NUMBERS = + "[ERROR] 6개의 당첨 번호를 입력해야합니다. 다시"; class App { async run() { - let lottoCost; + let lottoBudget; let isValid = false; while (!isValid) { try { - lottoCost = Number(await this.getLottoCost()); - if (isNaN(lottoCost)) { + lottoBudget = Number(await this.getLottoCost()); + if (isNaN(lottoBudget)) { throw new Error(ERROR_MESSAGE_NOT_NUMBER); - } else if (lottoCost % LOTTO_COST_MIN !== 0) { + } else if (lottoBudget % LOTTO_COST_MIN !== 0) { throw new Error(ERROR_MESSAGE_INVALID_COST); } isValid = true; @@ -28,9 +35,8 @@ class App { MissionUtils.Console.print(error.message); } } - isValid = false; - const lottoCnt = lottoCost / LOTTO_COST_MIN; + const lottoCnt = lottoBudget / LOTTO_COST_MIN; let lottoNumbers = []; for (let i = 0; i < lottoCnt; i++) { const randomNumbers = Lotto.generateRandomNumbers(); @@ -45,11 +51,54 @@ class App { }); let userPickedNumbers = []; - userPickedNumbers = this.splitUserPickedNumbers( - await this.getUserPickedNumbers() - ).map(Number); - let userPickedBonusNum = Number(await this.getUserPickedBonusNumber()); + isValid = false; + while (!isValid) { + try { + userPickedNumbers = this.splitUserPickedNumbers( + await this.getUserPickedNumbers() + ).map(Number); + + if (userPickedNumbers.length != 6) { + throw new Error(ERROR_MESSAGE_NOT_SIX_NUMBERS); + } + + userPickedNumbers.forEach((number) => { + if (!Lotto.isValidLottoNumberRange(number)) { + throw new Error(ERROR_MESSAGE_NOT_IN_VALID_RANGE); + } + }); + + if (Lotto.hasDuplicatedLottoNumber(userPickedNumbers)) { + throw new Error(ERROR_MESSAGE_DUPLICATED_LOTTO_NUMBER); + } + + isValid = true; + } catch (error) { + MissionUtils.Console.print(error.message); + } + } + + let userPickedBonusNum; + + isValid = false; + while (!isValid) { + try { + userPickedBonusNum = Number(await this.getUserPickedBonusNumber()); + + if (userPickedNumbers.includes(userPickedBonusNum)) { + throw new Error(ERROR_MESSAGE_DUPLICATED_LOTTO_NUMBER); + } + + if (!Lotto.isValidLottoNumberRange(userPickedBonusNum)) { + throw new Error(ERROR_MESSAGE_NOT_IN_VALID_RANGE); + } + + isValid = true; + } catch (error) { + MissionUtils.Console.print(error.message); + } + } let score = Lotto.getScore( userPickedNumbers, @@ -65,7 +114,7 @@ class App { let totalPrizeMoney = Lotto.calculateTotalPrizeMoney(counts); - const profitRatio = Lotto.getProfitRatio(lottoCost, totalPrizeMoney); + const profitRatio = Lotto.getProfitRatio(lottoBudget, totalPrizeMoney); // 수익률 반환된거 출력 MissionUtils.Console.print(`총 수익률은 ${profitRatio}%입니다.`); } @@ -88,6 +137,7 @@ class App { return MissionUtils.Console.readLineAsync( GUIDE_MESSAGE_INPUT_USER_PICKED_BONUS_NUMBER ); + j; } } diff --git a/src/Lotto.js b/src/Lotto.js index b54fd832e..d4e1968d3 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -2,11 +2,12 @@ import { MissionUtils } from "@woowacourse/mission-utils"; const LOTTO_NUMBER_MIN = 1; const LOTTO_NUMBER_MAX = 45; const LOTTO_NUMBER_COUNT = 6; -const FIRST_PRIZE = ["1등", 2000000000]; -const SECOND_PRIZE = ["2등", 30000000]; -const THIRD_PRIZE = ["3등", 1500000]; -const FOURTH_PRIZE = ["4등", 50000]; -const FIFTH_PRIZE = ["5등", 5000]; + +const FIRST_PRIZE_MONEY = 2000000000; +const SECOND_PRIZE_MONEY = 30000000; +const THIRD_PRIZE_MONEY = 1500000; +const FOURTH_PRIZE_MONEY = 50000; +const FIFTH_PRIZE_MONEY = 5000; class Lotto { #numbers; @@ -20,11 +21,6 @@ class Lotto { if (numbers.length !== 6) { throw new Error("[ERROR] 로또 번호는 6개여야 합니다."); } - - const numberSet = new Set(numbers); - if (numberSet.size !== 6) { - throw new Error("[ERROR] 로또 번호에는 중복된 숫자가 없어야 합니다."); - } } getNumbers() { @@ -97,16 +93,16 @@ class Lotto { let totalPrizeMoney = 0; for (let i = 0; i < countArr.length; i++) { if (i === 0) { - totalPrizeMoney += FIFTH_PRIZE[1] * countArr[i]; + totalPrizeMoney += FIFTH_PRIZE_MONEY * countArr[i]; } else if (i === 1) { - totalPrizeMoney += FOURTH_PRIZE[1] * countArr[i]; + totalPrizeMoney += FOURTH_PRIZE_MONEY * countArr[i]; } else if (i === 2) { - totalPrizeMoney += THIRD_PRIZE[1] * countArr[i]; + totalPrizeMoney += THIRD_PRIZE_MONEY * countArr[i]; } else if (i === 3) { - totalPrizeMoney += SECOND_PRIZE[1] * countArr[i]; + totalPrizeMoney += SECOND_PRIZE_MONEY * countArr[i]; } else if (i === 4) { - totalPrizeMoney += FIRST_PRIZE[1] * countArr[i]; - } else totalPrizeMoney = 0; + totalPrizeMoney += FIRST_PRIZE_MONEY * countArr[i]; + } } return totalPrizeMoney; @@ -120,6 +116,15 @@ class Lotto { return ratio; } + + static isValidLottoNumberRange(number) { + return number >= LOTTO_NUMBER_MIN && number <= LOTTO_NUMBER_MAX; + } + + static hasDuplicatedLottoNumber(numbers) { + const numberSet = new Set(numbers); + return numberSet.size !== numbers.length; + } } export default Lotto;