From d6c80f42a2c7d5cfd3727d668d53d73303d2a2d0 Mon Sep 17 00:00:00 2001 From: mbeankong Date: Wed, 8 Nov 2023 23:50:15 +0900 Subject: [PATCH] unfinished --- README.md | 30 ++++++++++++++++++ src/App.js | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/Lotto.js | 16 +++++++++- 3 files changed, 132 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index aff2c46597..e841d7e0fe 100644 --- a/README.md +++ b/README.md @@ -237,3 +237,33 @@ class Lotto { - **Git의 커밋 단위는 앞 단계에서 `docs/README.md`에 정리한 기능 목록 단위**로 추가한다. - [커밋 메시지 컨벤션](https://gist.github.com/stephenparish/9941e89d80e2bc58a153) 가이드를 참고해 커밋 메시지를 작성한다. - 과제 진행 및 제출 방법은 [프리코스 과제 제출](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) 문서를 참고한다. + +# 기능 구현 목록 +< App.js > +- 로또 구입 금액 입력 + * 1장 1000원 +- 로또 수량 + 번호 출력 (오름차순 정렬 [,]) + +- 당첨 번호 6개 입력 (쉼표 기준) +- 보너스 번호 1개 입력 + +- 당첨 내역 출력 (개수까지 / - 개) + * 3개 일치 (5,000원) + * 4개 일치 (50,000원) + * 5개 일치 (1,5000,000원) + * 5개 일치, 보너스 볼 일치 (30,000,000원) + * 6개 일치 (2,000,000,000원) +- 수익률 출력 (소수점 둘째자리 반올림) + +- 예외 + * 로또 구입 금액 1000원 단위 X + * 로또 번호 입력 시 1~45 사이 X + * 로또 번호 입력 시 숫자 X + * 로또 번호 입력 시 중복 + + +- 예외 (번호 유효성 검증) + * 구매 로또 번호 6개 X + * 구매 로또 번호 1~45 사이 X + * 구매 로또 번호 숫자 X + * 구매 로또 번호 중복 \ No newline at end of file diff --git a/src/App.js b/src/App.js index c38b30d5b2..d76f89ace5 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,90 @@ +import { MissionUtils } from "@woowacourse/mission-utils"; +import Lotto from './Lotto.js'; + class App { - async play() {} + async play() { + try { + const purchaseAmount = await MissionUtils.Console.readLineAsync('구입금액을 입력해 주세요.'); + + if (purchaseAmount % 1000 !== 0) { + throw new Error("[Error] 로또는 1000원 단위로 구매해야합니다."); + } + const lottoCount = purchaseAmount / 1000; + MissionUtils.Console.print(lottoCount + '개를 구매했습니다.'); + + const lottos = []; + for (let i = 0; i < lottoCount; i++) { + const lottoNumsbers = MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6); + lottos.push(new Lotto(lottoNumsbers)); + } + lottos.forEach(lotto => { + MissionUtils.Console.print('[' + lotto.getNumbers().join(', ') + ']'); + }); + + const winningNumbers = await MissionUtils.Console.readLineAsync('당첨 번호를 입력해 주세요.'); + const bonusNumber = await MissionUtils.Console.readLineAsync('보너스 번호를 입력해 주세요.'); + + const winningStatistics = this.calculateWinningStatistics(lottos, winningNumbers, bonusNumber); + this.printResult(winningStatistics, lottoCount); + + } catch (error) { + MissionUtils.Console.print(`[ERROR] ${error.message}`); + this.play(); + } + } + + calculateWinningStatistics(lottos, winningNumbers, bonusNumber) { + const winningStatistics = {}; + + for (let i = 1; i <= 5; i++) { + winningStatistics[i] = 0; + } + + lottos.forEach(lotto => { + const numMatchCount = lotto.getNumbers().filter(number => winningNumbers.includes(number)).length; + const bonusMatchStatus = lotto.getNumbers().includes(bonusNumber); + this.setWinningStatistics(winningStatistics, numMatchCount, bonusMatchStatus); + }); + + return winningStatistics; + } + + setWinningStatistics(winningStatistics, numMatchCount, bonusMatchStatus) { + if (numMatchCount === 6) { + winningStatistics[1]++; + } else if (numMatchCount === 5 && bonusMatchStatus) { + winningStatistics[2]++; + } else if (numMatchCount === 5) { + winningStatistics[3]++; + } else if (numMatchCount === 4) { + winningStatistics[4]++; + } else if (numMatchCount === 3) { + winningStatistics[5]++; + } + } + + printResult(winningStatistics, lottoCount) { + const prizeMoney = [2000000000, 30000000, 1500000, 50000, 5000]; + let totalPrize = 0; + + MissionUtils.Console.print('당첨 통계'); + MissionUtils.Console.print('---'); + for (let i = 1; i <= 5; i++) { + totalPrize += winningStatistics[i] * prizeMoney[i]; + } + MissionUtils.Console.print(`3개 일치 (${prizeMoney[4]}원) - ${winningStatistics[5]}개`); + MissionUtils.Console.print(`4개 일치 (${prizeMoney[3]}원) - ${winningStatistics[4]}개`); + MissionUtils.Console.print(`5개 일치 (${prizeMoney[2]}원) - ${winningStatistics[3]}개`); + MissionUtils.Console.print(`5개 일치, 보너스 볼 일치 (${prizeMoney[1]}원) - ${winningStatistics[2]}개`); + MissionUtils.Console.print(`6개 일치 (${prizeMoney[0]}원) - ${winningStatistics[1]}개`); + + const profitRate = ((totalPrize - lottoCount * 1000) / (lottoCount * 1000)) * 100; + MissionUtils.Console.print(`총 수익률은 ${profitRate.toFixed(1)}%입니다.`); + } + + /*numberWithCommas(n) { + return n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); + }*/ } -export default App; +export default App; \ No newline at end of file diff --git a/src/Lotto.js b/src/Lotto.js index cb0b1527e9..251c9cb60e 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -10,9 +10,23 @@ class Lotto { if (numbers.length !== 6) { throw new Error("[ERROR] 로또 번호는 6개여야 합니다."); } + + if (numbers.some(number => typeof number !== "number")) { + throw new Error("[ERROR] 로또 번호는 숫자이어야 합니다."); + } + + if (numbers.some(number => number < 1 || number > 45)) { + throw new Error("[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다."); + } + + if (new Set(numbers).size !== numbers.length) { + throw new Error("[ERROR] 로또 번호에 중복된 숫자가 있습니다."); + } } - // TODO: 추가 기능 구현 + getNumbers() { + return this.#numbers; + } } export default Lotto;