Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[로또] 정석찬 미션 제출합니다. #405

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
60 changes: 59 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,59 @@
# javascript-lotto-precourse
# 로또 발매기

간단한 로또 발매기
구매한 로또의 금액과 당첨된 로또의 금액을 비교하여 수익률을 알려주는 프로그램

## 실행 결과

### 입력

``` plaintext
구입금액을 입력해 주세요.
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%입니다.
```

## 구현할 기능
- [x] 입력 받기
- [x] 로또 구매할 금액 입력
- [x] 1000원으로 나누어 떨어지지 않는 경우 ERROR
- [x] 당첨 번호 입력
- [x] 예외 처리
- [x] ','로 구분 안되는 값
- [x] 숫자가 아닌 값
- [x] 중복된 값
- [x] 보너스 번호 입력
- [x] 예외 처리
- [x] 숫자가 아닌 값
- [x] 입력 당첨 번호와 중복된 값

- [ ] 로또 발행하기
- [x] 구매한 로또만큼 번호 발행
- [x] 발행한 로또 출력
- [x] 발행한 로또 당첨 처리
- [x] 당첨 내역 출력
- [x] 수익률 출력
2 changes: 1 addition & 1 deletion __tests__/LottoTest.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Lotto from "../src/Lotto";
import Lotto from "../src/Lotto.js";

describe("로또 클래스 테스트", () => {
test("로또 번호의 개수가 6개가 넘어가면 예외가 발생한다.", () => {
Expand Down
36 changes: 35 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
import Customer from "./model/Customer.js";
import Lotto from "./Lotto.js";
import LottoChecker from "./model/LottoChecker.js";
import InputView from "./view/InputView.js";

class App {
async run() {}
async run() {
const input = new InputView();
const customer = new Customer();
const lottoChecker = new LottoChecker();


// 로또 구매 및 출력
const purchaseAmount = await input.readPurchaseAmount();
customer.purchaseLotto(purchaseAmount);
customer.getLottoNumberList();

// 생성한 번호 출력
customer.lottoNumbersPrint();

const winningNumbers = await input.readWinningNumbers();
const lotto = new Lotto(winningNumbers);
const validWinningNumbers = lotto.getNumbers();
const bonusNumber = await input.readBonusNumber();

lottoChecker.setWinningAndBonusNumbers(validWinningNumbers, bonusNumber);
customer.getLottoResults(lottoChecker);

customer.calculateProfit();
customer.lottoResultPrint();





}
}

export default App;
13 changes: 12 additions & 1 deletion src/Lotto.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,20 @@ class Lotto {
if (numbers.length !== 6) {
throw new Error("[ERROR] 로또 번호는 6개여야 합니다.");
}

if (new Set(numbers).size !== numbers.length) {
throw new Error("[ERROR] 로또 당첨 번호는 중복된 값을 가질 수 없습니다.");
}

if (numbers.some((number) => number < 1 || number > 45)) {
throw new Error("[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다.");
}
}

getNumbers() {
return this.#numbers;
}

// TODO: 추가 기능 구현
}

export default Lotto;
28 changes: 28 additions & 0 deletions src/View/InputView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Console } from "@woowacourse/mission-utils";

export default class InputView {

async readPurchaseAmount() {
const purchaseAmountStr = await Console.readLineAsync("구입금액을 입력해 주세요.\n");
const purchaseAmount = Number(purchaseAmountStr);
return purchaseAmount;
}

async readWinningNumbers() {
const winningNumbers = await Console.readLineAsync("당첨 번호를 입력해 주세요.\n");
const winningNumbersArr = this.splitNumbers(winningNumbers);
return winningNumbersArr;
}

async readBonusNumber() {
let bonusNumber = await Console.readLineAsync("보너스 번호를 입력해 주세요.\n");
bonusNumber = Number(bonusNumber.trim());
return bonusNumber;
}

splitNumbers(winningNumbers) {
const numbersArray = winningNumbers.split(',').map(number => Number(number.trim()));
return numbersArray;
}

}
6 changes: 6 additions & 0 deletions src/View/outputView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Console } from "@woowacourse/mission-utils";

export default class outputView {

static
}
61 changes: 61 additions & 0 deletions src/model/Customer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import Lotto from "../Lotto.js";
import LottoChecker from "./LottoChecker.js";
import { Console } from "@woowacourse/mission-utils";

export default class Customer {
#purchaseAmount;
#lottoNumbersList = [];
#lottoRankResults = [0, 0, 0, 0, 0, 0]; // index = 결과 등수
#lottoCount;
#profitRate;
#profit = 0;

#valid(purchaseAmount) {
if (purchaseAmount % 1000 !== 0)
throw new Error("[ERROR] 구매금액은 1000원 단위이어야합니다.");
}

purchaseLotto(purchaseAmount) {
this.#valid(purchaseAmount);
this.#purchaseAmount = purchaseAmount;
this.#lottoCount = purchaseAmount/1000;
}

getLottoNumberList() {
Array.from({ length: this.#lottoCount }).forEach(() => {
const lottoNumbers = LottoChecker.generateLottoNumbers();
this.#lottoNumbersList.push(lottoNumbers);
})
}

getLottoResults(lottoChecker) {
this.#lottoNumbersList.forEach(lottoNumbers => {
const rank = lottoChecker.getLottoRank(lottoNumbers);
this.#lottoRankResults[rank] += 1;
})
}

lottoNumbersPrint() {
Console.print(`${this.#lottoCount}개를 구매했습니다.\n`);
this.#lottoNumbersList.forEach((lottoNumbers) => {
Console.print(`${lottoNumbers}\n`);
})
}

calculateProfit() {
const prizeAmounts = [0, 2000000000, 30000000, 1500000, 50000, 5000];

this.#lottoRankResults.forEach((count, rank) => {
this.#profit += count * prizeAmounts[rank];
});

this.#profitRate = Math.round((this.#profit / this.#purchaseAmount) * 10000) / 100;
}

lottoResultPrint() {
Console.print("당첨 통계\n---\n");
Console.print(`3개 일치 (5,000원) - ${this.#lottoRankResults[5]}개\n4개 일치 (50,000원) - ${this.#lottoRankResults[4]}개\n5개 일치 (1,500,000원) - ${this.#lottoRankResults[3]}개\n5개 일치, 보너스 볼 일치 (30,000,000원) - ${this.#lottoRankResults[2]}개\n6개 일치 (2,000,000,000원) - ${this.#lottoRankResults[1]}개\n총 수익률은 ${this.#profitRate}%입니다.\n
`)
}

}
34 changes: 34 additions & 0 deletions src/model/LottoChecker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Random } from "@woowacourse/mission-utils";

export default class LottoChecker {
#winningNumbers=[];
#bonusNumber;

setWinningAndBonusNumbers(winningNumbers, bonusNumber) {
this.#winningNumbers = winningNumbers;
this.#bonusNumber = bonusNumber;
}

static generateLottoNumbers() {
const lottoNumbers = Random.pickUniqueNumbersInRange(1, 45, 6);
return lottoNumbers;
}

// return : 로또 등수
getLottoRank(LottoNumbers) {
const winningCount = LottoNumbers.filter(number => this.#winningNumbers.includes(number))
const actions = {
3: () => {return 5},
4: () => {return 4},
5: () => {
if (LottoNumbers.includes(this.#bonusNumber))
return 2;
return 3;
},
6: () => { return 1; },
default: () => { return 0;}
}
const rank = (actions[winningCount.length] || actions.default)();
return rank;
}
}