From 1af59765889e4b9fed33b9c81479d1a9382980de Mon Sep 17 00:00:00 2001 From: devGEP Date: Sun, 5 Nov 2023 22:53:35 +0900 Subject: [PATCH 01/17] =?UTF-8?q?docs:=20=EA=B2=8C=EC=9E=84=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B0=8F=20=EA=B5=AC=ED=98=84=ED=95=A0=20=EA=B8=B0?= =?UTF-8?q?=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 | 180 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..489d4afe99 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,180 @@ +# 게임 흐름 +1. 로또 시작 +2. 로또를 구입하기 위해 지불할 금액 입력받기 + - 금액에 대한 유효성 검사 + - 금액을 로또 개수로 변환 후, 출력 +4. 로또 번호 생성 로직 + - 로또 개수만큼 + 1) 로또 번호의 숫자를 1~45까지 무작위로 6개를 생성 + 2) 로또 번호의 배열을 오름차순으로 정렬 후, 출력 +5. 당첨 번호 입력받기 + - 당첨 번호에 대한 유효성 검사 +6. 보너스 당첨 번호 입력받기 + - 보너스 번호에 대한 유효성 검사 +7. 로또 결과 + - 주어진 로또 번호가 당첨 번호와 일치하는지 확인 후, 출력 + - 수익률 계산 후, 출력 + + +
+
+ +# 구현할 기능 목록 + +# Controller +## LottoContoller.js +> 사용자 입력을 받아 모델을 업데이트하고, 뷰를 통해 결과를 표시하는 함수들을 관리 + +
+ +handlePurchase +- [ ] 로또 구매를 처리 + +LottoWinningInputHandler +- [ ] 당첨 번호 입력을 처리 + +calculateProfit +- [ ] 수익률을 계산 + +
+ +# Model +## Lotto.js +> 로또 번호를 생성하고 관리 + +
+ +generateLottoNumbers +- [ ] 로또 번호의 숫자를 1~45까지 무작위로 6개를 생성 + +sortLottoNumbers +- [ ] 로또 번호를 오름차순으로 정렬 + +
+ +## LottoMachine.js +> 로또 발행과 관련된 로직 관리 + +
+ +purchaseLottos +- [ ] 지불한 금액으로 구매할 수 있는 로또의 수를 계산 + +printLottos +- [ ] 구매한 로또의 번호를 출력 + +
+ +## WinningLotto.js +> 당첨 번호와 보너스 번호를 관리, 당첨 여부를 확인 + +
+ +setWinningNumbers +- [ ] 당첨 번호를 설정 + +setBonumsNumbers +- [ ] 보너스 당첨 번호를 설정 + +validateNumbers +- [ ] 당첨 번호의 유효성을 검사 + +validateBonusNumbers +- [ ] 보너스 당첨 번호의 유효성을 검사 + +checkWinning +- [ ] 주어진 로또 번호가 당첨 번호와 일치하는지 확인 + +
+ +# View +## LottoInputView.js +> **사용자로부터 입력을 받는 부분을 담당**
+ 금액 입력, 당첨 번호 입력 + +
+ +promptPurchaseAmount +- [ ] 사용자에게 구입 금액을 입력받기 + +promptWinnningNumbers +- [ ] 사용자에게 당첨 번호를 입력받기 + +promptBonusNumber +- [ ] 사용자에게 보너스 번호를 입력받기 + +printLottos +- [ ] 구매한 로또 번호를 화면에 출력하기 + +printLottoResult +- [ ] 당첨 결과를 화면에 출력하기 + +
+ +## LottoOutputView.js +> **결과나 메세지를 사용자에게 표시한느 부분을 담당**
+ 로또 번호, 당첨 결과, 수익률 등을 사용자에게 표시하는 함수들을 관리 + +
+ +# Utils +## Constants.js +> Enum 관리(게임 메세지, 에러 메세지, 각 등수별 상금 정보) + +
+ +## InputHandler.js +> 사용자로부터의 입력을 받고 검증하는 함수들을 관리 + +getPurchaseAmount +- [INPUT] 얼마로 살건지 +- `구입금액을 입력해 주세요.` + +getLottoWinningNumber +- [INPUT] 당첨 번호 입력 (배열) +- `당첨 번호를 입력해 주세요.` + +getLottoBonusWinningNumber +- [INPUT] 보너스 번호 입력 (숫자) +- `보너스 번호를 입력해 주세요.` + +
+ +## InputValidator.js +### `입력값이 유효한지 검사하는 로직을 관리` + + +
+ +## OutputHandler.js +> 사용자에게 정보를 출력하는 함수들을 관리 + +
+ +printPurchaseCount +- [OUTPUT] 몇개를 구입했는지 출력 +- `${lottoCount}개를 구매했습니다.` + +printLottoNumber +- [OUTPUT] 사용자가 구입한 로또 번호 출력 +- `[8, 21, 23, 41, 42, 43]`
+ `[3, 5, 11, 16, 32, 38]` ... + +announceWinningNumber +- [OUTPUT] 당첨 통계 +- `당첨 통계`
+ `---`
+ `3개 일치 (5,000원) - 1개`
+ `4개 일치 (50,000원) - 0개`
+ `5개 일치 (1,500,000원) - 0개`
+ `5개 일치, 보너스 볼 일치 (30,000,000원) - 0개`
+ `6개 일치 (2,000,000,000원) - 0개`
+ +printWinningRates +- [OUTPUT] 총 수익률 출력 +- `총 수익률은 ${winningRates}%입니다.` + +
+ +## ErrorHandler.js +> 예외 처리와 관련된 함수나 로직을 관리 \ No newline at end of file From b4332726e13fd8c99d486cad248646bdd5562623 Mon Sep 17 00:00:00 2001 From: devGEP Date: Sun, 5 Nov 2023 22:57:21 +0900 Subject: [PATCH 02/17] =?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=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/docs/README.md b/docs/README.md index 489d4afe99..3a1d2bd300 100644 --- a/docs/README.md +++ b/docs/README.md @@ -33,7 +33,7 @@ handlePurchase LottoWinningInputHandler - [ ] 당첨 번호 입력을 처리 -calculateProfit +calculateProfitRates - [ ] 수익률을 계산
@@ -103,17 +103,22 @@ promptWinnningNumbers promptBonusNumber - [ ] 사용자에게 보너스 번호를 입력받기 +
+ +## LottoOutputView.js +> **결과나 메세지를 사용자에게 표시하는 부분을 담당**
+ 로또 번호, 당첨 결과, 수익률 등을 사용자에게 표시하는 함수들을 관리 + +
+ printLottos - [ ] 구매한 로또 번호를 화면에 출력하기 printLottoResult - [ ] 당첨 결과를 화면에 출력하기 -
- -## LottoOutputView.js -> **결과나 메세지를 사용자에게 표시한느 부분을 담당**
- 로또 번호, 당첨 결과, 수익률 등을 사용자에게 표시하는 함수들을 관리 +printProfitRates +- [ ] 수익률을 화면에 출력하기
@@ -127,22 +132,21 @@ printLottoResult > 사용자로부터의 입력을 받고 검증하는 함수들을 관리 getPurchaseAmount -- [INPUT] 얼마로 살건지 +- [ ] 로또를 구입하기 위해 지불할 금액 입력받기 - `구입금액을 입력해 주세요.` getLottoWinningNumber -- [INPUT] 당첨 번호 입력 (배열) +- [ ] 당첨 번호 입력 (배열) - `당첨 번호를 입력해 주세요.` getLottoBonusWinningNumber -- [INPUT] 보너스 번호 입력 (숫자) +- [ ] 보너스 번호 입력 (숫자) - `보너스 번호를 입력해 주세요.`
## InputValidator.js -### `입력값이 유효한지 검사하는 로직을 관리` - +> 입력값이 유효한지 검사하는 로직을 관리
@@ -152,16 +156,16 @@ getLottoBonusWinningNumber
printPurchaseCount -- [OUTPUT] 몇개를 구입했는지 출력 +- [ ] 몇개를 구입했는지 출력 - `${lottoCount}개를 구매했습니다.` printLottoNumber -- [OUTPUT] 사용자가 구입한 로또 번호 출력 +- [ ] 사용자가 구입한 로또 번호 출력 - `[8, 21, 23, 41, 42, 43]`
`[3, 5, 11, 16, 32, 38]` ... announceWinningNumber -- [OUTPUT] 당첨 통계 +- [ ] 당첨 통계 - `당첨 통계`
`---`
`3개 일치 (5,000원) - 1개`
@@ -171,7 +175,7 @@ announceWinningNumber `6개 일치 (2,000,000,000원) - 0개`
printWinningRates -- [OUTPUT] 총 수익률 출력 +- [ ] 총 수익률 출력 - `총 수익률은 ${winningRates}%입니다.`
From 9fe9acaf597a150971ce7b3b571355ecd6271440 Mon Sep 17 00:00:00 2001 From: devGEP Date: Mon, 6 Nov 2023 06:30:25 +0900 Subject: [PATCH 03/17] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EA=B5=AC?= =?UTF-8?q?=EC=9E=85=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=9C=20=EC=A7=80?= =?UTF-8?q?=EB=B6=88=ED=95=A0=20=EA=B8=88=EC=95=A1=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EB=B0=9B=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 --- docs/README.md | 4 ++-- src/App.js | 15 ++++++++++++++- src/Controller/LottoController.js | 15 +++++++++++++++ src/View/InputView.js | 16 ++++++++++++++++ src/utils/Constants.js | 6 ++++++ 5 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 src/Controller/LottoController.js create mode 100644 src/View/InputView.js create mode 100644 src/utils/Constants.js diff --git a/docs/README.md b/docs/README.md index 3a1d2bd300..d67cd3fd40 100644 --- a/docs/README.md +++ b/docs/README.md @@ -57,7 +57,7 @@ sortLottoNumbers
-purchaseLottos +calculateLottoCount - [ ] 지불한 금액으로 구매할 수 있는 로또의 수를 계산 printLottos @@ -95,7 +95,7 @@ checkWinning
promptPurchaseAmount -- [ ] 사용자에게 구입 금액을 입력받기 +- [x] 사용자에게 구입 금액을 입력받기 promptWinnningNumbers - [ ] 사용자에게 당첨 번호를 입력받기 diff --git a/src/App.js b/src/App.js index c38b30d5b2..1463cbcf67 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,18 @@ +import LottoController from "./Controller/LottoController.js"; + class App { - async play() {} + constructor() { + this.lottoController = new LottoController(); + } + + async play() { + await this.startLotto(); + } + + async startLotto() { + this.lottoController.handlePurchase(); + + } } export default App; diff --git a/src/Controller/LottoController.js b/src/Controller/LottoController.js new file mode 100644 index 0000000000..1b1c2471d1 --- /dev/null +++ b/src/Controller/LottoController.js @@ -0,0 +1,15 @@ +import InputView from "../View/InputView.js"; +import { Console } from '@woowacourse/mission-utils'; + +class LottoController { + constructor() { + this.inputView = new InputView(); + } + + async handlePurchase() { + const purchaseAmount = await this.inputView.promptPurchaseAmount(); + Console.print(purchaseAmount); + } +} + +export default LottoController; \ No newline at end of file diff --git a/src/View/InputView.js b/src/View/InputView.js new file mode 100644 index 0000000000..cb63ec5391 --- /dev/null +++ b/src/View/InputView.js @@ -0,0 +1,16 @@ +import { Console } from '@woowacourse/mission-utils'; +import { GAME_MESSAGES } from '../utils/Constants.js'; + +class InputView { + async getUserInput(question) { + return await Console.readLineAsync(question); + } + + async promptPurchaseAmount() { + const money = await this.getUserInput(GAME_MESSAGES.ENTER_PURCHASE_AMOUNT); + // validation 처리할 예정 + return money; + } +} + +export default InputView; \ No newline at end of file diff --git a/src/utils/Constants.js b/src/utils/Constants.js new file mode 100644 index 0000000000..a1ce0da8ca --- /dev/null +++ b/src/utils/Constants.js @@ -0,0 +1,6 @@ +export const GAME_MESSAGES = { + ENTER_PURCHASE_AMOUNT: "구입금액을 입력해 주세요.", + CONFIRM_PURCHASED_LOTTOS_AMOUNT: "개를 구매했습니다.", + ENTER_WINNING_NUMBERS: "당첨 번호를 입력해 주세요.", + ENTER_BONUS_NUMBER: "보너스 번호를 입력해 주세요.", +} \ No newline at end of file From 129a6e9c778870d9e4407eea20f77d7adc68e8c4 Mon Sep 17 00:00:00 2001 From: devGEP Date: Mon, 6 Nov 2023 06:42:19 +0900 Subject: [PATCH 04/17] =?UTF-8?q?feat:=20=EC=A7=80=EB=B6=88=ED=95=9C=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1=EC=9C=BC=EB=A1=9C=20=EA=B5=AC=EB=A7=A4?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20=EB=A1=9C=EB=98=90?= =?UTF-8?q?=EC=9D=98=20=EC=88=98=EB=A5=BC=20=EA=B3=84=EC=82=B0=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 --- src/Controller/LottoController.js | 5 ++++- src/Model/LottoMachine.js | 9 +++++++++ src/utils/Constants.js | 6 +++--- 3 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 src/Model/LottoMachine.js diff --git a/src/Controller/LottoController.js b/src/Controller/LottoController.js index 1b1c2471d1..0d04168754 100644 --- a/src/Controller/LottoController.js +++ b/src/Controller/LottoController.js @@ -1,14 +1,17 @@ import InputView from "../View/InputView.js"; +import LottoMachine from "../Model/LottoMachine.js"; import { Console } from '@woowacourse/mission-utils'; class LottoController { constructor() { this.inputView = new InputView(); + this.lottoMachine = new LottoMachine(); } async handlePurchase() { const purchaseAmount = await this.inputView.promptPurchaseAmount(); - Console.print(purchaseAmount); + const numberOfLottos = this.lottoMachine.calculateLottoCount(purchaseAmount); + Console.print(numberOfLottos); } } diff --git a/src/Model/LottoMachine.js b/src/Model/LottoMachine.js new file mode 100644 index 0000000000..7d83ff46c7 --- /dev/null +++ b/src/Model/LottoMachine.js @@ -0,0 +1,9 @@ +class LottoMachine { + calculateLottoCount(amount) { + return Math.floor(amount / 1000); + } +} + +export default LottoMachine; + + diff --git a/src/utils/Constants.js b/src/utils/Constants.js index a1ce0da8ca..8d612c079c 100644 --- a/src/utils/Constants.js +++ b/src/utils/Constants.js @@ -1,6 +1,6 @@ export const GAME_MESSAGES = { - ENTER_PURCHASE_AMOUNT: "구입금액을 입력해 주세요.", + ENTER_PURCHASE_AMOUNT: "구입금액을 입력해 주세요. ", CONFIRM_PURCHASED_LOTTOS_AMOUNT: "개를 구매했습니다.", - ENTER_WINNING_NUMBERS: "당첨 번호를 입력해 주세요.", - ENTER_BONUS_NUMBER: "보너스 번호를 입력해 주세요.", + ENTER_WINNING_NUMBERS: "당첨 번호를 입력해 주세요. ", + ENTER_BONUS_NUMBER: "보너스 번호를 입력해 주세요. ", } \ No newline at end of file From cdcd248e121f111f47bbd30f2346a8b381979749 Mon Sep 17 00:00:00 2001 From: devGEP Date: Mon, 6 Nov 2023 07:13:23 +0900 Subject: [PATCH 05/17] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=206=EA=B0=9C=20=EB=AC=B4=EC=9E=91=EC=9C=84=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=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 generateLottoNumbers에서 6개의 로또 번호를 무작위로 생성하고 printLottoNumbersArray로 값을 넘겨줌 --- docs/README.md | 7 +++++-- src/Controller/LottoController.js | 9 +++++++-- src/Lotto.js | 18 +++++++++++++++--- src/Model/LottoMachine.js | 2 -- src/View/InputView.js | 2 +- src/utils/Constants.js | 2 +- 6 files changed, 29 insertions(+), 11 deletions(-) diff --git a/docs/README.md b/docs/README.md index d67cd3fd40..e7f5f2ce0d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -45,11 +45,14 @@ calculateProfitRates
generateLottoNumbers -- [ ] 로또 번호의 숫자를 1~45까지 무작위로 6개를 생성 +- [x] 로또 번호의 숫자를 1~45까지 무작위로 6개를 생성 sortLottoNumbers - [ ] 로또 번호를 오름차순으로 정렬 +printLottoNumbersArray +- [x] 로또 번호들의 값을 넘김 +
## LottoMachine.js @@ -58,7 +61,7 @@ sortLottoNumbers
calculateLottoCount -- [ ] 지불한 금액으로 구매할 수 있는 로또의 수를 계산 +- [x] 지불한 금액으로 구매할 수 있는 로또의 수를 계산 printLottos - [ ] 구매한 로또의 번호를 출력 diff --git a/src/Controller/LottoController.js b/src/Controller/LottoController.js index 0d04168754..9c4410eeb1 100644 --- a/src/Controller/LottoController.js +++ b/src/Controller/LottoController.js @@ -1,9 +1,11 @@ import InputView from "../View/InputView.js"; import LottoMachine from "../Model/LottoMachine.js"; +import Lotto from "../Lotto.js"; import { Console } from '@woowacourse/mission-utils'; class LottoController { constructor() { + this.lotto = new Lotto(); this.inputView = new InputView(); this.lottoMachine = new LottoMachine(); } @@ -11,8 +13,11 @@ class LottoController { async handlePurchase() { const purchaseAmount = await this.inputView.promptPurchaseAmount(); const numberOfLottos = this.lottoMachine.calculateLottoCount(purchaseAmount); - Console.print(numberOfLottos); + + this.lotto.generateLottoNumbers(numberOfLottos); + const lottoNumbersArray = this.lotto.printLottoNumbersArray(); + Console.print(lottoNumbersArray); } } -export default LottoController; \ No newline at end of file +export default LottoController; diff --git a/src/Lotto.js b/src/Lotto.js index cb0b1527e9..f07d32471d 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -1,18 +1,30 @@ +import { Random } from '@woowacourse/mission-utils'; + class Lotto { #numbers; constructor(numbers) { + this.lottoNumbersArray = []; this.#validate(numbers); this.#numbers = numbers; } + generateLottoNumbers(lottoCount) { + for (let i = 0; i < lottoCount; i += 1) { + const lottoNumber = Random.pickUniqueNumbersInRange(1, 45, 6); + this.lottoNumbersArray.push(lottoNumber); + } + } + + printLottoNumbersArray() { + return this.lottoNumbersArray; + } + #validate(numbers) { - if (numbers.length !== 6) { + if (numbers && numbers.length !== 6) { throw new Error("[ERROR] 로또 번호는 6개여야 합니다."); } } - - // TODO: 추가 기능 구현 } export default Lotto; diff --git a/src/Model/LottoMachine.js b/src/Model/LottoMachine.js index 7d83ff46c7..9b5601e324 100644 --- a/src/Model/LottoMachine.js +++ b/src/Model/LottoMachine.js @@ -5,5 +5,3 @@ class LottoMachine { } export default LottoMachine; - - diff --git a/src/View/InputView.js b/src/View/InputView.js index cb63ec5391..d8c9dc2f9b 100644 --- a/src/View/InputView.js +++ b/src/View/InputView.js @@ -13,4 +13,4 @@ class InputView { } } -export default InputView; \ No newline at end of file +export default InputView; diff --git a/src/utils/Constants.js b/src/utils/Constants.js index 8d612c079c..cccb2837cf 100644 --- a/src/utils/Constants.js +++ b/src/utils/Constants.js @@ -3,4 +3,4 @@ export const GAME_MESSAGES = { CONFIRM_PURCHASED_LOTTOS_AMOUNT: "개를 구매했습니다.", ENTER_WINNING_NUMBERS: "당첨 번호를 입력해 주세요. ", ENTER_BONUS_NUMBER: "보너스 번호를 입력해 주세요. ", -} \ No newline at end of file +} From beb68366adaadb740feda8ad9604b93b87338390 Mon Sep 17 00:00:00 2001 From: devGEP Date: Mon, 6 Nov 2023 07:16:24 +0900 Subject: [PATCH 06/17] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=98=A4=EB=A6=84=EC=B0=A8=EC=88=9C=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=95=EB=A0=AC=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 Lotto.js 파일에서 sortLottoNumbers() 함수에서 sort((num1, num2) => a - b); 라는 로직으로 배열 오름차순 구현 --- docs/README.md | 2 +- src/Controller/LottoController.js | 4 ++-- src/Lotto.js | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index e7f5f2ce0d..802b0ba014 100644 --- a/docs/README.md +++ b/docs/README.md @@ -48,7 +48,7 @@ generateLottoNumbers - [x] 로또 번호의 숫자를 1~45까지 무작위로 6개를 생성 sortLottoNumbers -- [ ] 로또 번호를 오름차순으로 정렬 +- [x] 로또 번호를 오름차순으로 정렬 printLottoNumbersArray - [x] 로또 번호들의 값을 넘김 diff --git a/src/Controller/LottoController.js b/src/Controller/LottoController.js index 9c4410eeb1..7eb0d3f4d9 100644 --- a/src/Controller/LottoController.js +++ b/src/Controller/LottoController.js @@ -13,11 +13,11 @@ class LottoController { async handlePurchase() { const purchaseAmount = await this.inputView.promptPurchaseAmount(); const numberOfLottos = this.lottoMachine.calculateLottoCount(purchaseAmount); - + this.lotto.generateLottoNumbers(numberOfLottos); const lottoNumbersArray = this.lotto.printLottoNumbersArray(); Console.print(lottoNumbersArray); } } -export default LottoController; +export default LottoController; \ No newline at end of file diff --git a/src/Lotto.js b/src/Lotto.js index f07d32471d..ebdeb46d71 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -12,10 +12,14 @@ class Lotto { generateLottoNumbers(lottoCount) { for (let i = 0; i < lottoCount; i += 1) { const lottoNumber = Random.pickUniqueNumbersInRange(1, 45, 6); - this.lottoNumbersArray.push(lottoNumber); + this.sortLottoNumbers(lottoNumber); } } + sortLottoNumbers(lottoNumber) { + this.lottoNumbersArray.push(lottoNumber.sort((num1, num2) => num1 - num2)); + } + printLottoNumbersArray() { return this.lottoNumbersArray; } From 8038aa718af1f7266bf4435cfdd37ed543630640 Mon Sep 17 00:00:00 2001 From: devGEP Date: Mon, 6 Nov 2023 07:26:01 +0900 Subject: [PATCH 07/17] =?UTF-8?q?feat:=20=EA=B5=AC=EB=A7=A4=ED=95=9C=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=20=EA=B0=9C=EC=88=98=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=ED=95=98=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 --- docs/README.md | 7 +++++-- src/Controller/LottoController.js | 3 +++ src/View/OutputView.js | 10 ++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 src/View/OutputView.js diff --git a/docs/README.md b/docs/README.md index 802b0ba014..9d96b502f5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -91,7 +91,7 @@ checkWinning
# View -## LottoInputView.js +## InputView.js > **사용자로부터 입력을 받는 부분을 담당**
금액 입력, 당첨 번호 입력 @@ -108,12 +108,15 @@ promptBonusNumber
-## LottoOutputView.js +## OutputView.js > **결과나 메세지를 사용자에게 표시하는 부분을 담당**
로또 번호, 당첨 결과, 수익률 등을 사용자에게 표시하는 함수들을 관리
+printLottoCounts +- [x] 구매한 로또 개수를 화면에 출력하기 + printLottos - [ ] 구매한 로또 번호를 화면에 출력하기 diff --git a/src/Controller/LottoController.js b/src/Controller/LottoController.js index 7eb0d3f4d9..3455f3fd32 100644 --- a/src/Controller/LottoController.js +++ b/src/Controller/LottoController.js @@ -1,4 +1,5 @@ import InputView from "../View/InputView.js"; +import OutputView from "../View/OutputView.js"; import LottoMachine from "../Model/LottoMachine.js"; import Lotto from "../Lotto.js"; import { Console } from '@woowacourse/mission-utils'; @@ -7,12 +8,14 @@ class LottoController { constructor() { this.lotto = new Lotto(); this.inputView = new InputView(); + this.outputView = new OutputView(); this.lottoMachine = new LottoMachine(); } async handlePurchase() { const purchaseAmount = await this.inputView.promptPurchaseAmount(); const numberOfLottos = this.lottoMachine.calculateLottoCount(purchaseAmount); + this.outputView.printLottoCounts(numberOfLottos); this.lotto.generateLottoNumbers(numberOfLottos); const lottoNumbersArray = this.lotto.printLottoNumbersArray(); diff --git a/src/View/OutputView.js b/src/View/OutputView.js new file mode 100644 index 0000000000..5a4ae5b61c --- /dev/null +++ b/src/View/OutputView.js @@ -0,0 +1,10 @@ +import { Console } from '@woowacourse/mission-utils'; +import { GAME_MESSAGES } from '../utils/Constants.js'; + +class OutputView { + printLottoCounts(lottoCounts) { + Console.print(lottoCounts + GAME_MESSAGES.CONFIRM_PURCHASED_LOTTOS_AMOUNT); + } +} + +export default OutputView; \ No newline at end of file From 4002f5eabd03dbe297899c7aac3232b258ccea91 Mon Sep 17 00:00:00 2001 From: devGEP Date: Mon, 6 Nov 2023 07:27:11 +0900 Subject: [PATCH 08/17] =?UTF-8?q?feat:=20=EA=B5=AC=EB=A7=A4=ED=95=9C=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=20=EB=B2=88=ED=98=B8=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EC=97=90=20=EC=B6=9C=EB=A0=A5=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 --- docs/README.md | 2 +- src/Controller/LottoController.js | 2 +- src/View/OutputView.js | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 9d96b502f5..96b29c514d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -118,7 +118,7 @@ printLottoCounts - [x] 구매한 로또 개수를 화면에 출력하기 printLottos -- [ ] 구매한 로또 번호를 화면에 출력하기 +- [x] 구매한 로또 번호를 화면에 출력하기 printLottoResult - [ ] 당첨 결과를 화면에 출력하기 diff --git a/src/Controller/LottoController.js b/src/Controller/LottoController.js index 3455f3fd32..361292ab17 100644 --- a/src/Controller/LottoController.js +++ b/src/Controller/LottoController.js @@ -19,7 +19,7 @@ class LottoController { this.lotto.generateLottoNumbers(numberOfLottos); const lottoNumbersArray = this.lotto.printLottoNumbersArray(); - Console.print(lottoNumbersArray); + this.outputView.printLottos(lottoNumbersArray); } } diff --git a/src/View/OutputView.js b/src/View/OutputView.js index 5a4ae5b61c..db440d2361 100644 --- a/src/View/OutputView.js +++ b/src/View/OutputView.js @@ -5,6 +5,12 @@ class OutputView { printLottoCounts(lottoCounts) { Console.print(lottoCounts + GAME_MESSAGES.CONFIRM_PURCHASED_LOTTOS_AMOUNT); } + + printLottos(lottos) { + lottos.map((lotto, _) => { + Console.print(lotto); + }) + } } export default OutputView; \ No newline at end of file From fc7cfb1bbb2074795f7c899d0fc27d1552eb8f5d Mon Sep 17 00:00:00 2001 From: devGEP Date: Mon, 6 Nov 2023 07:33:20 +0900 Subject: [PATCH 09/17] =?UTF-8?q?fix:=20=ED=95=98=EB=82=98=EC=9D=98=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EA=B0=80=20=ED=95=98=EB=82=98?= =?UTF-8?q?=EC=9D=98=20=EA=B8=B0=EB=8A=A5=EC=9D=84=20=ED=95=98=EA=B2=8C?= =?UTF-8?q?=EB=81=94=20=EB=A1=9C=EC=A7=81=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LottoController.js에서 handlerPurchase() 메서드가 로또 번호 6개 무작위 생성 로직을 포함하고 있어 이를 App.js에 분리 --- docs/README.md | 3 --- src/App.js | 5 ++++- src/Controller/LottoController.js | 5 +---- src/Lotto.js | 6 ++---- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/docs/README.md b/docs/README.md index 96b29c514d..674c593a3b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -50,9 +50,6 @@ generateLottoNumbers sortLottoNumbers - [x] 로또 번호를 오름차순으로 정렬 -printLottoNumbersArray -- [x] 로또 번호들의 값을 넘김 -
## LottoMachine.js diff --git a/src/App.js b/src/App.js index 1463cbcf67..cdc436a977 100644 --- a/src/App.js +++ b/src/App.js @@ -10,8 +10,11 @@ class App { } async startLotto() { - this.lottoController.handlePurchase(); + const numberOfLottos = this.lottoController.handlePurchase(); + this.outputView.printLottoCounts(numberOfLottos); + const lottoNumbersArray = this.lotto.generateLottoNumbers(numberOfLottos); + this.outputView.printLottos(lottoNumbersArray); } } diff --git a/src/Controller/LottoController.js b/src/Controller/LottoController.js index 361292ab17..d90cda7df6 100644 --- a/src/Controller/LottoController.js +++ b/src/Controller/LottoController.js @@ -15,11 +15,8 @@ class LottoController { async handlePurchase() { const purchaseAmount = await this.inputView.promptPurchaseAmount(); const numberOfLottos = this.lottoMachine.calculateLottoCount(purchaseAmount); - this.outputView.printLottoCounts(numberOfLottos); - this.lotto.generateLottoNumbers(numberOfLottos); - const lottoNumbersArray = this.lotto.printLottoNumbersArray(); - this.outputView.printLottos(lottoNumbersArray); + return numberOfLottos; } } diff --git a/src/Lotto.js b/src/Lotto.js index ebdeb46d71..70b3581b43 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -14,16 +14,14 @@ class Lotto { const lottoNumber = Random.pickUniqueNumbersInRange(1, 45, 6); this.sortLottoNumbers(lottoNumber); } + + return this.lottoNumbersArray; } sortLottoNumbers(lottoNumber) { this.lottoNumbersArray.push(lottoNumber.sort((num1, num2) => num1 - num2)); } - printLottoNumbersArray() { - return this.lottoNumbersArray; - } - #validate(numbers) { if (numbers && numbers.length !== 6) { throw new Error("[ERROR] 로또 번호는 6개여야 합니다."); From 627af532dc303fb406982e23d41b218c511b53ea Mon Sep 17 00:00:00 2001 From: devGEP Date: Wed, 8 Nov 2023 17:28:05 +0900 Subject: [PATCH 10/17] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=9E=85=EB=A0=A5=EB=B0=9B=EA=B8=B0=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 --- docs/README.md | 59 +++++++++++++------------------ src/App.js | 14 ++++++-- src/Controller/LottoController.js | 10 +++--- src/Model/LottoMachine.js | 6 ++++ src/View/InputView.js | 10 ++++-- src/View/OutputView.js | 8 +++-- 6 files changed, 62 insertions(+), 45 deletions(-) diff --git a/docs/README.md b/docs/README.md index 674c593a3b..433c48cbf8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,10 +28,11 @@
handlePurchase -- [ ] 로또 구매를 처리 +- [x] 로또 구매를 처리 -LottoWinningInputHandler -- [ ] 당첨 번호 입력을 처리 +handleLottoWinningNumbers +- [x] 당첨 번호 입력을 처리 +- [x] 보너스 당첨 번호 입력을 처리 calculateProfitRates - [ ] 수익률을 계산 @@ -60,8 +61,8 @@ sortLottoNumbers calculateLottoCount - [x] 지불한 금액으로 구매할 수 있는 로또의 수를 계산 -printLottos -- [ ] 구매한 로또의 번호를 출력 +printLottoNumbers +- [x] 구매한 로또의 번호를 출력
@@ -78,9 +79,16 @@ setBonumsNumbers validateNumbers - [ ] 당첨 번호의 유효성을 검사 +- 예외 처리 + - [ ] 숫자의 개수가 6개인지 확인 + - [ ] 각 숫자가 로또 번호로서 1~45 범위 내에 있는지 확인 + - [ ] 숫자들에 중복이 없는지 확인 validateBonusNumbers - [ ] 보너스 당첨 번호의 유효성을 검사 +- 예외 처리 + - [ ] 숫자가 로또 번호로서 1~45 범위 내에 있는지 확인 + - [ ] 당첨 번호들과 중복되지 않아야 한다. checkWinning - [ ] 주어진 로또 번호가 당첨 번호와 일치하는지 확인 @@ -113,15 +121,26 @@ promptBonusNumber printLottoCounts - [x] 구매한 로또 개수를 화면에 출력하기 +- `${lottoCount}개를 구매했습니다.` printLottos - [x] 구매한 로또 번호를 화면에 출력하기 +- `[8, 21, 23, 41, 42, 43]`
+ `[3, 5, 11, 16, 32, 38]` ... printLottoResult - [ ] 당첨 결과를 화면에 출력하기 +- `당첨 통계`
+ `---`
+ `3개 일치 (5,000원) - 1개`
+ `4개 일치 (50,000원) - 0개`
+ `5개 일치 (1,500,000원) - 0개`
+ `5개 일치, 보너스 볼 일치 (30,000,000원) - 0개`
+ `6개 일치 (2,000,000,000원) - 0개`
printProfitRates - [ ] 수익률을 화면에 출력하기 +- `총 수익률은 ${winningRates}%입니다.`
@@ -153,35 +172,5 @@ getLottoBonusWinningNumber
-## OutputHandler.js -> 사용자에게 정보를 출력하는 함수들을 관리 - -
- -printPurchaseCount -- [ ] 몇개를 구입했는지 출력 -- `${lottoCount}개를 구매했습니다.` - -printLottoNumber -- [ ] 사용자가 구입한 로또 번호 출력 -- `[8, 21, 23, 41, 42, 43]`
- `[3, 5, 11, 16, 32, 38]` ... - -announceWinningNumber -- [ ] 당첨 통계 -- `당첨 통계`
- `---`
- `3개 일치 (5,000원) - 1개`
- `4개 일치 (50,000원) - 0개`
- `5개 일치 (1,500,000원) - 0개`
- `5개 일치, 보너스 볼 일치 (30,000,000원) - 0개`
- `6개 일치 (2,000,000,000원) - 0개`
- -printWinningRates -- [ ] 총 수익률 출력 -- `총 수익률은 ${winningRates}%입니다.` - -
- ## ErrorHandler.js > 예외 처리와 관련된 함수나 로직을 관리 \ No newline at end of file diff --git a/src/App.js b/src/App.js index cdc436a977..1aafede7b4 100644 --- a/src/App.js +++ b/src/App.js @@ -1,7 +1,14 @@ +import Lotto from "./Lotto.js"; +import OutputView from "./View/OutputView.js"; import LottoController from "./Controller/LottoController.js"; +import LottoMachine from "./Model/LottoMachine.js"; +import { Console } from '@woowacourse/mission-utils'; class App { constructor() { + this.lotto = new Lotto(); + this.outputView = new OutputView(); + this.lottoMachine = new LottoMachine(); this.lottoController = new LottoController(); } @@ -10,11 +17,14 @@ class App { } async startLotto() { - const numberOfLottos = this.lottoController.handlePurchase(); + const numberOfLottos = await this.lottoController.handlePurchase(); this.outputView.printLottoCounts(numberOfLottos); const lottoNumbersArray = this.lotto.generateLottoNumbers(numberOfLottos); - this.outputView.printLottos(lottoNumbersArray); + this.outputView.printLottoNumbers(lottoNumbersArray); + + const winningNumbers = await this.lottoController.handleLottoWinningNumbers(); + Console.print(winningNumbers) } } diff --git a/src/Controller/LottoController.js b/src/Controller/LottoController.js index d90cda7df6..d72e662d80 100644 --- a/src/Controller/LottoController.js +++ b/src/Controller/LottoController.js @@ -1,14 +1,10 @@ import InputView from "../View/InputView.js"; -import OutputView from "../View/OutputView.js"; import LottoMachine from "../Model/LottoMachine.js"; -import Lotto from "../Lotto.js"; import { Console } from '@woowacourse/mission-utils'; class LottoController { constructor() { - this.lotto = new Lotto(); this.inputView = new InputView(); - this.outputView = new OutputView(); this.lottoMachine = new LottoMachine(); } @@ -18,6 +14,12 @@ class LottoController { return numberOfLottos; } + + async handleLottoWinningNumbers() { + const winningNumbers = await this.inputView.promptWinningNumbers(); + + return winningNumbers; + } } export default LottoController; \ No newline at end of file diff --git a/src/Model/LottoMachine.js b/src/Model/LottoMachine.js index 9b5601e324..0df4f33566 100644 --- a/src/Model/LottoMachine.js +++ b/src/Model/LottoMachine.js @@ -1,4 +1,10 @@ +import OutputView from "../View/OutputView.js"; + class LottoMachine { + constructor() { + this.outputView = new OutputView(); + } + calculateLottoCount(amount) { return Math.floor(amount / 1000); } diff --git a/src/View/InputView.js b/src/View/InputView.js index d8c9dc2f9b..0ae1982d63 100644 --- a/src/View/InputView.js +++ b/src/View/InputView.js @@ -7,9 +7,15 @@ class InputView { } async promptPurchaseAmount() { - const money = await this.getUserInput(GAME_MESSAGES.ENTER_PURCHASE_AMOUNT); + const purchaseAmount = await this.getUserInput(GAME_MESSAGES.ENTER_PURCHASE_AMOUNT); // validation 처리할 예정 - return money; + return purchaseAmount; + } + + async promptWinningNumbers() { + const winningNumbers = await this.getUserInput(GAME_MESSAGES.ENTER_WINNING_NUMBERS); + //validation 처리할 예정 + return winningNumbers; } } diff --git a/src/View/OutputView.js b/src/View/OutputView.js index db440d2361..f168dfcb3f 100644 --- a/src/View/OutputView.js +++ b/src/View/OutputView.js @@ -2,14 +2,18 @@ import { Console } from '@woowacourse/mission-utils'; import { GAME_MESSAGES } from '../utils/Constants.js'; class OutputView { + constructor() {} + printLottoCounts(lottoCounts) { Console.print(lottoCounts + GAME_MESSAGES.CONFIRM_PURCHASED_LOTTOS_AMOUNT); + Console.print(''); } - printLottos(lottos) { - lottos.map((lotto, _) => { + printLottoNumbers(lottos) { + lottos.map((lotto, _) => { Console.print(lotto); }) + Console.print(''); } } From 710f12f2d73fa25c05643e2140dde2d188af280b Mon Sep 17 00:00:00 2001 From: devGEP Date: Wed, 8 Nov 2023 17:39:51 +0900 Subject: [PATCH 11/17] =?UTF-8?q?feat:=20=EB=B3=B4=EB=84=88=EC=8A=A4=20?= =?UTF-8?q?=EB=8B=B9=EC=B2=A8=20=EB=B2=88=ED=98=B8=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EB=B0=9B=EA=B8=B0=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 | 27 +++++---------------------- src/Controller/LottoController.js | 5 +++-- src/View/InputView.js | 9 ++++++++- 3 files changed, 16 insertions(+), 25 deletions(-) diff --git a/docs/README.md b/docs/README.md index 433c48cbf8..151e8b88a8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -61,9 +61,6 @@ sortLottoNumbers calculateLottoCount - [x] 지불한 금액으로 구매할 수 있는 로또의 수를 계산 -printLottoNumbers -- [x] 구매한 로또의 번호를 출력 -
## WinningLotto.js @@ -104,12 +101,15 @@ checkWinning promptPurchaseAmount - [x] 사용자에게 구입 금액을 입력받기 +- `구입금액을 입력해 주세요.` promptWinnningNumbers -- [ ] 사용자에게 당첨 번호를 입력받기 +- [x] 사용자에게 당첨 번호(배열)를 입력받기 +- `당첨 번호를 입력해 주세요.` promptBonusNumber -- [ ] 사용자에게 보너스 번호를 입력받기 +- [x] 사용자에게 보너스 번호(숫자)를 입력받기 +- `보너스 번호를 입력해 주세요.`
@@ -150,23 +150,6 @@ printProfitRates
-## InputHandler.js -> 사용자로부터의 입력을 받고 검증하는 함수들을 관리 - -getPurchaseAmount -- [ ] 로또를 구입하기 위해 지불할 금액 입력받기 -- `구입금액을 입력해 주세요.` - -getLottoWinningNumber -- [ ] 당첨 번호 입력 (배열) -- `당첨 번호를 입력해 주세요.` - -getLottoBonusWinningNumber -- [ ] 보너스 번호 입력 (숫자) -- `보너스 번호를 입력해 주세요.` - -
- ## InputValidator.js > 입력값이 유효한지 검사하는 로직을 관리 diff --git a/src/Controller/LottoController.js b/src/Controller/LottoController.js index d72e662d80..c3445780a0 100644 --- a/src/Controller/LottoController.js +++ b/src/Controller/LottoController.js @@ -17,8 +17,9 @@ class LottoController { async handleLottoWinningNumbers() { const winningNumbers = await this.inputView.promptWinningNumbers(); - - return winningNumbers; + const bonusNumbers = await this.inputView.promptBonusNumber(); + + return [winningNumbers, bonusNumbers]; } } diff --git a/src/View/InputView.js b/src/View/InputView.js index 0ae1982d63..ce0baee80a 100644 --- a/src/View/InputView.js +++ b/src/View/InputView.js @@ -14,8 +14,15 @@ class InputView { async promptWinningNumbers() { const winningNumbers = await this.getUserInput(GAME_MESSAGES.ENTER_WINNING_NUMBERS); + const winningNumbersArray = winningNumbers.split(',').map((number) => number.trim()); //validation 처리할 예정 - return winningNumbers; + return winningNumbersArray; + } + + async promptBonusNumber() { + const bonusNumber = await this.getUserInput(GAME_MESSAGES.ENTER_BONUS_NUMBER); + //validation 처리할 예정 + return bonusNumber; } } From 6fa84cfabb1fe40a08ca10f46fea710d1ca59c9f Mon Sep 17 00:00:00 2001 From: devGEP Date: Wed, 8 Nov 2023 20:04:25 +0900 Subject: [PATCH 12/17] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=EB=A5=BC=20=ED=99=94=EB=A9=B4=EC=97=90=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=ED=95=98=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 21 ++++++++++------ src/App.js | 9 ++++++- src/Lotto.js | 2 ++ src/Model/WinningLotto.js | 53 +++++++++++++++++++++++++++++++++++++++ src/View/InputView.js | 5 ++-- src/View/OutputView.js | 12 ++++++++- src/utils/Constants.js | 19 ++++++++++++++ 7 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 src/Model/WinningLotto.js diff --git a/docs/README.md b/docs/README.md index 151e8b88a8..0d404a3053 100644 --- a/docs/README.md +++ b/docs/README.md @@ -68,11 +68,20 @@ calculateLottoCount
-setWinningNumbers -- [ ] 당첨 번호를 설정 +calculateNumberOfMatchingNumbers +- [x] -setBonumsNumbers -- [ ] 보너스 당첨 번호를 설정 +isBonusNumberMatched +- [x] + +determinePrizeCategory +- [x] + +countAndPrintResult +- [x] + +checkWinning +- [x] 주어진 로또 번호가 당첨 번호와 일치하는지 확인 validateNumbers - [ ] 당첨 번호의 유효성을 검사 @@ -87,8 +96,6 @@ validateBonusNumbers - [ ] 숫자가 로또 번호로서 1~45 범위 내에 있는지 확인 - [ ] 당첨 번호들과 중복되지 않아야 한다. -checkWinning -- [ ] 주어진 로또 번호가 당첨 번호와 일치하는지 확인
@@ -129,7 +136,7 @@ printLottos `[3, 5, 11, 16, 32, 38]` ... printLottoResult -- [ ] 당첨 결과를 화면에 출력하기 +- [x] 당첨 결과를 화면에 출력하기 - `당첨 통계`
`---`
`3개 일치 (5,000원) - 1개`
diff --git a/src/App.js b/src/App.js index 1aafede7b4..13b1096e26 100644 --- a/src/App.js +++ b/src/App.js @@ -2,6 +2,7 @@ import Lotto from "./Lotto.js"; import OutputView from "./View/OutputView.js"; import LottoController from "./Controller/LottoController.js"; import LottoMachine from "./Model/LottoMachine.js"; +import WinningLotto from "./Model/WinningLotto.js"; import { Console } from '@woowacourse/mission-utils'; class App { @@ -9,6 +10,7 @@ class App { this.lotto = new Lotto(); this.outputView = new OutputView(); this.lottoMachine = new LottoMachine(); + this.winningLotto = new WinningLotto(); this.lottoController = new LottoController(); } @@ -24,7 +26,12 @@ class App { this.outputView.printLottoNumbers(lottoNumbersArray); const winningNumbers = await this.lottoController.handleLottoWinningNumbers(); - Console.print(winningNumbers) + + const lottoResult = lottoNumbersArray.map(lottoNumbers => { + return this.winningLotto.checkWinning(lottoNumbers, winningNumbers); + }) + + this.winningLotto.countAndPrintResult(lottoResult); } } diff --git a/src/Lotto.js b/src/Lotto.js index 70b3581b43..9b5af4dace 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -13,6 +13,8 @@ class Lotto { for (let i = 0; i < lottoCount; i += 1) { const lottoNumber = Random.pickUniqueNumbersInRange(1, 45, 6); this.sortLottoNumbers(lottoNumber); + + // this.lottoNumbersArray.push(lottoNumber); } return this.lottoNumbersArray; diff --git a/src/Model/WinningLotto.js b/src/Model/WinningLotto.js new file mode 100644 index 0000000000..daba0164de --- /dev/null +++ b/src/Model/WinningLotto.js @@ -0,0 +1,53 @@ +import OutputView from "../View/OutputView.js"; + +class WinningLotto { + constructor() { + this.outputView = new OutputView(); + } + + calculateNumberOfMatchingNumbers(lottoNumbers, winningNumbers) { + return lottoNumbers.filter((number) => winningNumbers.includes(number)).length; + } + + isBonusNumberMatched(lottoNumbers, bonusNumber) { + return lottoNumbers.includes(bonusNumber); + } + + determinePrizeCategory(matchCount, isBonusMatched) { + if (matchCount === 6) return 1; + if (matchCount === 5 && isBonusMatched) return 2; + if (matchCount === 5) return 3; + if (matchCount === 4) return 4; + if (matchCount === 3) return 5; + + return 0; + } + + checkWinning(lottoNumbers, winningNumbers) { + const winningNums = winningNumbers[0].map(Number); + const bonusNum = Number(winningNumbers[1]); + + const matchCount = this.calculateNumberOfMatchingNumbers(lottoNumbers, winningNums); + const isBonusMatched = this.isBonusNumberMatched(lottoNumbers, bonusNum); + + return this.determinePrizeCategory(matchCount, isBonusMatched); + } + + countAndPrintResult(lottoResult) { + const counts = {}; + + for (let i = 0; i<=5; i+= 1) { + counts[i] = 0; + } + + lottoResult.forEach(num => { + if (num >= 1 && num <= 5) { + counts[num] += 1; + } + }); + + this.outputView.printWinningResult(counts); + } +} + +export default WinningLotto; \ No newline at end of file diff --git a/src/View/InputView.js b/src/View/InputView.js index ce0baee80a..e43132b4fd 100644 --- a/src/View/InputView.js +++ b/src/View/InputView.js @@ -2,6 +2,7 @@ import { Console } from '@woowacourse/mission-utils'; import { GAME_MESSAGES } from '../utils/Constants.js'; class InputView { + constructor() {} async getUserInput(question) { return await Console.readLineAsync(question); } @@ -15,13 +16,13 @@ class InputView { async promptWinningNumbers() { const winningNumbers = await this.getUserInput(GAME_MESSAGES.ENTER_WINNING_NUMBERS); const winningNumbersArray = winningNumbers.split(',').map((number) => number.trim()); - //validation 처리할 예정 + return winningNumbersArray; } async promptBonusNumber() { const bonusNumber = await this.getUserInput(GAME_MESSAGES.ENTER_BONUS_NUMBER); - //validation 처리할 예정 + return bonusNumber; } } diff --git a/src/View/OutputView.js b/src/View/OutputView.js index f168dfcb3f..a255c9bd96 100644 --- a/src/View/OutputView.js +++ b/src/View/OutputView.js @@ -1,5 +1,5 @@ import { Console } from '@woowacourse/mission-utils'; -import { GAME_MESSAGES } from '../utils/Constants.js'; +import { GAME_MESSAGES, RANK_MESSAGES, } from '../utils/Constants.js'; class OutputView { constructor() {} @@ -15,6 +15,16 @@ class OutputView { }) Console.print(''); } + + printWinningResult(counts) { + Console.print(GAME_MESSAGES.STATICS_HEADER); + Console.print(GAME_MESSAGES.DIVIDER); + + for (let rank = 5; rank >= 1; rank -= 1) { + const message = RANK_MESSAGES[rank] + `${counts[rank]}` + GAME_MESSAGES.MESSSAGE_SUFFIX; + Console.print(message); + } + } } export default OutputView; \ No newline at end of file diff --git a/src/utils/Constants.js b/src/utils/Constants.js index cccb2837cf..dc628bd465 100644 --- a/src/utils/Constants.js +++ b/src/utils/Constants.js @@ -3,4 +3,23 @@ export const GAME_MESSAGES = { CONFIRM_PURCHASED_LOTTOS_AMOUNT: "개를 구매했습니다.", ENTER_WINNING_NUMBERS: "당첨 번호를 입력해 주세요. ", ENTER_BONUS_NUMBER: "보너스 번호를 입력해 주세요. ", + STATICS_HEADER: "당첨 통계", + DIVIDER: "---------", + MESSSAGE_SUFFIX: "개" +} + +export const RANK_PRIZE = { + 1: '2,000,000,000원', + 2: '30,000,000원', + 3: '1,500,000원', + 4: '50,000원', + 5: '5,000원', +} + +export const RANK_MESSAGES = { + 1: `6개 일치 (${RANK_PRIZE[1]}) - `, + 2: `5개 일치 + 보너스볼 (${RANK_PRIZE[2]}) - `, + 3: `5개 일치 (${RANK_PRIZE[3]}) - `, + 4: `4개 일치 (${RANK_PRIZE[4]}) - `, + 5: `3개 일치 (${RANK_PRIZE[5]}) - `, } From 9e195aa9e64f3b957aba7f17178d57b364c9f5eb Mon Sep 17 00:00:00 2001 From: devGEP Date: Wed, 8 Nov 2023 20:08:21 +0900 Subject: [PATCH 13/17] =?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=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WinningLotto 수정 --- docs/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index 0d404a3053..3912149280 100644 --- a/docs/README.md +++ b/docs/README.md @@ -69,16 +69,16 @@ calculateLottoCount
calculateNumberOfMatchingNumbers -- [x] +- [x] 로또에 있는 번호 중 당첨 번호와 일치하는 개수를 계산 isBonusNumberMatched -- [x] +- [x] 보너스 번호가 로또 번호에 포함되어 있는지 확인 determinePrizeCategory -- [x] +- [x] 일치하는 번호의 개수와 보너스 번호의 존재 여부에 따라 상금 등급을 결정 countAndPrintResult -- [x] +- [x] 상금 등급에 따라 화면에 출력하도록 함 checkWinning - [x] 주어진 로또 번호가 당첨 번호와 일치하는지 확인 From 942f048c5b6575386faac0c28330cd23ade85096 Mon Sep 17 00:00:00 2001 From: devGEP Date: Wed, 8 Nov 2023 21:04:44 +0900 Subject: [PATCH 14/17] =?UTF-8?q?feat:=20=EC=88=98=EC=9D=B5=EB=A5=A0=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=ED=95=B4=EC=84=9C=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=ED=95=98=EA=B8=B0=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 | 4 ++-- src/App.js | 7 +++++-- src/Controller/LottoController.js | 25 ++++++++++++++++++++++--- src/{ => Model}/Lotto.js | 10 ++++------ src/Model/WinningLotto.js | 2 ++ src/View/OutputView.js | 10 +++++++--- src/utils/Constants.js | 1 + 7 files changed, 43 insertions(+), 16 deletions(-) rename src/{ => Model}/Lotto.js (64%) diff --git a/docs/README.md b/docs/README.md index 3912149280..f380f1a1a4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -35,7 +35,7 @@ handleLottoWinningNumbers - [x] 보너스 당첨 번호 입력을 처리 calculateProfitRates -- [ ] 수익률을 계산 +- [x] 수익률을 계산
@@ -146,7 +146,7 @@ printLottoResult `6개 일치 (2,000,000,000원) - 0개`
printProfitRates -- [ ] 수익률을 화면에 출력하기 +- [x] 수익률을 화면에 출력하기 - `총 수익률은 ${winningRates}%입니다.`
diff --git a/src/App.js b/src/App.js index 13b1096e26..b34b8e78d5 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,4 @@ -import Lotto from "./Lotto.js"; +import Lotto from "./Model/Lotto.js"; import OutputView from "./View/OutputView.js"; import LottoController from "./Controller/LottoController.js"; import LottoMachine from "./Model/LottoMachine.js"; @@ -31,7 +31,10 @@ class App { return this.winningLotto.checkWinning(lottoNumbers, winningNumbers); }) - this.winningLotto.countAndPrintResult(lottoResult); + const lottoWinningResult = this.winningLotto.countAndPrintResult(lottoResult); + + const profitRates = this.lottoController.calculateProfitRates(lottoWinningResult); + this.outputView.printProfitRates(profitRates.toFixed(1)); } } diff --git a/src/Controller/LottoController.js b/src/Controller/LottoController.js index c3445780a0..59cd893e75 100644 --- a/src/Controller/LottoController.js +++ b/src/Controller/LottoController.js @@ -1,16 +1,17 @@ import InputView from "../View/InputView.js"; import LottoMachine from "../Model/LottoMachine.js"; -import { Console } from '@woowacourse/mission-utils'; +import { RANK_PRIZE } from "../utils/Constants.js"; class LottoController { constructor() { + this.purchaseAmount = 0; this.inputView = new InputView(); this.lottoMachine = new LottoMachine(); } async handlePurchase() { - const purchaseAmount = await this.inputView.promptPurchaseAmount(); - const numberOfLottos = this.lottoMachine.calculateLottoCount(purchaseAmount); + this.purchaseAmount = await this.inputView.promptPurchaseAmount(); + const numberOfLottos = this.lottoMachine.calculateLottoCount(this.purchaseAmount); return numberOfLottos; } @@ -21,6 +22,24 @@ class LottoController { return [winningNumbers, bonusNumbers]; } + + convertPrizeToNumber(prize) { + return parseInt(prize.replace(/[^0-9]/g, '')); + } + + calculateTotalPrize(lottoResult) { + return lottoResult.reduce((total, count, rank) => { + if (rank === 0 || !RANK_PRIZE[rank]) return total; + + const prize = this.convertPrizeToNumber(RANK_PRIZE[rank]); + return total + (prize * count); + }, 0); + } + + calculateProfitRates(lottoResult) { + const totalPrize = this.calculateTotalPrize(lottoResult); + return (totalPrize / this.purchaseAmount) * 100; + } } export default LottoController; \ No newline at end of file diff --git a/src/Lotto.js b/src/Model/Lotto.js similarity index 64% rename from src/Lotto.js rename to src/Model/Lotto.js index 9b5af4dace..95c65d50ea 100644 --- a/src/Lotto.js +++ b/src/Model/Lotto.js @@ -11,17 +11,15 @@ class Lotto { generateLottoNumbers(lottoCount) { for (let i = 0; i < lottoCount; i += 1) { - const lottoNumber = Random.pickUniqueNumbersInRange(1, 45, 6); - this.sortLottoNumbers(lottoNumber); - - // this.lottoNumbersArray.push(lottoNumber); + this.#numbers = Random.pickUniqueNumbersInRange(1, 45, 6); + this.sortLottoNumbers(); } return this.lottoNumbersArray; } - sortLottoNumbers(lottoNumber) { - this.lottoNumbersArray.push(lottoNumber.sort((num1, num2) => num1 - num2)); + sortLottoNumbers() { + this.lottoNumbersArray.push(this.#numbers.sort((num1, num2) => num1 - num2)); } #validate(numbers) { diff --git a/src/Model/WinningLotto.js b/src/Model/WinningLotto.js index daba0164de..ca3ef84597 100644 --- a/src/Model/WinningLotto.js +++ b/src/Model/WinningLotto.js @@ -47,6 +47,8 @@ class WinningLotto { }); this.outputView.printWinningResult(counts); + + return Object.values(counts); } } diff --git a/src/View/OutputView.js b/src/View/OutputView.js index a255c9bd96..4a09bec568 100644 --- a/src/View/OutputView.js +++ b/src/View/OutputView.js @@ -1,17 +1,17 @@ import { Console } from '@woowacourse/mission-utils'; -import { GAME_MESSAGES, RANK_MESSAGES, } from '../utils/Constants.js'; +import { GAME_MESSAGES, RANK_MESSAGES } from '../utils/Constants.js'; class OutputView { constructor() {} printLottoCounts(lottoCounts) { Console.print(lottoCounts + GAME_MESSAGES.CONFIRM_PURCHASED_LOTTOS_AMOUNT); - Console.print(''); + // Console.print(''); } printLottoNumbers(lottos) { lottos.map((lotto, _) => { - Console.print(lotto); + Console.print(`[${lotto.join(", ")}]`); }) Console.print(''); } @@ -25,6 +25,10 @@ class OutputView { Console.print(message); } } + + printProfitRates(profitRates) { + Console.print(GAME_MESSAGES.TOTAL_PRIZE_RATE(profitRates)); + } } export default OutputView; \ No newline at end of file diff --git a/src/utils/Constants.js b/src/utils/Constants.js index dc628bd465..584be6ade4 100644 --- a/src/utils/Constants.js +++ b/src/utils/Constants.js @@ -3,6 +3,7 @@ export const GAME_MESSAGES = { CONFIRM_PURCHASED_LOTTOS_AMOUNT: "개를 구매했습니다.", ENTER_WINNING_NUMBERS: "당첨 번호를 입력해 주세요. ", ENTER_BONUS_NUMBER: "보너스 번호를 입력해 주세요. ", + TOTAL_PRIZE_RATE: (winningRates) => `총 수익률은 ${winningRates}%입니다.`, STATICS_HEADER: "당첨 통계", DIVIDER: "---------", MESSSAGE_SUFFIX: "개" From f7b5c26e0799fe838cab8faf3f9aa6a301a8abab Mon Sep 17 00:00:00 2001 From: devGEP Date: Wed, 8 Nov 2023 21:28:56 +0900 Subject: [PATCH 15/17] =?UTF-8?q?docs:=20Validation=20=EB=AA=A9=EB=A1=9D?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/README.md b/docs/README.md index f380f1a1a4..186186ba2d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -109,14 +109,28 @@ validateBonusNumbers promptPurchaseAmount - [x] 사용자에게 구입 금액을 입력받기 - `구입금액을 입력해 주세요.` +- 예외처리 + - [ ] 값이 비어있는지 확인 + - [ ] 숫자 형식인지 확인 + - [ ] 1,000원 단위로 입력했는지 확인 promptWinnningNumbers - [x] 사용자에게 당첨 번호(배열)를 입력받기 - `당첨 번호를 입력해 주세요.` +- 예외처리 + - [ ] 값이 비어있는지 확인 + - [ ] 로또 번호 중복되어있는지 확인 + - [ ] 로또 번호 1~45 사이인지 확인 + - [ ] 6개 입력되어있는지 확인 promptBonusNumber - [x] 사용자에게 보너스 번호(숫자)를 입력받기 - `보너스 번호를 입력해 주세요.` +- 예외처리 + - [ ] 값이 비어있는지 확인 + - [ ] 숫자 형식인지 확인 + - [ ] 로또 번호 1~45 사이인지 확인 + - [ ] 로또 번호와 중복되는지 확인
From a2397814bd2ef3d6d4d5381c41e3276717fcf0d1 Mon Sep 17 00:00:00 2001 From: devGEP Date: Wed, 8 Nov 2023 23:50:39 +0900 Subject: [PATCH 16/17] =?UTF-8?q?fix:=20=EC=97=90=EB=9F=AC=20=EB=A9=94?= =?UTF-8?q?=EC=84=B8=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/LottoTest.js | 2 +- src/App.js | 5 +-- src/Model/Lotto.js | 22 +++--------- src/Model/LottoMachine.js | 15 +++++++++ src/View/InputView.js | 51 +++++++++++++++++++++++----- src/utils/Constants.js | 14 +++++++- src/utils/InputValidator.js | 26 ++++++++++++++ src/utils/Validation.js | 67 +++++++++++++++++++++++++++++++++++++ 8 files changed, 170 insertions(+), 32 deletions(-) create mode 100644 src/utils/InputValidator.js create mode 100644 src/utils/Validation.js diff --git a/__tests__/LottoTest.js b/__tests__/LottoTest.js index 97bd457659..ff0ddde87f 100644 --- a/__tests__/LottoTest.js +++ b/__tests__/LottoTest.js @@ -1,4 +1,4 @@ -import Lotto from "../src/Lotto.js"; +import Lotto from "../src/Model/Lotto.js"; describe("로또 클래스 테스트", () => { test("로또 번호의 개수가 6개가 넘어가면 예외가 발생한다.", () => { diff --git a/src/App.js b/src/App.js index b34b8e78d5..8f97e044f6 100644 --- a/src/App.js +++ b/src/App.js @@ -1,13 +1,10 @@ -import Lotto from "./Model/Lotto.js"; import OutputView from "./View/OutputView.js"; import LottoController from "./Controller/LottoController.js"; import LottoMachine from "./Model/LottoMachine.js"; import WinningLotto from "./Model/WinningLotto.js"; -import { Console } from '@woowacourse/mission-utils'; class App { constructor() { - this.lotto = new Lotto(); this.outputView = new OutputView(); this.lottoMachine = new LottoMachine(); this.winningLotto = new WinningLotto(); @@ -22,7 +19,7 @@ class App { const numberOfLottos = await this.lottoController.handlePurchase(); this.outputView.printLottoCounts(numberOfLottos); - const lottoNumbersArray = this.lotto.generateLottoNumbers(numberOfLottos); + const lottoNumbersArray = this.lottoMachine.generateLottoNumbers(numberOfLottos); this.outputView.printLottoNumbers(lottoNumbersArray); const winningNumbers = await this.lottoController.handleLottoWinningNumbers(); diff --git a/src/Model/Lotto.js b/src/Model/Lotto.js index 95c65d50ea..17cd5694c7 100644 --- a/src/Model/Lotto.js +++ b/src/Model/Lotto.js @@ -1,31 +1,19 @@ -import { Random } from '@woowacourse/mission-utils'; +import InputValidator from '../utils/InputValidator.js'; class Lotto { #numbers; constructor(numbers) { - this.lottoNumbersArray = []; this.#validate(numbers); this.#numbers = numbers; } - generateLottoNumbers(lottoCount) { - for (let i = 0; i < lottoCount; i += 1) { - this.#numbers = Random.pickUniqueNumbersInRange(1, 45, 6); - this.sortLottoNumbers(); - } - - return this.lottoNumbersArray; - } - - sortLottoNumbers() { - this.lottoNumbersArray.push(this.#numbers.sort((num1, num2) => num1 - num2)); + #validate(numbers) { + InputValidator.validateLottoWinningNumber(numbers); } - #validate(numbers) { - if (numbers && numbers.length !== 6) { - throw new Error("[ERROR] 로또 번호는 6개여야 합니다."); - } + getLottoNumbers() { + return this.#numbers.sort((num1, num2) => num1 - num2); } } diff --git a/src/Model/LottoMachine.js b/src/Model/LottoMachine.js index 0df4f33566..c18cd9f9c8 100644 --- a/src/Model/LottoMachine.js +++ b/src/Model/LottoMachine.js @@ -1,13 +1,28 @@ +import { Random } from '@woowacourse/mission-utils'; import OutputView from "../View/OutputView.js"; +import Lotto from './Lotto.js'; class LottoMachine { constructor() { + this.lottoNumbersArray = []; this.outputView = new OutputView(); } calculateLottoCount(amount) { return Math.floor(amount / 1000); } + + generateLottoNumbers(lottoCount) { + for (let i = 0; i < lottoCount; i += 1) { + const lottoNumbers = Random.pickUniqueNumbersInRange(1, 45, 6); + const lottos = new Lotto(lottoNumbers); + const lottoSortNumbers = lottos.getLottoNumbers(lottoNumbers); + + this.lottoNumbersArray.push(lottoSortNumbers); + } + + return this.lottoNumbersArray; + } } export default LottoMachine; diff --git a/src/View/InputView.js b/src/View/InputView.js index e43132b4fd..8cf693a51c 100644 --- a/src/View/InputView.js +++ b/src/View/InputView.js @@ -1,29 +1,62 @@ import { Console } from '@woowacourse/mission-utils'; import { GAME_MESSAGES } from '../utils/Constants.js'; +import InputValidator from '../utils/InputValidator.js'; class InputView { - constructor() {} + constructor() { + this.winningNumberArray = []; + } + async getUserInput(question) { return await Console.readLineAsync(question); } async promptPurchaseAmount() { - const purchaseAmount = await this.getUserInput(GAME_MESSAGES.ENTER_PURCHASE_AMOUNT); - // validation 처리할 예정 - return purchaseAmount; + while(true) { + try { + const purchaseAmount = await this.getUserInput(GAME_MESSAGES.ENTER_PURCHASE_AMOUNT); + + const userMoney = Number(purchaseAmount); + console.log('userMoney: ', userMoney); + InputValidator.validatePurchaseAmount(userMoney); + + return userMoney; + } catch(error) { + Console.print(error.message); + } + } } async promptWinningNumbers() { - const winningNumbers = await this.getUserInput(GAME_MESSAGES.ENTER_WINNING_NUMBERS); - const winningNumbersArray = winningNumbers.split(',').map((number) => number.trim()); + while(true) { + try { + const winningNumbers = await this.getUserInput(GAME_MESSAGES.ENTER_WINNING_NUMBERS); + const winningNumbersArray = winningNumbers.split(',').map((number) => number.trim()); + + this.winningNumberArray = winningNumbersArray; - return winningNumbersArray; + InputValidator.validateLottoWinningNumber(winningNumbersArray); + + return winningNumbersArray; + } catch(error) { + Console.print(error); + } + } + } async promptBonusNumber() { - const bonusNumber = await this.getUserInput(GAME_MESSAGES.ENTER_BONUS_NUMBER); + while(true){ + try { + const bonusNumber = await this.getUserInput(GAME_MESSAGES.ENTER_BONUS_NUMBER); + + InputValidator.validateLottoBonusNumber(this.winningNumberArray, Number(bonusNumber)); - return bonusNumber; + return bonusNumber; + } catch(error) { + Console.print(error); + } + } } } diff --git a/src/utils/Constants.js b/src/utils/Constants.js index 584be6ade4..5467e553f3 100644 --- a/src/utils/Constants.js +++ b/src/utils/Constants.js @@ -9,6 +9,17 @@ export const GAME_MESSAGES = { MESSSAGE_SUFFIX: "개" } +export const ERROR_MESSAGES = { + EMPTY_INPUT: '[ERROR] 값이 비어있습니다.', + INVALID_NUMBER_FORMAT: "[ERROR] 숫자 형식이 아닙니다.", + DUPLICATE_LOTTO_NUMBER: "[ERROR] 로또 번호가 중복되면 안됩니다.", + NUMBER_OUT_OF_RANGE: `[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다.`, + BONUS_NUMBER_OUT_OF_RANGE: `[ERROR] 보너스 로또 번호도 1부터 45 사이의 숫자여야 합니다.`, + NUMBER_OUT_OF_RANGE: "[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다.", + LOTTO_NUMBER_OUT_OF_RANGE: "[ERROR] 로또 번호는 6개를 입력해주세요.", + INVAID_PURCHASE_AMOUNT: "[ERROR] 구입 금액은 1,000원 단위로 입력해야 합니다." +} + export const RANK_PRIZE = { 1: '2,000,000,000원', 2: '30,000,000원', @@ -19,8 +30,9 @@ export const RANK_PRIZE = { export const RANK_MESSAGES = { 1: `6개 일치 (${RANK_PRIZE[1]}) - `, - 2: `5개 일치 + 보너스볼 (${RANK_PRIZE[2]}) - `, + 2: `5개 일치, 보너스 볼 일치 (${RANK_PRIZE[2]}) - `, 3: `5개 일치 (${RANK_PRIZE[3]}) - `, 4: `4개 일치 (${RANK_PRIZE[4]}) - `, 5: `3개 일치 (${RANK_PRIZE[5]}) - `, } + diff --git a/src/utils/InputValidator.js b/src/utils/InputValidator.js new file mode 100644 index 0000000000..fc0af22c28 --- /dev/null +++ b/src/utils/InputValidator.js @@ -0,0 +1,26 @@ +import Validation from "./Validation.js"; + +class InputValidator { + static validatePurchaseAmount(amount) { + Validation.validateNumberEmpty(amount); + Validation.validateIsNumber(amount); + Validation.validateInputThousandWonUnit(amount); + } + + static validateLottoWinningNumber(array) { + Validation.validateArrayEmpty(array); + Validation.validateArrayIsNumber(array); + Validation.validateHasDuplicate(array); + Validation.validateArrayOfRange(array); + Validation.validateArrayLength(array); + } + + static validateLottoBonusNumber(array, number) { + Validation.validateNumberEmpty(number); + Validation.validateIsNumber(number); + Validation.validateNumberOfRange(number); + Validation.validateHasDuplicateArrayAndNumber(array, number); + } +} + +export default InputValidator; diff --git a/src/utils/Validation.js b/src/utils/Validation.js new file mode 100644 index 0000000000..8c6a710028 --- /dev/null +++ b/src/utils/Validation.js @@ -0,0 +1,67 @@ +import { ERROR_MESSAGES } from "./Constants.js"; + +class Validation { + static validateArrayEmpty(array) { + if (array.includes('')) { + throw new Error(ERROR_MESSAGES.EMPTY_INPUT); + } + } + + static validateNumberEmpty(input) { + if (input === '') { + throw new Error(ERROR_MESSAGES.EMPTY_INPUT); + } + } + + static validateIsNumber(input) { + if (isNaN(input)) { + throw new Error(ERROR_MESSAGES.INVALID_NUMBER_FORMAT); + } + } + + static validateInputThousandWonUnit(amount) { + if (amount % 1000 !== 0) { + throw new Error(ERROR_MESSAGES.INVAID_PURCHASE_AMOUNT); + } + } + + static validateHasDuplicate(input) { + const uniqueNumbers = new Set(input); + if (uniqueNumbers.size !== input.length) { + throw new Error(ERROR_MESSAGES.DUPLICATE_LOTTO_NUMBER); + } + } + + static validateHasDuplicateArrayAndNumber(array, input) { + if (array.includes(input)) { + throw new Error(ERROR_MESSAGES.DUPLICATE_LOTTO_NUMBER); + } + } + + static validateNumberOfRange(input) { + if (input < 1 || input > 45) { + throw new Error(ERROR_MESSAGES.BONUS_NUMBER_OUT_OF_RANGE); + } + } + + static validateArrayOfRange(array) { + console.log(array); + if (array.some(number => number < 1 || number > 45)) { + throw new Error(ERROR_MESSAGES.NUMBER_OUT_OF_RANGE); + } + } + + static validateArrayIsNumber(array) { + if (array.some(number => isNaN(number))) { + throw new Error(ERROR_MESSAGES.INVALID_NUMBER_FORMAT); + } + } + + static validateArrayLength(array) { + if (array.length !== 6) { + throw new Error(ERROR_MESSAGES.LOTTO_NUMBER_OUT_OF_RANGE); + } + } +} + +export default Validation; From ebc4236229b4e19cf6ef1ceaccbb8e7d30e2480e Mon Sep 17 00:00:00 2001 From: devGEP Date: Wed, 8 Nov 2023 23:56:12 +0900 Subject: [PATCH 17/17] =?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=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 43 ++++++++++++------------------------------- 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/docs/README.md b/docs/README.md index 186186ba2d..c0f3383886 100644 --- a/docs/README.md +++ b/docs/README.md @@ -83,20 +83,6 @@ countAndPrintResult checkWinning - [x] 주어진 로또 번호가 당첨 번호와 일치하는지 확인 -validateNumbers -- [ ] 당첨 번호의 유효성을 검사 -- 예외 처리 - - [ ] 숫자의 개수가 6개인지 확인 - - [ ] 각 숫자가 로또 번호로서 1~45 범위 내에 있는지 확인 - - [ ] 숫자들에 중복이 없는지 확인 - -validateBonusNumbers -- [ ] 보너스 당첨 번호의 유효성을 검사 -- 예외 처리 - - [ ] 숫자가 로또 번호로서 1~45 범위 내에 있는지 확인 - - [ ] 당첨 번호들과 중복되지 않아야 한다. - -
# View @@ -110,27 +96,27 @@ promptPurchaseAmount - [x] 사용자에게 구입 금액을 입력받기 - `구입금액을 입력해 주세요.` - 예외처리 - - [ ] 값이 비어있는지 확인 - - [ ] 숫자 형식인지 확인 - - [ ] 1,000원 단위로 입력했는지 확인 + - [x] 값이 비어있는지 확인 + - [x] 숫자 형식인지 확인 + - [x] 1,000원 단위로 입력했는지 확인 promptWinnningNumbers - [x] 사용자에게 당첨 번호(배열)를 입력받기 - `당첨 번호를 입력해 주세요.` - 예외처리 - - [ ] 값이 비어있는지 확인 - - [ ] 로또 번호 중복되어있는지 확인 - - [ ] 로또 번호 1~45 사이인지 확인 - - [ ] 6개 입력되어있는지 확인 + - [x] 값이 비어있는지 확인 + - [x] 로또 번호 중복되어있는지 확인 + - [x] 로또 번호 1~45 사이인지 확인 + - [x] 6개 입력되어있는지 확인 promptBonusNumber - [x] 사용자에게 보너스 번호(숫자)를 입력받기 - `보너스 번호를 입력해 주세요.` - 예외처리 - - [ ] 값이 비어있는지 확인 - - [ ] 숫자 형식인지 확인 - - [ ] 로또 번호 1~45 사이인지 확인 - - [ ] 로또 번호와 중복되는지 확인 + - [x] 값이 비어있는지 확인 + - [x] 숫자 형식인지 확인 + - [x] 로또 번호 1~45 사이인지 확인 + - [x] 로또 번호와 중복되는지 확인
@@ -172,9 +158,4 @@ printProfitRates
## InputValidator.js -> 입력값이 유효한지 검사하는 로직을 관리 - -
- -## ErrorHandler.js -> 예외 처리와 관련된 함수나 로직을 관리 \ No newline at end of file +> 입력값이 유효한지 검사하는 로직을 관리 \ No newline at end of file