From 3c73d6e2d883620050f1148f9bd780560ad88c91 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Sun, 3 Nov 2024 20:35:16 +0900 Subject: [PATCH 01/35] =?UTF-8?q?docs=20:=20README=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/README.md b/README.md index 15bb106b5..dd09ab36c 100644 --- a/README.md +++ b/README.md @@ -1 +1,121 @@ # javascript-lotto-precourse + +## 기능 요구 사항 + + + 로또 게임 기능을 구현해야 한다. 로또 게임은 아래와 같은 규칙으로 진행된다. + +``` +- 로또 번호의 숫자 범위는 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를 발생시키고 해당 메시지를 출력한 다음 해당 지점부터 다시 입력을 받는다. + ``` + 예시) [ERROR] 숫자가 잘못된 형식입니다. + ``` +
+- - - + +## 입출력 요구 사항 + +### 입력 + +- 로또 구입 금액을 입력 받는다. 구입 금액은 1,000원 단위로 입력 받으며 1,000원으로 나누어 떨어지지 않는 경우 예외 처리한다. + +``` +14000 +``` + +- 당첨 번호를 입력 받는다. 번호는 쉼표(,)를 기준으로 구분한다. + +``` +1,2,3,4,5,6 +``` + +- 보너스 번호를 입력 받는다. + +``` +7 +``` + +### 출력 + +- 발행한 로또 수량 및 번호를 출력한다. 로또 번호는 오름차순으로 정렬하여 보여준다. + +``` +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] +``` + +- 당첨 내역을 출력한다. + +``` +3개 일치 (5,000원) - 1개 +4개 일치 (50,000원) - 0개 +5개 일치 (1,500,000원) - 0개 +5개 일치, 보너스 볼 일치 (30,000,000원) - 0개 +6개 일치 (2,000,000,000원) - 0개 +``` + +- 수익률은 소수점 둘째 자리에서 반올림한다. (ex. 100.0%, 51.5%, 1,000,000.0%) + +``` +총 수익률은 62.5%입니다. +``` + +- 예외 상황 시 에러 문구를 출력해야 한다. 단, 에러 문구는 "[ERROR]"로 시작해야 한다. + +``` +[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다. +``` + +### 실행 결과 예시 + +``` +구입금액을 입력해 주세요. +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%입니다. +``` \ No newline at end of file From 99782a78964a178a0778dbf2faf548515e6740d2 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 01:55:16 +0900 Subject: [PATCH 02/35] =?UTF-8?q?test=20:=20=EB=A1=9C=EB=98=90=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EC=97=90=20=EA=B4=80=ED=95=9C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4=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 - 번호의 범위에 관한 예외 케이스 작성 - 자연수 확인에 관한 예외 케이스 작성 - 문자열로 입력된 경우에 관한 예외 케이스 작성 --- __tests__/LottoTest.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/__tests__/LottoTest.js b/__tests__/LottoTest.js index 409aaf69b..68ffd87f4 100644 --- a/__tests__/LottoTest.js +++ b/__tests__/LottoTest.js @@ -14,5 +14,21 @@ describe("로또 클래스 테스트", () => { }).toThrow("[ERROR]"); }); - // TODO: 추가 기능 구현에 따른 테스트 코드 작성 + test("로또 번호 1~45 범위를 초과하면 예외가 발생한다.", () => { + expect(() => { + new Lotto([1, 2, 3, 4, 5, 46]); + }).toThrow("[ERROR]"); + }); + + test("로또 번호가 자연수가 아니면 예외가 발생한다.", () => { + expect(() => { + new Lotto([1, 2, 3, 4, 5, 6.5]); + }).toThrow("[ERROR]"); + }); + + test("로또 번호가 숫자가 아니면 예외가 발생한다.", () => { + expect(() => { + new Lotto([12, "A", 1, "f", 3, "C"]); + }).toThrow("[ERROR]"); + }); }); From 2c71b49c6d96c904e32bab42f1b469290e84f302 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 01:56:57 +0900 Subject: [PATCH 03/35] =?UTF-8?q?test=20:=20=EB=A1=9C=EB=98=90=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=EA=B0=80=20=EC=9D=8C=EC=88=98=EC=9D=BC=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=EC=9D=98=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/LottoTest.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/__tests__/LottoTest.js b/__tests__/LottoTest.js index 68ffd87f4..eb2341655 100644 --- a/__tests__/LottoTest.js +++ b/__tests__/LottoTest.js @@ -26,6 +26,12 @@ describe("로또 클래스 테스트", () => { }).toThrow("[ERROR]"); }); + test("로또 번호가 음수일 경우 예외가 발생한다.", () => { + expect(() => { + new Lotto([1, -2, 3, -4, 5, -6]); + }).toThrow("[ERROR]"); + }); + test("로또 번호가 숫자가 아니면 예외가 발생한다.", () => { expect(() => { new Lotto([12, "A", 1, "f", 3, "C"]); From 9b1e7e129ee95ad098f11f396796421f0e3b08c3 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 02:11:57 +0900 Subject: [PATCH 04/35] =?UTF-8?q?test=20:=20=EB=B3=B4=EB=84=88=EC=8A=A4=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=EC=97=90=20=EA=B4=80=ED=95=9C=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 보너스 번호가 당첨 번호와 중복될 경우 - 보너스 번호가 범위를 벗어난 경우 --- __tests__/ApplicationTest.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/__tests__/ApplicationTest.js b/__tests__/ApplicationTest.js index 872380c9c..9c4e121f9 100644 --- a/__tests__/ApplicationTest.js +++ b/__tests__/ApplicationTest.js @@ -42,6 +42,24 @@ const runException = async (input) => { expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("[ERROR]")); }; +const runExceptionBonus = async (bonusNumber) => { + // given + const logSpy = getLogSpy(); + + const RANDOM_NUMBERS_TO_END = [1, 2, 3, 4, 5, 6]; + const INPUT_NUMBERS_TO_END = ["1000", "1,2,3,4,5,6", bonusNumber]; + + mockRandoms([RANDOM_NUMBERS_TO_END]); + mockQuestions([INPUT_NUMBERS_TO_END]); + + // when + const app = new App(); + await app.run(); + + // then + expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("[ERROR]")); +} + describe("로또 테스트", () => { beforeEach(() => { jest.restoreAllMocks(); @@ -94,4 +112,12 @@ describe("로또 테스트", () => { test("예외 테스트", async () => { await runException("1000j"); }); + + test("보너스 번호가 당첨 번호와 중복될 경우 예외 처리", async () => { + await runException("3"); + }); + + test("보너스 번호가 1~45 범위를 벗어난 경우 예외 처리", async () => { + await runException("46"); + }); }); From 260e37e05b8772db9ace3a81eb2f43a865190978 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 02:15:45 +0900 Subject: [PATCH 05/35] =?UTF-8?q?feat=20:=20=EC=9E=85=EB=A0=A5=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=EC=97=90=20=EA=B4=80=ED=95=9C=20=EC=83=81?= =?UTF-8?q?=EC=88=98=EA=B0=92=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/constants.js | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/constants/constants.js diff --git a/src/constants/constants.js b/src/constants/constants.js new file mode 100644 index 000000000..84c234f37 --- /dev/null +++ b/src/constants/constants.js @@ -0,0 +1,5 @@ +export const INPUT_MESSAGE = { + inputPurchaseAmount : "구입 금액을 입력해 주세요.\n", + inputWinningNumbers : "\n당첨 번호를 입력해 주세요.\n", + inputBonusNumber : "\n보너스 번호를 입력해 주세요.\n", +}; From 9dfe59b88f6451f63bf5d63e24845d1b65f4111c Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 02:26:06 +0900 Subject: [PATCH 06/35] =?UTF-8?q?feat=20:=20=EC=B6=9C=EB=A0=A5=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=EC=97=90=20=EA=B4=80=ED=95=9C=20=EC=83=81?= =?UTF-8?q?=EC=88=98=EA=B0=92=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/constants.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/constants/constants.js b/src/constants/constants.js index 84c234f37..67b34bfb0 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -3,3 +3,14 @@ export const INPUT_MESSAGE = { inputWinningNumbers : "\n당첨 번호를 입력해 주세요.\n", inputBonusNumber : "\n보너스 번호를 입력해 주세요.\n", }; + +export const OUTPUT_MESSAGE = { + printPurchaseNumber : (count) => `\n${count}개 구매했습니다.`, + printWinningStatistics : "\n당첨 통계\n---", + printFifth : (count) => `3개 일치 (5,000원) - ${count}개`, + printFourth : (count) => `4개 일치 (50,000원) - ${count}개`, + printThird : (count) => `5개 일치 (1,500,000원) - ${count}개`, + printSecond : (count) => `5개 일치, 보너스 볼 일치 (30,000,000원) - ${count}개`, + printFirst : (count) => `6개 일치 (2,000,000,000원) - ${count}개`, + printRateReturn : (rate) => `총 수익률은 ${rate}%입니다.`, +}; \ No newline at end of file From b9a31d5f6a8395d7d9d65c41935b75219524f565 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 02:30:37 +0900 Subject: [PATCH 07/35] =?UTF-8?q?feat=20:=20=EC=97=90=EB=9F=AC=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=EC=97=90=20=EA=B4=80=ED=95=9C=20=EC=83=81?= =?UTF-8?q?=EC=88=98=EA=B0=92=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/constants.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/constants/constants.js b/src/constants/constants.js index 67b34bfb0..6f2f469ed 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -13,4 +13,18 @@ export const OUTPUT_MESSAGE = { printSecond : (count) => `5개 일치, 보너스 볼 일치 (30,000,000원) - ${count}개`, printFirst : (count) => `6개 일치 (2,000,000,000원) - ${count}개`, printRateReturn : (rate) => `총 수익률은 ${rate}%입니다.`, +}; + +const ERROR_PREFIX = "[ERROR]"; + +export const ERROR_MESSAGE = { + purchaseError : `${ERROR_PREFIX} 구입 금액은 1000으로 나누어 떨어지는 수 입니다.`, + purchaseRangeError : `${ERROR_PREFIX} 구입 금액 범위는 양수인 정수입니다.`, + lottoLengthError : `${ERROR_PREFIX} 당첨 번호는 6개여야 합니다.`, + lottoDuplicatedError : `${ERROR_PREFIX} 당첨 번호는 중복될 수 없습니다.`, + lottoRangeError : `${ERROR_PREFIX} 당첨 번호의 범위는 1~45 폐구간 입니다.`, + lottoTypeError : `${ERROR_PREFIX} 당첨 번호는 자연수입니다.`, + bonusDuplicatedError : `${ERROR_PREFIX} 보너스 번호는 당첨 번호와 중복될 수 없습니다.`, + bonusRangeError : `${ERROR_PREFIX} 보너스 번호의 범위는 1~45 폐구간 입니다.`, + bonusTypeError : `${ERROR_PREFIX} 보너스 번호는 자연수입니다.`, }; \ No newline at end of file From 0597843298b03803074f2ff37fb681e273f3f358 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 02:52:42 +0900 Subject: [PATCH 08/35] =?UTF-8?q?feat=20:=20=EC=9E=85=EB=A0=A5=EC=97=90=20?= =?UTF-8?q?=EA=B4=80=ED=95=9C=20InputView=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/InputView.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/view/InputView.js diff --git a/src/view/InputView.js b/src/view/InputView.js new file mode 100644 index 000000000..fa7070378 --- /dev/null +++ b/src/view/InputView.js @@ -0,0 +1,27 @@ +import { Console } from "@woowacourse/mission-utils"; +import { INPUT_MESSAGE } from "../constants/constants"; + +class InputView { + #read + + constructor() { + this.#read = Console.readLineAsync; + } + + async readPurchaseAmount() { + const inputPrice = await this.#read(INPUT_MESSAGE.inputPurchaseAmount); + return inputPrice; + } + + async readWinningLotto() { + const winningNumber = await this.#read(INPUT_MESSAGE.inputWinningNumbers); + return winningNumber; + } + + async readBonusNumber() { + const bonusNumber = await this.#read(INPUT_MESSAGE.inputBonusNumber); + return bonusNumber; + } +} + +export default InputView \ No newline at end of file From bead62044434205d91dfa5b5360e8e9bc0b10316 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 03:14:35 +0900 Subject: [PATCH 09/35] =?UTF-8?q?feat=20:=20=EC=B6=9C=EB=A0=A5=EC=97=90=20?= =?UTF-8?q?=EA=B4=80=ED=95=9C=20OutputView=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/OutputView.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/view/OutputView.js diff --git a/src/view/OutputView.js b/src/view/OutputView.js new file mode 100644 index 000000000..78f8e0675 --- /dev/null +++ b/src/view/OutputView.js @@ -0,0 +1,27 @@ +import { Console } from "@woowacourse/mission-utils"; +import { OUTPUT_MESSAGE } from "../constants/constants"; + + +class OutputView { + #print + + constructor() { + this.#print = Console.print; + } + + printMyLotto(purchaseNumber) { + this.#print(OUTPUT_MESSAGE.printPurchaseNumber(purchaseNumber)); + } + + printResult() { + this.#print(OUTPUT_MESSAGE.printWinningStatistics); + this.#print(OUTPUT_MESSAGE.printFifth(0)); + this.#print(OUTPUT_MESSAGE.printFourth(0)); + this.#print(OUTPUT_MESSAGE.printThird(0)); + this.#print(OUTPUT_MESSAGE.printSecond(0)); + this.#print(OUTPUT_MESSAGE.printFirst(0)); + this.#print(OUTPUT_MESSAGE.printRateReturn(0)); + } +} + +export default OutputView; \ No newline at end of file From 3c5bc9c47afc09ce386c46b04de801e17096ee4a Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 03:23:17 +0900 Subject: [PATCH 10/35] =?UTF-8?q?feat=20:=20Controller=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/Controller.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/controller/Controller.js diff --git a/src/controller/Controller.js b/src/controller/Controller.js new file mode 100644 index 000000000..314c24702 --- /dev/null +++ b/src/controller/Controller.js @@ -0,0 +1,25 @@ +import InputView from "../view/InputView.js"; +import OutputView from "../view/OutputView.js"; + +class Controller { + #inputView; + #outputView; + + constructor() { + this.#inputView = new InputView(); + this.#outputView = new OutputView(); + } + + async run() { + const purchaseNumber = await this.#inputView.readPurchaseAmount(); + + this.#outputView.printMyLotto(0); + + const winningNumber = await this.#inputView.readWinningLotto(); + const bonusNumber = await this.#inputView.readBonusNumber(); + + this.#outputView.printResult(); + } +} + +export default Controller; \ No newline at end of file From ef1bd72bf2a592f838f54ffbcaf234675a7ce1f1 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 03:24:22 +0900 Subject: [PATCH 11/35] =?UTF-8?q?fix=20:=20view=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EB=93=A4=EC=9D=98=20constants=EB=A5=BC=20=EB=B0=9B?= =?UTF-8?q?=EB=8A=94=20=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/InputView.js | 2 +- src/view/OutputView.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/view/InputView.js b/src/view/InputView.js index fa7070378..1b892e7a0 100644 --- a/src/view/InputView.js +++ b/src/view/InputView.js @@ -1,5 +1,5 @@ import { Console } from "@woowacourse/mission-utils"; -import { INPUT_MESSAGE } from "../constants/constants"; +import { INPUT_MESSAGE } from "../constants/constants.js"; class InputView { #read diff --git a/src/view/OutputView.js b/src/view/OutputView.js index 78f8e0675..6550a2933 100644 --- a/src/view/OutputView.js +++ b/src/view/OutputView.js @@ -1,5 +1,5 @@ import { Console } from "@woowacourse/mission-utils"; -import { OUTPUT_MESSAGE } from "../constants/constants"; +import { OUTPUT_MESSAGE } from "../constants/constants.js"; class OutputView { From 1fc69f79835d4cd022ebc49e70c48f61a9d0b5b9 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 03:27:23 +0900 Subject: [PATCH 12/35] =?UTF-8?q?feat=20:=20App=EC=97=90=EC=84=9C=20contro?= =?UTF-8?q?ller=20=EA=B0=9D=EC=B2=B4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index 091aa0a5d..b04f75f57 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,15 @@ +import Controller from "./controller/Controller.js"; + class App { - async run() {} + #controller; + + constructor() { + this.#controller = new Controller(); + } + + async run() { + await this.#controller.run(); + } } export default App; From 412092af5c1ae012ec43de826380c896b9a01ed0 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 03:28:57 +0900 Subject: [PATCH 13/35] =?UTF-8?q?style=20:=20view=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=BD=94=EB=93=9C=EC=9D=98=20=EC=9D=BC=EB=B6=80=20?= =?UTF-8?q?=EC=84=B8=EB=AF=B8=EC=BD=9C=EB=A1=A0=20=EB=88=84=EB=9D=BD=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/InputView.js | 2 +- src/view/OutputView.js | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/view/InputView.js b/src/view/InputView.js index 1b892e7a0..7be94e68c 100644 --- a/src/view/InputView.js +++ b/src/view/InputView.js @@ -2,7 +2,7 @@ import { Console } from "@woowacourse/mission-utils"; import { INPUT_MESSAGE } from "../constants/constants.js"; class InputView { - #read + #read; constructor() { this.#read = Console.readLineAsync; diff --git a/src/view/OutputView.js b/src/view/OutputView.js index 6550a2933..d7b8babe5 100644 --- a/src/view/OutputView.js +++ b/src/view/OutputView.js @@ -1,9 +1,8 @@ import { Console } from "@woowacourse/mission-utils"; import { OUTPUT_MESSAGE } from "../constants/constants.js"; - class OutputView { - #print + #print; constructor() { this.#print = Console.print; From ddf5dcc85d6f2d33c258236eec7dc40b6bd32ae7 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 03:29:52 +0900 Subject: [PATCH 14/35] =?UTF-8?q?style=20:=20InputView=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20export=20=EB=B6=80=EB=B6=84=20=EC=84=B8?= =?UTF-8?q?=EB=AF=B8=EC=BD=9C=EB=A1=A0=20=EB=88=84=EB=9D=BD=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/view/InputView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/InputView.js b/src/view/InputView.js index 7be94e68c..0e93877be 100644 --- a/src/view/InputView.js +++ b/src/view/InputView.js @@ -24,4 +24,4 @@ class InputView { } } -export default InputView \ No newline at end of file +export default InputView; \ No newline at end of file From 89cd36eb79f47c0423f0e5f1c3b240c7c67e0566 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 03:32:47 +0900 Subject: [PATCH 15/35] =?UTF-8?q?style=20:=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EC=83=81=EC=88=98=EA=B0=92=20=EC=9D=BC=EB=B6=80=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/constants/constants.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants/constants.js b/src/constants/constants.js index 6f2f469ed..919eabf91 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -5,7 +5,7 @@ export const INPUT_MESSAGE = { }; export const OUTPUT_MESSAGE = { - printPurchaseNumber : (count) => `\n${count}개 구매했습니다.`, + printPurchaseNumber : (count) => `\n${count}개를 구매했습니다.`, printWinningStatistics : "\n당첨 통계\n---", printFifth : (count) => `3개 일치 (5,000원) - ${count}개`, printFourth : (count) => `4개 일치 (50,000원) - ${count}개`, From afe6e745f63d70af85ff3d9350a926235a343efc Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 03:39:58 +0900 Subject: [PATCH 16/35] =?UTF-8?q?test=20:=20=EB=B3=B4=EB=84=88=EC=8A=A4=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EC=9E=85=EB=A0=A5=20=EB=8B=A8=EC=9C=84=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=B6=80=EB=B6=84=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 잘못된 보너스 번호 입력 시 오류가 발생하고 발생 부분부터 다시 입력되도록 수정 --- __tests__/ApplicationTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tests__/ApplicationTest.js b/__tests__/ApplicationTest.js index 9c4e121f9..a4a35f100 100644 --- a/__tests__/ApplicationTest.js +++ b/__tests__/ApplicationTest.js @@ -47,7 +47,7 @@ const runExceptionBonus = async (bonusNumber) => { const logSpy = getLogSpy(); const RANDOM_NUMBERS_TO_END = [1, 2, 3, 4, 5, 6]; - const INPUT_NUMBERS_TO_END = ["1000", "1,2,3,4,5,6", bonusNumber]; + const INPUT_NUMBERS_TO_END = ["1000", "1,2,3,4,5,6", bonusNumber, "7"]; mockRandoms([RANDOM_NUMBERS_TO_END]); mockQuestions([INPUT_NUMBERS_TO_END]); From 2cfa2ac9981e5f5f21055e274f42073eacc8c6ea Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 03:42:04 +0900 Subject: [PATCH 17/35] =?UTF-8?q?test=20:=20=EB=B3=B4=EB=84=88=EC=8A=A4=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EC=9E=85=EB=A0=A5=20=EB=8B=A8=EC=9C=84=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=B6=80=EB=B6=84=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - runException 함수가 아닌 runExceptionBonus를 테스트 하도록 수정 --- __tests__/ApplicationTest.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__tests__/ApplicationTest.js b/__tests__/ApplicationTest.js index a4a35f100..2c36d2e21 100644 --- a/__tests__/ApplicationTest.js +++ b/__tests__/ApplicationTest.js @@ -114,10 +114,10 @@ describe("로또 테스트", () => { }); test("보너스 번호가 당첨 번호와 중복될 경우 예외 처리", async () => { - await runException("3"); + await runExceptionBonus("3"); }); test("보너스 번호가 1~45 범위를 벗어난 경우 예외 처리", async () => { - await runException("46"); + await runExceptionBonus("46"); }); }); From 86ae67dd7bd8eb63e67b50702c605369567ff26c Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 08:57:49 +0900 Subject: [PATCH 18/35] =?UTF-8?q?feat=20:=20LottoService=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4,=20LottoRepository=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=EC=A1=B0=20=EC=83=9D=EC=84=B1=20=EB=B0=8F?= =?UTF-8?q?=20Lotto=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 로직을 처리할 LottoService 클래스 생성 - 데이터를 저장할 LottoRepository 클래스 생성 - entity를 담당할 Lotto 클래스 파일 위치 변경 --- src/constants/constants.js | 4 +++- src/{ => domain}/Lotto.js | 0 src/domain/LottoRepository.js | 9 +++++++++ src/domain/LottoService.js | 27 +++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) rename src/{ => domain}/Lotto.js (100%) create mode 100644 src/domain/LottoRepository.js create mode 100644 src/domain/LottoService.js diff --git a/src/constants/constants.js b/src/constants/constants.js index 919eabf91..fbedab81f 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -27,4 +27,6 @@ export const ERROR_MESSAGE = { bonusDuplicatedError : `${ERROR_PREFIX} 보너스 번호는 당첨 번호와 중복될 수 없습니다.`, bonusRangeError : `${ERROR_PREFIX} 보너스 번호의 범위는 1~45 폐구간 입니다.`, bonusTypeError : `${ERROR_PREFIX} 보너스 번호는 자연수입니다.`, -}; \ No newline at end of file +}; + +export const LOTTO_PRICE = 1000; \ No newline at end of file diff --git a/src/Lotto.js b/src/domain/Lotto.js similarity index 100% rename from src/Lotto.js rename to src/domain/Lotto.js diff --git a/src/domain/LottoRepository.js b/src/domain/LottoRepository.js new file mode 100644 index 000000000..9f6ee07f4 --- /dev/null +++ b/src/domain/LottoRepository.js @@ -0,0 +1,9 @@ +class LottoRepository { + #lottos + + constructor() { + this.#lottos = []; + } +} + +export default LottoRepository; \ No newline at end of file diff --git a/src/domain/LottoService.js b/src/domain/LottoService.js new file mode 100644 index 000000000..2b98eadd5 --- /dev/null +++ b/src/domain/LottoService.js @@ -0,0 +1,27 @@ +import Lotto from "./Lotto.js"; +import LottoRepository from "./LottoRepository.js"; +import { LOTTO_PRICE } from "../constants/constants.js"; + +class LottoService { + #lottoRepository; + + constructor(){ + this.#lottoRepository = new LottoRepository(); + } + + #generateRandomLotto() { + + } + + purchaseLottos(payment) { + const numberOfPurchase = payment / LOTTO_PRICE + return numberOfPurchase; + } + + generateLottos() { + + } + +} + +export default LottoService; \ No newline at end of file From 247d6718c86a999a7a69643b6a3eb45ce5f68da9 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 09:15:32 +0900 Subject: [PATCH 19/35] =?UTF-8?q?feat=20:=20controller=EC=97=90=20LottoSer?= =?UTF-8?q?vice=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A3=BC=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/Controller.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/controller/Controller.js b/src/controller/Controller.js index 314c24702..8dc25ac03 100644 --- a/src/controller/Controller.js +++ b/src/controller/Controller.js @@ -1,22 +1,26 @@ import InputView from "../view/InputView.js"; import OutputView from "../view/OutputView.js"; +import LottoService from "../domain/LottoService.js"; class Controller { #inputView; #outputView; + #lottoService; constructor() { this.#inputView = new InputView(); this.#outputView = new OutputView(); + this.#lottoService = new LottoService(); } async run() { - const purchaseNumber = await this.#inputView.readPurchaseAmount(); + const payment = await this.#inputView.readPurchaseAmount(); // 지불 가격 유효성 검사 필요 + const numberOfPurchase = this.#lottoService.purchaseLottos(payment); - this.#outputView.printMyLotto(0); + this.#outputView.printMyLotto(numberOfPurchase); - const winningNumber = await this.#inputView.readWinningLotto(); - const bonusNumber = await this.#inputView.readBonusNumber(); + const winningNumber = await this.#inputView.readWinningLotto(); // 당첨 번호 유효성 검사 필요 + const bonusNumber = await this.#inputView.readBonusNumber(); // 보너스 번호 유효성 검사 필요 this.#outputView.printResult(); } From 0e1aaea7df2104e10f087d7e5961ace1a45d86c9 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 13:26:43 +0900 Subject: [PATCH 20/35] =?UTF-8?q?feat=20:=20=EB=AC=B4=EC=9E=91=EC=9C=84=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=20=EC=83=9D=EC=84=B1=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20=EB=B0=8F=20=EB=A1=9C=EB=98=90=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=83=81=EC=88=98=EA=B0=92=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/constants.js | 7 ++++++- src/controller/Controller.js | 1 + src/domain/LottoService.js | 22 ++++++++++++++-------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/constants/constants.js b/src/constants/constants.js index fbedab81f..b874a2937 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -29,4 +29,9 @@ export const ERROR_MESSAGE = { bonusTypeError : `${ERROR_PREFIX} 보너스 번호는 자연수입니다.`, }; -export const LOTTO_PRICE = 1000; \ No newline at end of file +export const LOTTO_RELATED_CONSTANTS = { + lottoPrice : 1000, + lottoRangeStart : 1, + lottoRangeEnd : 45, + lottoLength : 6, +}; \ No newline at end of file diff --git a/src/controller/Controller.js b/src/controller/Controller.js index 8dc25ac03..cf642eafd 100644 --- a/src/controller/Controller.js +++ b/src/controller/Controller.js @@ -17,6 +17,7 @@ class Controller { const payment = await this.#inputView.readPurchaseAmount(); // 지불 가격 유효성 검사 필요 const numberOfPurchase = this.#lottoService.purchaseLottos(payment); + this.#lottoService.generateLottos(numberOfPurchase); this.#outputView.printMyLotto(numberOfPurchase); const winningNumber = await this.#inputView.readWinningLotto(); // 당첨 번호 유효성 검사 필요 diff --git a/src/domain/LottoService.js b/src/domain/LottoService.js index 2b98eadd5..b725c031e 100644 --- a/src/domain/LottoService.js +++ b/src/domain/LottoService.js @@ -1,27 +1,33 @@ import Lotto from "./Lotto.js"; import LottoRepository from "./LottoRepository.js"; -import { LOTTO_PRICE } from "../constants/constants.js"; +import { LOTTO_RELATED_CONSTANTS } from "../constants/constants.js"; +import { MissionUtils } from "@woowacourse/mission-utils"; class LottoService { #lottoRepository; + #random constructor(){ this.#lottoRepository = new LottoRepository(); + this.#random = MissionUtils.Random.pickNumberInRange; } #generateRandomLotto() { - + const lottoNumbers = this.#random(LOTTO_RELATED_CONSTANTS.lottoRangeStart, LOTTO_RELATED_CONSTANTS.lottoRangeEnd, LOTTO_RELATED_CONSTANTS.lottoLength); + lottoNumbers.sort((a, b) => a - b); } - + + generateLottos(number) { + for (let idx = 0; idx < number; idx++) { + this.#generateRandomLotto(); + } + } + purchaseLottos(payment) { - const numberOfPurchase = payment / LOTTO_PRICE + const numberOfPurchase = payment / LOTTO_RELATED_CONSTANTS.lottoPrice; return numberOfPurchase; } - generateLottos() { - - } - } export default LottoService; \ No newline at end of file From c52c673278067eda0b2330e539cccd66539a9808 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 13:32:40 +0900 Subject: [PATCH 21/35] =?UTF-8?q?feat=20:=20=EC=83=9D=EC=84=B1=EB=90=9C=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=EB=A5=BC=20repository=EC=97=90=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=ED=95=98=EB=8A=94=20=ED=95=A8=EC=88=98=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 --- src/domain/LottoRepository.js | 4 ++++ src/domain/LottoService.js | 1 + 2 files changed, 5 insertions(+) diff --git a/src/domain/LottoRepository.js b/src/domain/LottoRepository.js index 9f6ee07f4..b5cd03712 100644 --- a/src/domain/LottoRepository.js +++ b/src/domain/LottoRepository.js @@ -4,6 +4,10 @@ class LottoRepository { constructor() { this.#lottos = []; } + + saveLotto(lotto) { + this.#lottos.push(lotto); + } } export default LottoRepository; \ No newline at end of file diff --git a/src/domain/LottoService.js b/src/domain/LottoService.js index b725c031e..209515297 100644 --- a/src/domain/LottoService.js +++ b/src/domain/LottoService.js @@ -15,6 +15,7 @@ class LottoService { #generateRandomLotto() { const lottoNumbers = this.#random(LOTTO_RELATED_CONSTANTS.lottoRangeStart, LOTTO_RELATED_CONSTANTS.lottoRangeEnd, LOTTO_RELATED_CONSTANTS.lottoLength); lottoNumbers.sort((a, b) => a - b); + this.#lottoRepository.saveLotto(lottoNumbers); } generateLottos(number) { From 6ba9ebc1e11a277dc193edfcc02f45e21c73ae34 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 13:53:38 +0900 Subject: [PATCH 22/35] =?UTF-8?q?refactor=20:=20=EB=AC=B4=EC=9E=91?= =?UTF-8?q?=EC=9C=84=20=EB=A1=9C=EB=98=90=20=EC=83=9D=EC=84=B1=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=EC=97=90=EC=84=9C=20=EB=B0=B0=EC=97=B4=EC=9D=84=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=ED=95=98=EB=8A=94=20=EB=8C=80=EC=8B=A0=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=20=EA=B0=9D=EC=B2=B4=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/domain/LottoService.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/domain/LottoService.js b/src/domain/LottoService.js index 209515297..203618c2e 100644 --- a/src/domain/LottoService.js +++ b/src/domain/LottoService.js @@ -15,7 +15,9 @@ class LottoService { #generateRandomLotto() { const lottoNumbers = this.#random(LOTTO_RELATED_CONSTANTS.lottoRangeStart, LOTTO_RELATED_CONSTANTS.lottoRangeEnd, LOTTO_RELATED_CONSTANTS.lottoLength); lottoNumbers.sort((a, b) => a - b); - this.#lottoRepository.saveLotto(lottoNumbers); + + const lotto = new Lotto(lottoNumbers); + this.#lottoRepository.saveLotto(lotto); } generateLottos(number) { From 860d09d6d29456d9a3c0f378d11dacae4d9553d9 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 14:00:29 +0900 Subject: [PATCH 23/35] =?UTF-8?q?feat=20:=20=EB=82=B4=20=EB=A1=9C=EB=98=90?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EA=B0=80=EC=A0=B8=EC=98=A4?= =?UTF-8?q?=EB=8A=94=20=ED=95=A8=EC=88=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/Controller.js | 1 + src/domain/LottoRepository.js | 10 +++++++--- src/domain/LottoService.js | 4 ++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/controller/Controller.js b/src/controller/Controller.js index cf642eafd..373228453 100644 --- a/src/controller/Controller.js +++ b/src/controller/Controller.js @@ -18,6 +18,7 @@ class Controller { const numberOfPurchase = this.#lottoService.purchaseLottos(payment); this.#lottoService.generateLottos(numberOfPurchase); + const myLottos = this.#lottoService.getLottos(); this.#outputView.printMyLotto(numberOfPurchase); const winningNumber = await this.#inputView.readWinningLotto(); // 당첨 번호 유효성 검사 필요 diff --git a/src/domain/LottoRepository.js b/src/domain/LottoRepository.js index b5cd03712..380fb6525 100644 --- a/src/domain/LottoRepository.js +++ b/src/domain/LottoRepository.js @@ -1,12 +1,16 @@ class LottoRepository { - #lottos + lottos constructor() { - this.#lottos = []; + this.lottos = []; } saveLotto(lotto) { - this.#lottos.push(lotto); + this.lottos.push(lotto); + } + + getLottos() { + return this.lottos; } } diff --git a/src/domain/LottoService.js b/src/domain/LottoService.js index 203618c2e..71ea06c0c 100644 --- a/src/domain/LottoService.js +++ b/src/domain/LottoService.js @@ -31,6 +31,10 @@ class LottoService { return numberOfPurchase; } + getLottos() { + return this.#lottoRepository.getLottos(); + } + } export default LottoService; \ No newline at end of file From 090ebcebf6933a4405205e3672a9e24fdd6f29f7 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 14:06:25 +0900 Subject: [PATCH 24/35] =?UTF-8?q?feat=20:=20=EA=B5=AC=EC=9E=85=ED=95=9C=20?= =?UTF-8?q?=EB=AC=B4=EC=9E=91=EC=9C=84=20=EB=A1=9C=EB=98=90=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=EB=A5=BC=20=EC=B6=9C=EB=A0=A5=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/Controller.js | 2 +- src/domain/Lotto.js | 8 +++++--- src/view/OutputView.js | 6 +++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/controller/Controller.js b/src/controller/Controller.js index 373228453..4a469a378 100644 --- a/src/controller/Controller.js +++ b/src/controller/Controller.js @@ -19,7 +19,7 @@ class Controller { this.#lottoService.generateLottos(numberOfPurchase); const myLottos = this.#lottoService.getLottos(); - this.#outputView.printMyLotto(numberOfPurchase); + this.#outputView.printMyLotto(numberOfPurchase, myLottos); const winningNumber = await this.#inputView.readWinningLotto(); // 당첨 번호 유효성 검사 필요 const bonusNumber = await this.#inputView.readBonusNumber(); // 보너스 번호 유효성 검사 필요 diff --git a/src/domain/Lotto.js b/src/domain/Lotto.js index cb0b1527e..240447fef 100644 --- a/src/domain/Lotto.js +++ b/src/domain/Lotto.js @@ -1,9 +1,9 @@ class Lotto { - #numbers; + numbers; constructor(numbers) { this.#validate(numbers); - this.#numbers = numbers; + this.numbers = numbers; } #validate(numbers) { @@ -12,7 +12,9 @@ class Lotto { } } - // TODO: 추가 기능 구현 + getNumbers() { + return this.numbers; + } } export default Lotto; diff --git a/src/view/OutputView.js b/src/view/OutputView.js index d7b8babe5..ec13be845 100644 --- a/src/view/OutputView.js +++ b/src/view/OutputView.js @@ -8,8 +8,12 @@ class OutputView { this.#print = Console.print; } - printMyLotto(purchaseNumber) { + printMyLotto(purchaseNumber, myLottos) { this.#print(OUTPUT_MESSAGE.printPurchaseNumber(purchaseNumber)); + + for (let element of myLottos) { + this.#print(element.getNumbers()); + } } printResult() { From 53ae3820af3f5f8b9236fe9519dd54c4a7665f7c Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 14:22:25 +0900 Subject: [PATCH 25/35] =?UTF-8?q?chore=20:=20=EB=AF=B8=EC=85=98=20?= =?UTF-8?q?=EA=B7=9C=EC=B9=99=EC=97=90=20=EB=94=B0=EB=9D=BC=20Lotto=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EC=9D=98=20number=EB=A5=BC=20?= =?UTF-8?q?=EB=8B=A4=EC=8B=9C=20private=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/domain/Lotto.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/domain/Lotto.js b/src/domain/Lotto.js index 240447fef..8c97d8edc 100644 --- a/src/domain/Lotto.js +++ b/src/domain/Lotto.js @@ -1,9 +1,9 @@ class Lotto { - numbers; + #numbers; constructor(numbers) { this.#validate(numbers); - this.numbers = numbers; + this.#numbers = numbers; } #validate(numbers) { @@ -12,8 +12,8 @@ class Lotto { } } - getNumbers() { - return this.numbers; + getLotto() { + return this.#numbers; } } From 52f668a63b7adcfe2088697686e136a44c441c41 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 14:29:24 +0900 Subject: [PATCH 26/35] =?UTF-8?q?fix=20:=20=EC=9E=98=EB=AA=BB=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=EB=90=9C=20Random=20=ED=95=A8=EC=88=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20Lotto=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=EC=9D=98=20getLotto=20=ED=95=A8=EC=88=98=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/domain/Lotto.js | 2 +- src/domain/LottoService.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/domain/Lotto.js b/src/domain/Lotto.js index 8c97d8edc..87d6db3f2 100644 --- a/src/domain/Lotto.js +++ b/src/domain/Lotto.js @@ -12,7 +12,7 @@ class Lotto { } } - getLotto() { + getNumbers() { return this.#numbers; } } diff --git a/src/domain/LottoService.js b/src/domain/LottoService.js index 71ea06c0c..fb1e2077f 100644 --- a/src/domain/LottoService.js +++ b/src/domain/LottoService.js @@ -9,7 +9,7 @@ class LottoService { constructor(){ this.#lottoRepository = new LottoRepository(); - this.#random = MissionUtils.Random.pickNumberInRange; + this.#random = MissionUtils.Random.pickUniqueNumbersInRange; } #generateRandomLotto() { From 41c1af6a26f0abc93d564e16309743ae48e6f73c Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 21:02:40 +0900 Subject: [PATCH 27/35] =?UTF-8?q?feat=20:=20=EB=8B=B9=EC=B2=A8=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EB=B0=B0=EC=97=B4=20=EB=B6=84=EB=A6=AC=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 --- src/view/InputView.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/view/InputView.js b/src/view/InputView.js index 0e93877be..00dc480a3 100644 --- a/src/view/InputView.js +++ b/src/view/InputView.js @@ -8,13 +8,20 @@ class InputView { this.#read = Console.readLineAsync; } + // 입력값 공백인지 유효성 검사 필요 + + #separateNumber(data) { + return data.split(",").map(Number); + } + async readPurchaseAmount() { const inputPrice = await this.#read(INPUT_MESSAGE.inputPurchaseAmount); return inputPrice; } async readWinningLotto() { - const winningNumber = await this.#read(INPUT_MESSAGE.inputWinningNumbers); + const winningdata = await this.#read(INPUT_MESSAGE.inputWinningNumbers); + const winningNumber = this.#separateNumber(winningdata); return winningNumber; } From 0503a84fa18564bf031b2a6872dace159f7e39c6 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 21:43:46 +0900 Subject: [PATCH 28/35] =?UTF-8?q?feat=20:=20=EB=8B=B9=EC=B2=A8=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=EC=99=80=20=EB=B3=B4=EC=9C=A0=20=EB=A1=9C=EB=98=90=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=EB=A5=BC=20=EB=B9=84=EA=B5=90=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/Controller.js | 4 ++++ src/domain/LottoService.js | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/controller/Controller.js b/src/controller/Controller.js index 4a469a378..dffad7d9c 100644 --- a/src/controller/Controller.js +++ b/src/controller/Controller.js @@ -24,6 +24,10 @@ class Controller { const winningNumber = await this.#inputView.readWinningLotto(); // 당첨 번호 유효성 검사 필요 const bonusNumber = await this.#inputView.readBonusNumber(); // 보너스 번호 유효성 검사 필요 + const match = this.#lottoService.compareWithWinningNumbers(winningNumber, Number(bonusNumber)); + + console.log(match); + this.#outputView.printResult(); } } diff --git a/src/domain/LottoService.js b/src/domain/LottoService.js index fb1e2077f..6355dc374 100644 --- a/src/domain/LottoService.js +++ b/src/domain/LottoService.js @@ -35,6 +35,29 @@ class LottoService { return this.#lottoRepository.getLottos(); } + compareWithWinningNumbers(winningNumbers, bonusNumber) { + let matching = [0,0,0,0,0]; + const myLottos = this.getLottos(); + + for (let lotto of myLottos) { + let match = lotto.getNumbers().filter(element => winningNumbers.includes(element)).length; + let isHave = lotto.getNumbers().includes(bonusNumber); + + switch(match.length){ + case 3 : matching[0]++; break; + case 4 : matching[1]++; break; + case 6 : matching[4]++; break; + } + if (match == 5 && !isHave){ + matching[2]++; + } + if (match == 5 && isHave){ + matching[3]++; + } + } + + return matching; + } } export default LottoService; \ No newline at end of file From 376453b3e3bd41a53a237761d8f44008af2a166f Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 21:46:11 +0900 Subject: [PATCH 29/35] =?UTF-8?q?feat=20:=20=EC=9A=B0=EC=8A=B9=20=EC=83=81?= =?UTF-8?q?=EA=B8=88=EC=97=90=20=EA=B4=80=ED=95=9C=20=EC=83=81=EC=88=98?= =?UTF-8?q?=EA=B0=92=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/constants.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/constants/constants.js b/src/constants/constants.js index b874a2937..bd12aee45 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -34,4 +34,12 @@ export const LOTTO_RELATED_CONSTANTS = { lottoRangeStart : 1, lottoRangeEnd : 45, lottoLength : 6, -}; \ No newline at end of file +}; + +export const MATCH_REWARD = { + fifth : 5000, + fourth : 50000, + third : 1500000, + second : 30000000, + first : 2000000000, +} \ No newline at end of file From c7ee97415b4f96bd0d52af088fc27d71e9a0a9c1 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 21:58:21 +0900 Subject: [PATCH 30/35] =?UTF-8?q?feat=20:=20=EC=83=81=EA=B8=88=20=EB=B9=84?= =?UTF-8?q?=EC=9C=A8=20=EA=B3=84=EC=82=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 --- src/controller/Controller.js | 5 ++--- src/domain/LottoService.js | 13 +++++++++++++ src/view/OutputView.js | 14 +++++++------- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/controller/Controller.js b/src/controller/Controller.js index dffad7d9c..538a20d77 100644 --- a/src/controller/Controller.js +++ b/src/controller/Controller.js @@ -25,10 +25,9 @@ class Controller { const bonusNumber = await this.#inputView.readBonusNumber(); // 보너스 번호 유효성 검사 필요 const match = this.#lottoService.compareWithWinningNumbers(winningNumber, Number(bonusNumber)); + const rewardRate = this.#lottoService.calculateRate(match, payment); - console.log(match); - - this.#outputView.printResult(); + this.#outputView.printResult(match, rewardRate); } } diff --git a/src/domain/LottoService.js b/src/domain/LottoService.js index 6355dc374..0317fd227 100644 --- a/src/domain/LottoService.js +++ b/src/domain/LottoService.js @@ -1,6 +1,7 @@ import Lotto from "./Lotto.js"; import LottoRepository from "./LottoRepository.js"; import { LOTTO_RELATED_CONSTANTS } from "../constants/constants.js"; +import { MATCH_REWARD } from "../constants/constants.js"; import { MissionUtils } from "@woowacourse/mission-utils"; class LottoService { @@ -58,6 +59,18 @@ class LottoService { return matching; } + + calculateRate(match, payment) { + let matchReward = [MATCH_REWARD.fifth, MATCH_REWARD.fourth, MATCH_REWARD.third, MATCH_REWARD.second, MATCH_REWARD.first]; + + let reward = match.reduce((sum, value, index) => { + return sum + (value * matchReward[index]); + }, 0); + + let rate = (reward / payment).toFixed(1); + + return rate; + } } export default LottoService; \ No newline at end of file diff --git a/src/view/OutputView.js b/src/view/OutputView.js index ec13be845..534e2fa43 100644 --- a/src/view/OutputView.js +++ b/src/view/OutputView.js @@ -16,14 +16,14 @@ class OutputView { } } - printResult() { + printResult(match, rate) { this.#print(OUTPUT_MESSAGE.printWinningStatistics); - this.#print(OUTPUT_MESSAGE.printFifth(0)); - this.#print(OUTPUT_MESSAGE.printFourth(0)); - this.#print(OUTPUT_MESSAGE.printThird(0)); - this.#print(OUTPUT_MESSAGE.printSecond(0)); - this.#print(OUTPUT_MESSAGE.printFirst(0)); - this.#print(OUTPUT_MESSAGE.printRateReturn(0)); + this.#print(OUTPUT_MESSAGE.printFifth(match[0])); + this.#print(OUTPUT_MESSAGE.printFourth(match[1])); + this.#print(OUTPUT_MESSAGE.printThird(match[2])); + this.#print(OUTPUT_MESSAGE.printSecond(match[3])); + this.#print(OUTPUT_MESSAGE.printFirst(match[4])); + this.#print(OUTPUT_MESSAGE.printRateReturn(rate)); } } From b8eb30247530f2eb38208b29166ee5e774ac00de Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 22:07:06 +0900 Subject: [PATCH 31/35] =?UTF-8?q?fix=20:=20=EB=8B=B9=EC=B2=A8=20=EB=B9=84?= =?UTF-8?q?=EC=9C=A8=20=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/domain/LottoService.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/domain/LottoService.js b/src/domain/LottoService.js index 0317fd227..d7fed4747 100644 --- a/src/domain/LottoService.js +++ b/src/domain/LottoService.js @@ -44,7 +44,7 @@ class LottoService { let match = lotto.getNumbers().filter(element => winningNumbers.includes(element)).length; let isHave = lotto.getNumbers().includes(bonusNumber); - switch(match.length){ + switch(match){ case 3 : matching[0]++; break; case 4 : matching[1]++; break; case 6 : matching[4]++; break; @@ -67,7 +67,7 @@ class LottoService { return sum + (value * matchReward[index]); }, 0); - let rate = (reward / payment).toFixed(1); + let rate = (reward / payment * 100).toFixed(1); return rate; } From f7bda9b23c13356f7a13e42eaea9def10f4a23e3 Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 22:42:50 +0900 Subject: [PATCH 32/35] =?UTF-8?q?refactor=20:=20=EB=8B=B9=EC=B2=A8=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EB=B9=84=EA=B5=90=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20=EB=B0=8F=20=EC=83=81?= =?UTF-8?q?=EC=88=98=EA=B0=92=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - LottoService에서 updateMatch함수로 비교 함수 분리 - LottoRepository에서 match 함수 관리 - match에 필요한 상수값 추가 작성 --- src/constants/constants.js | 18 ++++++++++++++++- src/domain/LottoRepository.js | 21 +++++++++++++++++++- src/domain/LottoService.js | 37 +++++++++++++++++++---------------- 3 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/constants/constants.js b/src/constants/constants.js index bd12aee45..cc3a4c253 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -42,4 +42,20 @@ export const MATCH_REWARD = { third : 1500000, second : 30000000, first : 2000000000, -} \ No newline at end of file +}; + +export const MATCH = { + init : 0, + three : 3, + four : 4, + five : 5, + six : 6, +}; + +export const MATCH_RANK = { + fifit : 0, + fourth : 1, + third : 2, + second : 3, + first : 4, +}; \ No newline at end of file diff --git a/src/domain/LottoRepository.js b/src/domain/LottoRepository.js index 380fb6525..18c58c2c9 100644 --- a/src/domain/LottoRepository.js +++ b/src/domain/LottoRepository.js @@ -1,8 +1,15 @@ +import { MATCH_REWARD } from "../constants/constants.js"; +import { MATCH } from "../constants/constants.js"; + class LottoRepository { - lottos + lottos; + match; + matchReward; constructor() { this.lottos = []; + this.match = [MATCH.init, MATCH.init, MATCH.init, MATCH.init, MATCH.init]; + this.matchReward = [MATCH_REWARD.fifth, MATCH_REWARD.fourth, MATCH_REWARD.third, MATCH_REWARD.second, MATCH_REWARD.first]; } saveLotto(lotto) { @@ -12,6 +19,18 @@ class LottoRepository { getLottos() { return this.lottos; } + + getMatch() { + return this.match; + } + + updateMatch(number) { + this.match[number]++; + } + + getMatchReward() { + return this.matchReward; + } } export default LottoRepository; \ No newline at end of file diff --git a/src/domain/LottoService.js b/src/domain/LottoService.js index d7fed4747..0fdef8f9a 100644 --- a/src/domain/LottoService.js +++ b/src/domain/LottoService.js @@ -1,7 +1,8 @@ import Lotto from "./Lotto.js"; import LottoRepository from "./LottoRepository.js"; import { LOTTO_RELATED_CONSTANTS } from "../constants/constants.js"; -import { MATCH_REWARD } from "../constants/constants.js"; +import { MATCH } from "../constants/constants.js"; +import { MATCH_RANK } from "../constants/constants.js"; import { MissionUtils } from "@woowacourse/mission-utils"; class LottoService { @@ -36,33 +37,35 @@ class LottoService { return this.#lottoRepository.getLottos(); } + #updateMatch(match, isHaveBonus) { + switch(match){ + case MATCH.three : this.#lottoRepository.updateMatch(MATCH_RANK.fifit); break; + case MATCH.four : this.#lottoRepository.updateMatch(MATCH_RANK.fourth); break; + case MATCH.six : this.#lottoRepository.updateMatch(MATCH_RANK.first); break; + } + if (match == MATCH.five && !isHaveBonus){ + this.#lottoRepository.updateMatch(MATCH_RANK.third); + } + if (match == MATCH.five && isHaveBonus){ + this.#lottoRepository.updateMatch(MATCH_RANK.second); + } + } + compareWithWinningNumbers(winningNumbers, bonusNumber) { - let matching = [0,0,0,0,0]; const myLottos = this.getLottos(); for (let lotto of myLottos) { let match = lotto.getNumbers().filter(element => winningNumbers.includes(element)).length; - let isHave = lotto.getNumbers().includes(bonusNumber); + let isHaveBonus = lotto.getNumbers().includes(bonusNumber); - switch(match){ - case 3 : matching[0]++; break; - case 4 : matching[1]++; break; - case 6 : matching[4]++; break; - } - if (match == 5 && !isHave){ - matching[2]++; - } - if (match == 5 && isHave){ - matching[3]++; - } + this.#updateMatch(match, isHaveBonus); } - return matching; + return this.#lottoRepository.getMatch(); } calculateRate(match, payment) { - let matchReward = [MATCH_REWARD.fifth, MATCH_REWARD.fourth, MATCH_REWARD.third, MATCH_REWARD.second, MATCH_REWARD.first]; - + let matchReward = this.#lottoRepository.getMatchReward(); let reward = match.reduce((sum, value, index) => { return sum + (value * matchReward[index]); }, 0); From 98f115bbaf8a345e793743310a0343036c6a537f Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 22:45:31 +0900 Subject: [PATCH 33/35] =?UTF-8?q?refactor=20:=20=EC=83=81=EA=B8=88=20?= =?UTF-8?q?=EB=B9=84=EC=9C=A8=20=EC=83=81=EC=88=98=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/constants.js | 2 ++ src/domain/LottoService.js | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/constants/constants.js b/src/constants/constants.js index cc3a4c253..55cb005c7 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -34,6 +34,8 @@ export const LOTTO_RELATED_CONSTANTS = { lottoRangeStart : 1, lottoRangeEnd : 45, lottoLength : 6, + rate : 100, + rounding : 1, }; export const MATCH_REWARD = { diff --git a/src/domain/LottoService.js b/src/domain/LottoService.js index 0fdef8f9a..016d7d5ee 100644 --- a/src/domain/LottoService.js +++ b/src/domain/LottoService.js @@ -70,8 +70,7 @@ class LottoService { return sum + (value * matchReward[index]); }, 0); - let rate = (reward / payment * 100).toFixed(1); - + let rate = (reward / payment * LOTTO_RELATED_CONSTANTS.rate).toFixed(LOTTO_RELATED_CONSTANTS.rounding); return rate; } } From cce823cb11beb2a9aa109490cf07a96f15012c1f Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 23:37:34 +0900 Subject: [PATCH 34/35] =?UTF-8?q?feat=20:=20Validator=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC=20=EA=B8=B0=EB=8A=A5=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/constants.js | 4 ++ src/validation/Validator.js | 79 +++++++++++++++++++++++++++++++++++++ src/view/InputView.js | 8 +++- 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 src/validation/Validator.js diff --git a/src/constants/constants.js b/src/constants/constants.js index 55cb005c7..0f35c4f60 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -18,12 +18,16 @@ export const OUTPUT_MESSAGE = { const ERROR_PREFIX = "[ERROR]"; export const ERROR_MESSAGE = { + nullData : `${ERROR_PREFIX} 값을 입력해야 합니다.`, purchaseError : `${ERROR_PREFIX} 구입 금액은 1000으로 나누어 떨어지는 수 입니다.`, purchaseRangeError : `${ERROR_PREFIX} 구입 금액 범위는 양수인 정수입니다.`, + lottoLengthError : `${ERROR_PREFIX} 당첨 번호는 6개여야 합니다.`, lottoDuplicatedError : `${ERROR_PREFIX} 당첨 번호는 중복될 수 없습니다.`, lottoRangeError : `${ERROR_PREFIX} 당첨 번호의 범위는 1~45 폐구간 입니다.`, lottoTypeError : `${ERROR_PREFIX} 당첨 번호는 자연수입니다.`, + + bonusLengthError : `${ERROR_PREFIX} 보너스 번호는 1개여야 합니다.`, bonusDuplicatedError : `${ERROR_PREFIX} 보너스 번호는 당첨 번호와 중복될 수 없습니다.`, bonusRangeError : `${ERROR_PREFIX} 보너스 번호의 범위는 1~45 폐구간 입니다.`, bonusTypeError : `${ERROR_PREFIX} 보너스 번호는 자연수입니다.`, diff --git a/src/validation/Validator.js b/src/validation/Validator.js new file mode 100644 index 000000000..2261d2d14 --- /dev/null +++ b/src/validation/Validator.js @@ -0,0 +1,79 @@ +import { ERROR_MESSAGE } from "../constants/constants"; + +class Validator { + //입력 에러 + static inputNullData(data) { + if (data === null || data.trim() === "") { + throw new Error (ERROR_MESSAGE.nullData); + } + } + + static inputPurchaseValidation(price) { + if (!Number.isInteger(price / 1000)) { + throw new Error(ERROR_MESSAGE.purchaseError); + } + } + + static purchaseRangeValidation(price) { + if (price <= 0) { + throw new Error(ERROR_MESSAGE.purchaseRangeError); + } + } + + // 당첨 번호 에러 + static lottoLengthValidation(numbers) { + if (numbers.length !== 6) { + throw new Error(ERROR_MESSAGE.lottoLengthError); + } + } + + static lottoDuplicatedValidation(numbers) { + const isDuplicated = numbers.some(function(x) { + return numbers.indexOf(x) !== numbers.lastIndexOf(x); + }); + if (isDuplicated) { + throw new Error(ERROR_MESSAGE.lottoDuplicatedError); + } + } + + static lottoRangeValidation(numbers) { + const isOutOfRange = numbers.some(function(number) { + return number < 1 || number > 45; + }); + if (isOutOfRange) { + throw new Error(ERROR_MESSAGE.lottoRangeError); + } + } + + static lottoTypeValidation(numbers) { + const isTypeValid = numbers.every((element) => { + return Number.isInteger(element); + }); + if (!isTypeValid) { + throw new Error(ERROR_MESSAGE.lottoTypeError); + } + } + + //보너스 번호 에러 + static bonusLengthValidation(number) { + if (number.length !== 1) { + throw new Error(ERROR_MESSAGE.bonusLengthError); + } + } + + static bonusRangeValidation(number) { + const isOutOfRange = number < 1 || number > 45; + if (isOutOfRange) { + throw new Error(ERROR_MESSAGE.bonusRangeError); + } + } + + static bonusTypeValidation(number) { + const isTypeValid = Number.isInteger(number); + if (!isTypeValid) { + throw new Error(ERROR_MESSAGE.bonusTypeError); + } + } +} + +export default Validator; \ No newline at end of file diff --git a/src/view/InputView.js b/src/view/InputView.js index 00dc480a3..c6857e72a 100644 --- a/src/view/InputView.js +++ b/src/view/InputView.js @@ -1,5 +1,6 @@ import { Console } from "@woowacourse/mission-utils"; import { INPUT_MESSAGE } from "../constants/constants.js"; +import Validator from "../validation/Validator.js"; class InputView { #read; @@ -8,7 +9,9 @@ class InputView { this.#read = Console.readLineAsync; } - // 입력값 공백인지 유효성 검사 필요 + #validate(data) { + + } #separateNumber(data) { return data.split(",").map(Number); @@ -26,7 +29,8 @@ class InputView { } async readBonusNumber() { - const bonusNumber = await this.#read(INPUT_MESSAGE.inputBonusNumber); + const bonusData = await this.#read(INPUT_MESSAGE.inputBonusNumber); + const bonusNumber = this.#separateNumber(bonusData); return bonusNumber; } } From ce3c1adbf3121018adf515b3dc3d5346a52f35aa Mon Sep 17 00:00:00 2001 From: leelsj2007 Date: Mon, 4 Nov 2024 23:47:59 +0900 Subject: [PATCH 35/35] =?UTF-8?q?feat=20:=20=EA=B3=B5=EB=B0=B1=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EC=8B=9C=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=20=ED=9B=84=20=EB=8B=A4=EC=8B=9C=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EB=B0=9B=EA=B2=8C=20=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=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 --- src/validation/Validator.js | 2 +- src/view/InputView.js | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/validation/Validator.js b/src/validation/Validator.js index 2261d2d14..e7be693bd 100644 --- a/src/validation/Validator.js +++ b/src/validation/Validator.js @@ -1,4 +1,4 @@ -import { ERROR_MESSAGE } from "../constants/constants"; +import { ERROR_MESSAGE } from "../constants/constants.js"; class Validator { //입력 에러 diff --git a/src/view/InputView.js b/src/view/InputView.js index c6857e72a..9df1d7315 100644 --- a/src/view/InputView.js +++ b/src/view/InputView.js @@ -10,7 +10,7 @@ class InputView { } #validate(data) { - + Validator.inputNullData(data); } #separateNumber(data) { @@ -18,20 +18,39 @@ class InputView { } async readPurchaseAmount() { - const inputPrice = await this.#read(INPUT_MESSAGE.inputPurchaseAmount); - return inputPrice; + try { + const inputPrice = await this.#read(INPUT_MESSAGE.inputPurchaseAmount); + this.#validate(inputPrice); + return inputPrice; + } catch(e) { + console.error(e.message); + return await this.readPurchaseAmount(); + } + } async readWinningLotto() { - const winningdata = await this.#read(INPUT_MESSAGE.inputWinningNumbers); - const winningNumber = this.#separateNumber(winningdata); - return winningNumber; + try { + const winningdata = await this.#read(INPUT_MESSAGE.inputWinningNumbers); + const winningNumber = this.#separateNumber(winningdata); + this.#validate(winningNumber); + return winningNumber; + } catch(e) { + console.error(e.message); + return await this.readWinningLotto(); + } } async readBonusNumber() { - const bonusData = await this.#read(INPUT_MESSAGE.inputBonusNumber); - const bonusNumber = this.#separateNumber(bonusData); - return bonusNumber; + try { + const bonusData = await this.#read(INPUT_MESSAGE.inputBonusNumber); + const bonusNumber = this.#separateNumber(bonusData); + this.#validate(bonusNumber); + return bonusNumber; + } catch(e) { + console.error(e.message); + return await this.readBonusNumber(); + } } }