From 2c4ec527b49509d782035e7647d9c1b43ee0a0f1 Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Fri, 1 Nov 2024 19:10:14 +0900 Subject: [PATCH 01/20] =?UTF-8?q?docs(README.md):=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EB=B0=8F=20=EB=AA=A9=ED=91=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/README.md b/README.md index 15bb106b5..01009ee84 100644 --- a/README.md +++ b/README.md @@ -1 +1,74 @@ # javascript-lotto-precourse +# 로또 발매기 + +이 프로젝트는 우아한테크코스 프리코스 3주차 과제인 **간단한 로또 발매기**입니다. + +### 기능 목록 +- [ ] 중복 숫자 없도록 로또 발행 (6개 숫자) +- [ ] 입력받은 로또 구입 금액만큼 로또 발행 +- [ ] 당첨, 보너스 번호 입력 +- [ ] 기준에 따라 당첨 값 반환 +- [ ] 수익률 반환 +- [ ] Error handling + - 입력 틀리면 그 지점부터 다시 입력 + +#### ERROR CASE +- 로또 구입 금액 입력 + - 입력 X + - 숫자 X + - 천 원 단위 X +- 당첨 번호 문자열 입력 + - 입력 X + - 숫자 X + - 정수 X + - 1 ~ 45 범위 X + - 구분자 쉼표 X + - 공백 포함 +- 보너스 번호 입력 + - 입력 X + - 숫자 X + - 1 ~ 45 범위 X + - 정수 X + + + + + +### 피드백 반영 개인 목표 +- [오류를 찾을 때 출력 함수 대신 디버거를 사용한다.](https://code.visualstudio.com/docs/editor/debugging) + - 디버거를 잘 학습하고 활용해보자. +- 이름을 통해 의도를 드러낸다. + - 숫자 덧붙이기X(aN), 불용어X(Info, data, a, an, the) + - 사용할 상수 이름, 함수 이름, 클래스 이름을 `README.md`에 미리 작성한다. +- 축약하지 않는다. + - 클래스와 메서드 이름을 한 두 단어로 유지하려고 노력한다. + - 문맥을 중복하는 이름을 자제하자. + - `X: Order.shipOrder()` + - `O: Order.ship()` +- JavaScript에서 제공하는 API를 적극 활용한다. + - 함수를 구현하기 전에 API에서 해당 함수를 제공하는지 확인한다. +- 구현할 기능 목록을 잘 정리하고 변경사항이 있을 때 바로 최신화한다. +- 클래스는 필드, 생성자, 메서드 순으로 작성한다. +- 1메서드 1기능 (ex: 15라인 넘지 않도록 의식적으로 분리, 나만의 기준 세우기) +- 값을 하드 코딩하지 않는다. (대신 상수를 정의) + +### 학습 목표 +- 관련 함수를 묶어 클래스를 만들고, 객체들이 협력하여 하나의 큰 기능을 수행하도록 한다. +- 클래스와 함수에 대한 단위 테스트를 통해 의도한 대로 정확하게 작동하는 영역을 확보한다. +- 2주 차 공통 피드백을 최대한 반영한다. + + ## 기능 요구 사항 +- 로또 번호의 숫자 범위는 1~45까지이다. +- 1개의 로또를 발행할 때 중복되지 않는 6개의 숫자를 뽑는다. +- 당첨 번호 추첨 시 중복되지 않는 숫자 6개와 보너스 번호 1개를 뽑는다. +- 당첨은 1등부터 5등까지 있다. 당첨 기준과 금액은 아래와 같다. + - 1등: 6개 번호 일치 / 2,000,000,000원 + - 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원 + - 3등: 5개 번호 일치 / 1,500,000원 + - 4등: 4개 번호 일치 / 50,000원 + - 5등: 3개 번호 일치 / 5,000원 +- 로또 구입 금액을 입력하면 구입 금액에 해당하는 만큼 로또를 발행해야 한다. +- 로또 1장의 가격은 1,000원이다. +- 당첨 번호와 보너스 번호를 입력받는다. +- 사용자가 구매한 로또 번호와 당첨 번호를 비교하여 당첨 내역 및 수익률을 출력하고 로또 게임을 종료한다. +- 사용자가 잘못된 값을 입력할 경우 "[ERROR]"로 시작하는 메시지와 함께 Error를 발생시키고 해당 메시지를 출력한 다음 해당 지점부터 다시 입력을 받는다. From 1de6d6870b3b20326173ed761d4eeb892e071a0b Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Fri, 1 Nov 2024 20:26:19 +0900 Subject: [PATCH 02/20] =?UTF-8?q?docs(README.md):=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=20=EA=B8=B0=EB=8A=A5=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 01009ee84..df991db2e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ 이 프로젝트는 우아한테크코스 프리코스 3주차 과제인 **간단한 로또 발매기**입니다. ### 기능 목록 -- [ ] 중복 숫자 없도록 로또 발행 (6개 숫자) - [ ] 입력받은 로또 구입 금액만큼 로또 발행 - [ ] 당첨, 보너스 번호 입력 - [ ] 기준에 따라 당첨 값 반환 From 9ba3265fcefc9ca5291ce67f224d0f50c3170861 Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Fri, 1 Nov 2024 21:14:24 +0900 Subject: [PATCH 03/20] =?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=EB=A7=8C=ED=81=BC=20=EB=A1=9C?= =?UTF-8?q?=EB=98=90=20=EB=B0=9C=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/LottoArr.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/LottoArr.js diff --git a/src/LottoArr.js b/src/LottoArr.js new file mode 100644 index 000000000..a49c8e4ac --- /dev/null +++ b/src/LottoArr.js @@ -0,0 +1,27 @@ +import Lotto from "./Lotto.js" +import { MissionUtils } from "@woowacourse/mission-utils" + +class LottoArr { + #lottoArr = [] + #TIMES + #PAY_INPUT + + constructor(PAY_INPUT) { + this.#PAY_INPUT = PAY_INPUT + this.TIMES = PAY_INPUT / 1000 + } + + create() { + for (let i = 0; i < this.TIMES; i++) { + const LOTTO_NUMBERS = MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6) + this.#lottoArr[i] = new Lotto(LOTTO_NUMBERS) + MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6) + } + return this.#lottoArr + } +} + +// 테스트 코드 +const lottoArr = new LottoArr(5000); +const result = lottoArr.create(); +console.log(result); From abf1a9ded33736759532b2bc9bb36a4fc72a728e Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Fri, 1 Nov 2024 21:16:26 +0900 Subject: [PATCH 04/20] =?UTF-8?q?docs(README.md):=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EB=B0=9B=EC=9D=80=20=EB=A1=9C=EB=98=90=20=EA=B5=AC=EC=9E=85=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1=EB=A7=8C=ED=81=BC=20=EB=A1=9C=EB=98=90=20?= =?UTF-8?q?=EB=B0=9C=ED=96=89=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index df991db2e..9c9a5d5dc 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 이 프로젝트는 우아한테크코스 프리코스 3주차 과제인 **간단한 로또 발매기**입니다. ### 기능 목록 -- [ ] 입력받은 로또 구입 금액만큼 로또 발행 +- [x] 입력받은 로또 구입 금액만큼 로또 발행 - [ ] 당첨, 보너스 번호 입력 - [ ] 기준에 따라 당첨 값 반환 - [ ] 수익률 반환 From 76e048c5e70692e727300c68464fc145bd5a378d Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Fri, 1 Nov 2024 21:23:23 +0900 Subject: [PATCH 05/20] =?UTF-8?q?docs(README.md):=20=EB=A1=9C=EB=98=90=20?= =?UTF-8?q?=EA=B5=AC=EC=9E=85=20=EA=B8=88=EC=95=A1=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9c9a5d5dc..567a8db20 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ 이 프로젝트는 우아한테크코스 프리코스 3주차 과제인 **간단한 로또 발매기**입니다. ### 기능 목록 +- [ ] 로또 구입 금액 입력 - [x] 입력받은 로또 구입 금액만큼 로또 발행 - [ ] 당첨, 보너스 번호 입력 - [ ] 기준에 따라 당첨 값 반환 From 3151fa5f3dfbcc8f094083c864a94cba07af59d3 Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Fri, 1 Nov 2024 21:28:01 +0900 Subject: [PATCH 06/20] =?UTF-8?q?docs(README.md):=20=EB=A1=9C=EB=98=90=20?= =?UTF-8?q?=EA=B5=AC=EC=9E=85=20=EA=B8=88=EC=95=A1=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 567a8db20..e97ad6527 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 이 프로젝트는 우아한테크코스 프리코스 3주차 과제인 **간단한 로또 발매기**입니다. ### 기능 목록 -- [ ] 로또 구입 금액 입력 +- [x] 로또 구입 금액 입력 - [x] 입력받은 로또 구입 금액만큼 로또 발행 - [ ] 당첨, 보너스 번호 입력 - [ ] 기준에 따라 당첨 값 반환 From b7dc953da50c8a0483d29f5902eef60393d087de Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Fri, 1 Nov 2024 21:35:53 +0900 Subject: [PATCH 07/20] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8,=20=EB=B3=B4?= =?UTF-8?q?=EB=84=88=EC=8A=A4=20=EB=B2=88=ED=98=B8=20=EC=9E=85=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index 091aa0a5d..75723484a 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,12 @@ +import { Console } from "@woowacourse/mission-utils"; + + class App { - async run() {} + async run() { + const PAY_INPUT = await Console.readLineAsync("구입금액을 입력해 주세요.\n") + const WINNING_NUMBERS = await Console.readLineAsync("당첨 번호를 입력해 주세요.\n") + const BONUS_NUMBER = await Console.readLineAsync("보너스 번호를 입력해 주세요.\n") + } } export default App; From 2c2ca7f12b2cad63ad781af0d4d64e406873a2f8 Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Fri, 1 Nov 2024 21:36:27 +0900 Subject: [PATCH 08/20] =?UTF-8?q?docs(README.md):=20=EB=8B=B9=EC=B2=A8,=20?= =?UTF-8?q?=EB=B3=B4=EB=84=88=EC=8A=A4=20=EB=B2=88=ED=98=B8=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e97ad6527..ec18b18f1 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ### 기능 목록 - [x] 로또 구입 금액 입력 - [x] 입력받은 로또 구입 금액만큼 로또 발행 -- [ ] 당첨, 보너스 번호 입력 +- [x] 당첨, 보너스 번호 입력 - [ ] 기준에 따라 당첨 값 반환 - [ ] 수익률 반환 - [ ] Error handling From 98ab8c6537a7f75746ef2a4b9cf2837c0ea31fd5 Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Fri, 1 Nov 2024 21:50:24 +0900 Subject: [PATCH 09/20] =?UTF-8?q?fix:=20private=20=EC=83=81=EC=88=98=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/LottoArr.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/LottoArr.js b/src/LottoArr.js index a49c8e4ac..64b8521da 100644 --- a/src/LottoArr.js +++ b/src/LottoArr.js @@ -8,14 +8,17 @@ class LottoArr { constructor(PAY_INPUT) { this.#PAY_INPUT = PAY_INPUT - this.TIMES = PAY_INPUT / 1000 + this.#TIMES = this.#calculateTIMES() + } + + #calculateTIMES() { + return this.#PAY_INPUT / 1000 } create() { - for (let i = 0; i < this.TIMES; i++) { + for (let i = 0; i < this.#TIMES; i++) { const LOTTO_NUMBERS = MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6) this.#lottoArr[i] = new Lotto(LOTTO_NUMBERS) - MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6) } return this.#lottoArr } From 880a4c671c14b99a8be7cd455831a95996b68465 Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Fri, 1 Nov 2024 21:58:03 +0900 Subject: [PATCH 10/20] =?UTF-8?q?docs(README.md):=20=EC=8B=A4=ED=96=89=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=EC=98=88=EC=8B=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/README.md b/README.md index ec18b18f1..f6056b523 100644 --- a/README.md +++ b/README.md @@ -72,3 +72,34 @@ - 당첨 번호와 보너스 번호를 입력받는다. - 사용자가 구매한 로또 번호와 당첨 번호를 비교하여 당첨 내역 및 수익률을 출력하고 로또 게임을 종료한다. - 사용자가 잘못된 값을 입력할 경우 "[ERROR]"로 시작하는 메시지와 함께 Error를 발생시키고 해당 메시지를 출력한 다음 해당 지점부터 다시 입력을 받는다. + +### 실행 결과 예시 +```js +구입금액을 입력해 주세요. +8000 + +8개를 구매했습니다. +[8, 21, 23, 41, 42, 43] +[3, 5, 11, 16, 32, 38] +[7, 11, 16, 35, 36, 44] +[1, 8, 11, 31, 41, 42] +[13, 14, 16, 38, 42, 45] +[7, 11, 30, 40, 42, 43] +[2, 13, 22, 32, 38, 45] +[1, 3, 5, 14, 22, 45] + +당첨 번호를 입력해 주세요. +1,2,3,4,5,6 + +보너스 번호를 입력해 주세요. +7 + +당첨 통계 +--- +3개 일치 (5,000원) - 1개 +4개 일치 (50,000원) - 0개 +5개 일치 (1,500,000원) - 0개 +5개 일치, 보너스 볼 일치 (30,000,000원) - 0개 +6개 일치 (2,000,000,000원) - 0개 +총 수익률은 62.5%입니다. +``` From 78723a115fcf1a8de9d72b277e0d95dd2c8029bb Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Fri, 1 Nov 2024 23:32:14 +0900 Subject: [PATCH 11/20] =?UTF-8?q?feat:=20=EB=B0=9C=ED=96=89=20=ED=9A=9F?= =?UTF-8?q?=EC=88=98,=20=EB=B0=9C=ED=96=89=EB=90=9C=20=EB=A1=9C=EB=98=90?= =?UTF-8?q?=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lotto 클래스의 일부 Error throw도 구현했다. --- src/Lotto.js | 12 +++++++++--- src/LottoArr.js | 20 +++++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/Lotto.js b/src/Lotto.js index cb0b1527e..2f721bf2c 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -1,18 +1,24 @@ class Lotto { - #numbers; + #numbers = []; constructor(numbers) { this.#validate(numbers); - this.#numbers = 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] 로또 번호에 중복된 숫자 존재") + } + } + + toString() { + return `[${this.#numbers.join(', ')}]` } - // TODO: 추가 기능 구현 } export default Lotto; diff --git a/src/LottoArr.js b/src/LottoArr.js index 64b8521da..a9ba9167b 100644 --- a/src/LottoArr.js +++ b/src/LottoArr.js @@ -9,22 +9,32 @@ class LottoArr { constructor(PAY_INPUT) { this.#PAY_INPUT = PAY_INPUT this.#TIMES = this.#calculateTIMES() + this.#getLottoArr() } #calculateTIMES() { return this.#PAY_INPUT / 1000 } - create() { + #getLottoArr() { for (let i = 0; i < this.#TIMES; i++) { - const LOTTO_NUMBERS = MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6) + const LOTTO_NUMBERS = MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6).sort((a, b) => a - b) this.#lottoArr[i] = new Lotto(LOTTO_NUMBERS) } - return this.#lottoArr } + + print() { + let result = this.#TIMES + "개를 구매했습니다.\n" + + for (let i = 0; i < this.#lottoArr.length; i++) { + result += this.#lottoArr[i] + "\n" + } + return result + } + } // 테스트 코드 const lottoArr = new LottoArr(5000); -const result = lottoArr.create(); -console.log(result); +const result = lottoArr.print(); + From 3e02fd79620e068b72852cb52e907a5cea91855e Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Fri, 1 Nov 2024 23:32:48 +0900 Subject: [PATCH 12/20] =?UTF-8?q?docs(README.md):=20=EB=B0=9C=ED=96=89=20?= =?UTF-8?q?=ED=9A=9F=EC=88=98,=20=EB=B0=9C=ED=96=89=EB=90=9C=20=EB=A1=9C?= =?UTF-8?q?=EB=98=90=20=EC=B6=94=EA=B0=80,=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f6056b523..3cc807764 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ - [x] 로또 구입 금액 입력 - [x] 입력받은 로또 구입 금액만큼 로또 발행 - [x] 당첨, 보너스 번호 입력 +- [x] 발행 횟수, 발행된 로또 출력 - [ ] 기준에 따라 당첨 값 반환 - [ ] 수익률 반환 - [ ] Error handling From 26951581264654c59fbf6a07a6bfa343087e9d92 Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Mon, 4 Nov 2024 21:31:45 +0900 Subject: [PATCH 13/20] =?UTF-8?q?feat(Win):=20=EA=B8=B0=EC=A4=80=EC=97=90?= =?UTF-8?q?=20=EB=94=B0=EB=9D=BC=20=EB=8B=B9=EC=B2=A8=20=EA=B0=92,=20?= =?UTF-8?q?=EC=88=98=EC=9D=B5=EB=A5=A0=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Win.js | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/Win.js diff --git a/src/Win.js b/src/Win.js new file mode 100644 index 000000000..84c9b4695 --- /dev/null +++ b/src/Win.js @@ -0,0 +1,108 @@ +import LottoArr from "./LottoArr.js" + +export default class Win { + #numbers = [] + #BONUS_NUMBER + #matchCounts + #TOTAL_PRISE + #TOTAL_WIN + #returnRate + + + constructor(WINNING_NUMBERS) { + //error test + WINNING_NUMBERS.split(",").forEach(number => this.#numbers.push(Number(number.trim()))) + } + + getBonusNumber(BONUS_NUMBER) { + this.#BONUS_NUMBER = BONUS_NUMBER + } + + calculator(lottoArr) { + this.#matchCounts = this.#filtering(lottoArr) + this.#TOTAL_PRISE = this.#totalPrize() + this.#TOTAL_WIN = this.#totalWins() + this.#returnRate = (this.#TOTAL_PRISE / this.#TOTAL_WIN).toFixed(2) + } + + #filtering(lottoArr) { + const matchCounts = { + '3': 0, + '4': 0, + '5': 0, + '5+': 0, + '6': 0 + } + + lottoArr.forEach((lotto) => { + const matchCount = this.#numbers.reduce((count, number) => { + return count + (lotto.includes(number) ? 1 : 0) + }, 0) + + if (matchCount === 5 && lotto.includes(this.#BONUS_NUMBER)) { + matchCounts['5+'] += 1 + } else if (matchCount > 2) { + matchCounts[`${matchCount}`] += 1; + } + } + ) + + return matchCounts + } + + #totalPrize() { + const FIRST = 2000000000 + const SECOND = 30000000 + const THIRD = 1500000 + const FOURTH = 50000 + const FIFTH = 5000 + const PRIZE_ARR = [FIFTH, FOURTH, THIRD, SECOND, FIRST] + + const TOTAL = Object.keys(this.#matchCounts).reduce((total, key, index) => { + const count = this.#matchCounts[key] + const prize = PRIZE_ARR[index] + return total + (count * prize) + }, 0) + return TOTAL + } + + #totalWins() { + return Object.keys(this.#matchCounts).reduce((total, key) => { + return total + this.#matchCounts[key] + }, 0) + } + + print() { + let result = + ` + 당첨 통계 + --- + 3개 일치 (5,000원) - ${this.#matchCounts['3']}개 + 4개 일치 (50,000원) - ${this.#matchCounts['4']}개 + 5개 일치 (1,500,000원) - ${this.#matchCounts['5']}개 + 5개 일치, 보너스 볼 일치 (30,000,000원) - ${this.#matchCounts['5+']}개 + 6개 일치 (2,000,000,000원) - ${this.#matchCounts['6']}개 + 총 수익률은 ${this.#returnRate}%입니다. + ` + return result + } + +} + +//debug code +// const LottoArr = [ +// [8, 21, 23, 41, 42, 43], +// [3, 5, 11, 16, 32, 38], +// [7, 11, 16, 35, 36, 44], +// [1, 8, 11, 31, 41, 42], +// [13, 14, 16, 38, 42, 45], +// [7, 11, 30, 40, 42, 43], +// [2, 13, 22, 32, 38, 45], +// [1, 3, 5, 14, 22, 45], +// ] +// const LOTTO_ARRAY = new LottoArr(5000) +// const win = new Win('1,2,3,4,5,6') +// win.getBonusNumber(7) + +// const result = win.filtering(LOTTO_ARRAY.arr()) +// console.log(result) From bbe9c34823cf5c60a31234669b72e512980c8cb9 Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Mon, 4 Nov 2024 21:33:15 +0900 Subject: [PATCH 14/20] =?UTF-8?q?fix:=20array=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=EC=8B=9D=EC=95=88=EB=90=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit array를 return하는 작은 함수사용 --- src/Lotto.js | 4 ++++ src/LottoArr.js | 15 ++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Lotto.js b/src/Lotto.js index 2f721bf2c..d63b6a356 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -19,6 +19,10 @@ class Lotto { return `[${this.#numbers.join(', ')}]` } + toArr() { + return this.#numbers + } + } export default Lotto; diff --git a/src/LottoArr.js b/src/LottoArr.js index a9ba9167b..1f7f1c70f 100644 --- a/src/LottoArr.js +++ b/src/LottoArr.js @@ -19,7 +19,7 @@ class LottoArr { #getLottoArr() { for (let i = 0; i < this.#TIMES; i++) { const LOTTO_NUMBERS = MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6).sort((a, b) => a - b) - this.#lottoArr[i] = new Lotto(LOTTO_NUMBERS) + this.#lottoArr[i] = new Lotto(LOTTO_NUMBERS).toArr() } } @@ -32,9 +32,14 @@ class LottoArr { return result } -} + toString() { + return `[${this.#lottoArr.join(', ')}]` + } -// 테스트 코드 -const lottoArr = new LottoArr(5000); -const result = lottoArr.print(); + toArr() { + return this.#lottoArr + } + +} +export default LottoArr \ No newline at end of file From 16311aa6967248194cd8c8449dc79851e22661a2 Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Mon, 4 Nov 2024 21:34:04 +0900 Subject: [PATCH 15/20] =?UTF-8?q?docs(README.md):=20=EA=B8=B0=EC=A4=80?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EB=8B=B9=EC=B2=A8=20=EA=B0=92?= =?UTF-8?q?,=20=EC=88=98=EC=9D=B5=EB=A5=A0=20=EB=B0=98=ED=99=98=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- src/App.js | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3cc807764..8d6a6da46 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ - [x] 입력받은 로또 구입 금액만큼 로또 발행 - [x] 당첨, 보너스 번호 입력 - [x] 발행 횟수, 발행된 로또 출력 -- [ ] 기준에 따라 당첨 값 반환 -- [ ] 수익률 반환 +- [x] 기준에 따라 당첨 값 반환 +- [x] 수익률 반환 - [ ] Error handling - 입력 틀리면 그 지점부터 다시 입력 diff --git a/src/App.js b/src/App.js index 75723484a..8f356e2b3 100644 --- a/src/App.js +++ b/src/App.js @@ -1,12 +1,21 @@ import { Console } from "@woowacourse/mission-utils"; - +import LottoArr from "./LottoArr.js"; +import Win from "./Win.js"; class App { async run() { const PAY_INPUT = await Console.readLineAsync("구입금액을 입력해 주세요.\n") + const LOTTO_ARRAY = new LottoArr(PAY_INPUT) + Console.print("\n" + LOTTO_ARRAY.print()) const WINNING_NUMBERS = await Console.readLineAsync("당첨 번호를 입력해 주세요.\n") + const Wisn = new Win(WINNING_NUMBERS) const BONUS_NUMBER = await Console.readLineAsync("보너스 번호를 입력해 주세요.\n") + Wisn.getBonusNumber(BONUS_NUMBER) + Wisn.calculator(LOTTO_ARRAY.toArr()) + Console.print(Wisn.print()) } } export default App; + + From e32bc5b99385e6c68bd21338ab6546001f7efe1b Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Mon, 4 Nov 2024 21:35:01 +0900 Subject: [PATCH 16/20] =?UTF-8?q?docs(README.md):=20error=20case=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 --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 8d6a6da46..9d50fc072 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,6 @@ - 정수 X - 1 ~ 45 범위 X - 구분자 쉼표 X - - 공백 포함 - 보너스 번호 입력 - 입력 X - 숫자 X From f539226554257d73970feca8c2fe09699b35b17a Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Mon, 4 Nov 2024 21:39:10 +0900 Subject: [PATCH 17/20] =?UTF-8?q?docs(README.md):=20error=20case=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9d50fc072..af47bc857 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ - 숫자 X - 1 ~ 45 범위 X - 정수 X +- 수익률 + - zeroException From 03466346ada3c407b6a128c3960bf1acc4be2e04 Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Mon, 4 Nov 2024 21:40:16 +0900 Subject: [PATCH 18/20] fix(Win): returnRate zeroException --- src/Win.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Win.js b/src/Win.js index 84c9b4695..911bc2346 100644 --- a/src/Win.js +++ b/src/Win.js @@ -23,6 +23,9 @@ export default class Win { this.#TOTAL_PRISE = this.#totalPrize() this.#TOTAL_WIN = this.#totalWins() this.#returnRate = (this.#TOTAL_PRISE / this.#TOTAL_WIN).toFixed(2) + if (isNaN(this.#returnRate)) { + this.#returnRate = 0 + } } #filtering(lottoArr) { @@ -42,7 +45,7 @@ export default class Win { if (matchCount === 5 && lotto.includes(this.#BONUS_NUMBER)) { matchCounts['5+'] += 1 } else if (matchCount > 2) { - matchCounts[`${matchCount}`] += 1; + matchCounts[`${matchCount}`] += 1 } } ) From f7097156822f37f97f856abc5f862a0e22eae4ea Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Mon, 4 Nov 2024 21:50:05 +0900 Subject: [PATCH 19/20] =?UTF-8?q?fix:=20=EC=88=98=EC=9D=B5=EB=A5=A0=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=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 | 2 +- src/Win.js | 15 ++++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/App.js b/src/App.js index 8f356e2b3..0c0148cba 100644 --- a/src/App.js +++ b/src/App.js @@ -8,7 +8,7 @@ class App { const LOTTO_ARRAY = new LottoArr(PAY_INPUT) Console.print("\n" + LOTTO_ARRAY.print()) const WINNING_NUMBERS = await Console.readLineAsync("당첨 번호를 입력해 주세요.\n") - const Wisn = new Win(WINNING_NUMBERS) + const Wisn = new Win(WINNING_NUMBERS, PAY_INPUT) const BONUS_NUMBER = await Console.readLineAsync("보너스 번호를 입력해 주세요.\n") Wisn.getBonusNumber(BONUS_NUMBER) Wisn.calculator(LOTTO_ARRAY.toArr()) diff --git a/src/Win.js b/src/Win.js index 911bc2346..4de3b64e3 100644 --- a/src/Win.js +++ b/src/Win.js @@ -5,13 +5,13 @@ export default class Win { #BONUS_NUMBER #matchCounts #TOTAL_PRISE - #TOTAL_WIN #returnRate + #PAY_INPUT - - constructor(WINNING_NUMBERS) { + constructor(WINNING_NUMBERS, PAY_INPUT) { //error test WINNING_NUMBERS.split(",").forEach(number => this.#numbers.push(Number(number.trim()))) + this.#PAY_INPUT = PAY_INPUT } getBonusNumber(BONUS_NUMBER) { @@ -21,8 +21,7 @@ export default class Win { calculator(lottoArr) { this.#matchCounts = this.#filtering(lottoArr) this.#TOTAL_PRISE = this.#totalPrize() - this.#TOTAL_WIN = this.#totalWins() - this.#returnRate = (this.#TOTAL_PRISE / this.#TOTAL_WIN).toFixed(2) + this.#returnRate = (this.#TOTAL_PRISE / this.#PAY_INPUT * 100).toFixed(1) if (isNaN(this.#returnRate)) { this.#returnRate = 0 } @@ -69,12 +68,6 @@ export default class Win { return TOTAL } - #totalWins() { - return Object.keys(this.#matchCounts).reduce((total, key) => { - return total + this.#matchCounts[key] - }, 0) - } - print() { let result = ` From d7ffa98ec9441ef553e2bad5be78661c7e94fab1 Mon Sep 17 00:00:00 2001 From: sangkyeongJeong <137258368+VsangkyeongV@users.noreply.github.com> Date: Mon, 4 Nov 2024 23:45:23 +0900 Subject: [PATCH 20/20] =?UTF-8?q?feat:=20valid=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 20 ++++++--- src/LottoArr.js | 2 +- src/VaildInput.js | 110 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 8 deletions(-) create mode 100644 src/VaildInput.js diff --git a/src/App.js b/src/App.js index 0c0148cba..6982628ec 100644 --- a/src/App.js +++ b/src/App.js @@ -1,18 +1,24 @@ import { Console } from "@woowacourse/mission-utils"; import LottoArr from "./LottoArr.js"; import Win from "./Win.js"; +import { inputBonusNumber, inputPay, inputWinningNumbers } from "./VaildInput.js"; class App { + async run() { - const PAY_INPUT = await Console.readLineAsync("구입금액을 입력해 주세요.\n") + const PAY_INPUT = await inputPay() + //const PAY_INPUT = await Console.readLineAsync("구입금액을 입력해 주세요.\n") + console.log(PAY_INPUT) const LOTTO_ARRAY = new LottoArr(PAY_INPUT) Console.print("\n" + LOTTO_ARRAY.print()) - const WINNING_NUMBERS = await Console.readLineAsync("당첨 번호를 입력해 주세요.\n") - const Wisn = new Win(WINNING_NUMBERS, PAY_INPUT) - const BONUS_NUMBER = await Console.readLineAsync("보너스 번호를 입력해 주세요.\n") - Wisn.getBonusNumber(BONUS_NUMBER) - Wisn.calculator(LOTTO_ARRAY.toArr()) - Console.print(Wisn.print()) + const WINNING_NUMBERS = await inputWinningNumbers() + // const WINNING_NUMBERS = await Console.readLineAsync("당첨 번호를 입력해 주세요.\n") + const WIN = new Win(WINNING_NUMBERS, PAY_INPUT) + const BONUS_NUMBER = await inputBonusNumber() + // const BONUS_NUMBER = await Console.readLineAsync("보너스 번호를 입력해 주세요.\n") + WIN.getBonusNumber(BONUS_NUMBER) + WIN.calculator(LOTTO_ARRAY.toArr()) + Console.print(WIN.print()) } } diff --git a/src/LottoArr.js b/src/LottoArr.js index 1f7f1c70f..6b31bfdac 100644 --- a/src/LottoArr.js +++ b/src/LottoArr.js @@ -27,7 +27,7 @@ class LottoArr { let result = this.#TIMES + "개를 구매했습니다.\n" for (let i = 0; i < this.#lottoArr.length; i++) { - result += this.#lottoArr[i] + "\n" + result += '[' + this.#lottoArr[i] + ']' + "\n" } return result } diff --git a/src/VaildInput.js b/src/VaildInput.js new file mode 100644 index 000000000..0d0f439a4 --- /dev/null +++ b/src/VaildInput.js @@ -0,0 +1,110 @@ +import { Console } from "@woowacourse/mission-utils" + +export const getVaildInput = async (PROMPT, valid) => { + let isValid = false + let input = '' + while (!isValid) { + input = await Console.readLineAsync(PROMPT) + isValid = valid(input) + } + return input +} + +export const inputPay = async () => { + const PROMPT = '구입금액을 입력해 주세요.\n' + + const valid = (INPUT) => { + if (INPUT == '') { + Console.print("[ERROR] 로또 구입 금액을 입력해 주세요.") + return false + } + if (isNaN(INPUT)) { + Console.print("[ERROR] 숫자를 입력해 주세요.") + return false + } + if (INPUT % 1000 != 0) { + Console.print("[ERROR] 천 원 단위로 입력해 주세요.") + return false + } + return true + } + return await getVaildInput(PROMPT, valid) +} + +export const inputWinningNumbers = async () => { + const PROMPT = '당첨 번호를 입력해 주세요.\n' + + const valid = (INPUT) => { + if (INPUT == '' || INPUT == undefined) { + Console.print("[ERROR] 당첨 번호를 입력해 주세요.") + return false + } + + const INPUT_ARR = INPUT.split(',') + + + if (INPUT_ARR.every(num => isNaN(num))) { + Console.print("[ERROR] 숫자를 입력해 주세요.") + return false + } + + if (INPUT_ARR.length !== 6) { + Console.print("[ERROR] 수를 6개 입력해 주세요") + return false + } + + if (INPUT_ARR.every(num => !Number.isInteger(num))) { + Console.print("[ERROR] 정수를 입력해 주세요") + return false + } + + const numberSet = new Set(INPUT_ARR.map(Number)) + if (numberSet.size !== INPUT_ARR.length) { + Console.print("[ERROR] 로또 번호에 중복된 숫자가 존재합니다.") + return false + } + + for (const num of numberSet) { + if (num < 1 || num > 45) { + Console.print("[ERROR] 로또 번호는 1과 45 사이의 숫자여야 합니다.") + return false + } + } + + return true + } + + return await getVaildInput(PROMPT, valid) +} + + +export const inputBonusNumber = async () => { + const PROMPT = '보너스 번호를 입력해 주세요.\n' + + const valid = (INPUT) => { + if (INPUT == '') { + Console.print("[ERROR] 보너스 번호를 입력해 주세요.") + return false + } + + if (isNaN(INPUT)) { + Console.print("[ERROR] 숫자를 입력해 주세요.") + return false + } + + if (!Number.isInteger(INPUT)) { + Console.print("[ERROR] 정수를 입력해 주세요") + } + + + for (const num of numberSet) { + if (num < 1 || num > 45) { + Console.print("[ERROR] 보너스 번호는 1과 45 사이의 숫자여야 합니다.") + return false + } + } + + } + + return await getVaildInput(PROMPT, valid) +} \ No newline at end of file