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

[로또] 구은성 미션 제출합니다. #1363

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
aeb2fae
Docs: 구현 기능 목록 작성
Koo-EunSung Nov 2, 2024
67196d5
Docs: 구현 기능 목록 업데이트
Koo-EunSung Nov 2, 2024
cab1ca8
Feat: 구입금액 입력
Koo-EunSung Nov 3, 2024
3c0a8e4
Feat: 당첨 번호 입력
Koo-EunSung Nov 3, 2024
a158c2a
Feat: 보너스 번호 입력
Koo-EunSung Nov 3, 2024
f8a1531
Refactor: 상수명 변경
Koo-EunSung Nov 4, 2024
3d40891
Refactor: Lotto 클래스 패키지 변경
Koo-EunSung Nov 4, 2024
afdd573
Docs: 예외상황 업데이트
Koo-EunSung Nov 4, 2024
73def91
Feat: 번호 범위 검증
Koo-EunSung Nov 4, 2024
1b757f7
Feat: 구입 금액 검증
Koo-EunSung Nov 4, 2024
ed18e30
Feat: 구입 금액에 따라 로또 발행
Koo-EunSung Nov 4, 2024
f54399f
Feat: 입력 문자열 쉼표 기준 분리
Koo-EunSung Nov 4, 2024
33edb66
Feat: 문자열 숫자 변환
Koo-EunSung Nov 4, 2024
60a769b
Feat: 입력값 숫자 검증
Koo-EunSung Nov 4, 2024
edaf4c7
Feat: 중복값 검증
Koo-EunSung Nov 4, 2024
058c4e2
Refactor: 예외 메세지 enum으로 관리
Koo-EunSung Nov 4, 2024
4b1b81d
Feat: String list to Integer list
Koo-EunSung Nov 4, 2024
573b22c
Feat: 번호 갯수 검증
Koo-EunSung Nov 4, 2024
f1cb10d
Feat: Integer 리스트 번호 범위 검증
Koo-EunSung Nov 4, 2024
d4cf106
Feat: 보너스 번호 검증
Koo-EunSung Nov 4, 2024
1eee8a9
Feat: 사용자 입력 관련 비즈니스 로직
Koo-EunSung Nov 4, 2024
a720b39
Feat: 로또 결과 계산
Koo-EunSung Nov 4, 2024
4f7c244
ã„Feat: 로또 결과 관련 비즈니스 로직
Koo-EunSung Nov 4, 2024
f5c2626
Feat: 로또 구입 내역 출력
Koo-EunSung Nov 4, 2024
ab6fbfb
Feat: 수익률 계산
Koo-EunSung Nov 4, 2024
1aec709
Feat: 최종 결과 출력
Koo-EunSung Nov 4, 2024
fa8f838
Feat: 비즈니스 로직
Koo-EunSung Nov 4, 2024
9004137
Fix: LottoGameController 생성자 수정
Koo-EunSung Nov 4, 2024
da5a35b
Fix
Koo-EunSung Nov 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,75 @@
# java-lotto-precourse

## 개요
간단한 로또 발매기를 구현한다.

## 기능 목록
- 입력
- 로또 구입 금액
- 1,000원 단위로 입력받는다.
- 예외 상황: 이하의 경우에 예외를 던진다.
- 입력값이 숫자가 아닌 경우
- 금액이 1,000원 단위가 아닐 경우
- 당첨 번호
- 번호는 쉼표를 기준으로 구분한다.
- 예외 상항: 이하의 경우에 예외를 던진다.
- 쉼표(,)를 제외한 문자가 포함되어 있을 경우
- 숫자가 범위(1~45)를 벗어날 경우
- 숫자의 갯수가 6 초과인 경우
- 숫자의 갯수가 6 미만인 경우
- 중복된 숫자가 존재하는 경우
- 보너스 번호
- 예외 상황: 이하의 경우에 예외를 던진다.
- 입력값이 숫자가 아닌 경우
- 숫자가 범위(1~45)를 벗어날 경우
- 당첨 번호와 중복되는 경우
- 예외 처리: 예외가 던져지면 에러 메세지를 출력한 후 입력을 다시 받는다.
- 로또 발행: 중복되지 않는 6개의 숫자를 뽑는다.
- 발행 갯수는 `구입 금액 / 1000`이다.
- 당첨 결과 계산
- 발행한 로또와 당첨 번호 및 보너스 번호를 비교해 결과를 계산한다
- 기준
- 1등: 6개 번호 일치 / 2,000,000,000원
- 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원
- 3등: 5개 번호 일치 / 1,500,000원
- 4등: 4개 번호 일치 / 50,000원
- 5등: 3개 번호 일치 / 5,000원
- 출력
- 입력 시 안내 문구
- 로또 구입 금액: `구입금액을 입력해 주세요.`
- 당첨 번호: `당첨 번호를 입력해주세요.`
- 보너스 번호: `보너스 번호를 입력해주세요.`
- 발행한 로또 수량 및 번호
- 로또 번호는 오름차순으로 정렬
- 예시
```
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개
```
- 수익률
- 소수점 둘째 자리에서 반올림
- 예시: `총 수익률은 62.5%입니다.`
- 에러 문구
- 예외 상황 시에 출력
- 에러 문구는 `[ERROR]`로 시작
18 changes: 17 additions & 1 deletion src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
package lotto;

import lotto.controller.InputController;
import lotto.controller.LottoGameController;
import lotto.util.NumberConverter;
import lotto.util.StringParser;
import lotto.validator.NumberValidator;
import lotto.view.InputView;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
InputView inputView = new InputView();
NumberConverter numberConverter = new NumberConverter();
StringParser stringParser = new StringParser();
NumberValidator numberValidator = new NumberValidator();

InputController inputController = new InputController(inputView, numberConverter, stringParser, numberValidator);

LottoGameController lottoGameController = new LottoGameController(inputController);
lottoGameController.run();

}
}
20 changes: 0 additions & 20 deletions src/main/java/lotto/Lotto.java

This file was deleted.

70 changes: 70 additions & 0 deletions src/main/java/lotto/controller/InputController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package lotto.controller;

import java.util.List;
import lotto.util.NumberConverter;
import lotto.util.StringParser;
import lotto.validator.NumberValidator;
import lotto.view.InputView;

public class InputController {
private final InputView inputView;
private final NumberConverter numberConverter;
private final StringParser stringParser;
private final NumberValidator numberValidator;

public InputController(InputView inputView, NumberConverter numberConverter, StringParser stringParser, NumberValidator numberValidator) {
this.inputView = inputView;
this.numberConverter = numberConverter;
this.stringParser = stringParser;
this.numberValidator = numberValidator;
}

public Integer getMoney() {
String input = inputView.getMoney();

try {
numberValidator.isNumber(input);
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
getMoney();
}
return numberConverter.convertToInteger(input);
}

public List<Integer> getWinningNumbers() {
List<Integer> winningNumbers;

List<String> input = stringParser.parse(inputView.getWinningNumber());

try {
numberValidator.isNumber(input);
winningNumbers = numberConverter.convertToInteger(input);

numberValidator.checkCountOfNumber(winningNumbers);
numberValidator.isDuplicateNumber(winningNumbers);
numberValidator.checkInRange(winningNumbers);
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
getWinningNumbers();
}

return numberConverter.convertToInteger(input);
}

public Integer getBonusNumber(List<Integer> winningNumbers) {
String input = inputView.getBonusNumber();

try {
numberValidator.isNumber(input);
Integer bonusNumber = numberConverter.convertToInteger(input);

numberValidator.checkInRange(bonusNumber);
numberValidator.isDuplicateNumber(winningNumbers, bonusNumber);
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
getBonusNumber(winningNumbers);
}

return numberConverter.convertToInteger(input);
}
}
49 changes: 49 additions & 0 deletions src/main/java/lotto/controller/LottoGameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package lotto.controller;

import java.util.List;
import java.util.Map;
import lotto.model.Lotto;
import lotto.model.LottoGame;
import lotto.model.LottoMachine;
import lotto.model.Prize;
import lotto.util.RandomGenerator;
import lotto.view.OutputView;

public class LottoGameController {
private final InputController inputController;

public LottoGameController(InputController inputController) {
this.inputController = inputController;
}

public void run() {
LottoMachine lottoMachine;
List<Integer> winningNumbers;
Integer bonusNumber;
RandomGenerator randomGenerator = new RandomGenerator();

while (true) {
try {
Integer money = inputController.getMoney();
lottoMachine = new LottoMachine(money, randomGenerator);
break;
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}

List<Lotto> lottos = lottoMachine.makeLotto();
OutputView.printLottoBuyHistory(lottos)
;
winningNumbers = inputController.getWinningNumbers();
bonusNumber = inputController.getBonusNumber(winningNumbers);

LottoGame game = new LottoGame(lottos, winningNumbers, bonusNumber);

Map<Prize, Integer> result = game.getResult();
double profitRate = game.getProfitRate();

OutputView.printResult(result, profitRate);
}

}
21 changes: 21 additions & 0 deletions src/main/java/lotto/message/ExceptionMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package lotto.message;

public enum ExceptionMessage {
ONLY_NUMBER("[ERROR] 숫자만 입력해야 합니다."),
LOTTO_SIZE("[ERROR] 로또 번호는 6개여야 합니다."),
DUPLICATE("[ERROR] 로또 번호는 중복된 숫자가 없어야 합니다."),
OUT_OF_RANGE("[ERROR] 로또 번호는 1에서 45 사이여야 합니다."),
PURCHASE_AMOUNT("[ERROR] 구매 금액은 1000으로 나누어 떨어져야 합니다."),
BONUS_NUMBER("[ERROR] 보너스 번호는 당첨 번호에 없는 번호여야 합니다.")
;

private String message;

private ExceptionMessage(String message) {
this.message = message;
}

public String getMessage() {
return this.message;
}
}
41 changes: 41 additions & 0 deletions src/main/java/lotto/model/Lotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package lotto.model;

import java.util.List;
import lotto.validator.NumberValidator;

public class Lotto {
private final List<Integer> numbers;
private final NumberValidator numberValidator = new NumberValidator();

public Lotto(List<Integer> numbers) {
validate(numbers);
this.numbers = numbers;
}

private void validate(List<Integer> numbers) {
numberValidator.isDuplicateNumber(numbers);
if (numbers.size() != 6) {
throw new IllegalArgumentException("[ERROR] 로또 번호는 6개여야 합니다.");
}
}

public Prize checkResult(List<Integer> winningNumbers, Integer bonusNumber) {
Integer count = 0;
Boolean bonus = false;

for (Integer number : numbers) {
if (winningNumbers.contains(number))
count++;

if (number.equals(bonusNumber)) {
bonus = true;
}
}

return Prize.getResult(count, bonus);
}

public List<Integer> getNumbers() {
return numbers;
}
}
34 changes: 34 additions & 0 deletions src/main/java/lotto/model/LottoGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package lotto.model;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LottoGame {
private List<Lotto> lottos;
private List<Integer> winningNumbers;
private Integer bonusNumber;
private Map<Prize, Integer> results = new HashMap<>();

public LottoGame(List<Lotto> lottos, List<Integer> winningNumbers, Integer bonusNumber) {
this.lottos = lottos;
this.winningNumbers = winningNumbers;
this.bonusNumber = bonusNumber;
}

public Map<Prize, Integer> getResult() {
for (Lotto lotto : lottos) {
Prize result = lotto.checkResult(winningNumbers, bonusNumber);
results.put(result, results.getOrDefault(result, 0) + 1);
}

return results;
}

public double getProfitRate() {
Integer totalPrize = Prize.calculatePrize(results);
Integer usedMoney = 1000 * lottos.size();

return (double) totalPrize / usedMoney;
}
}
35 changes: 35 additions & 0 deletions src/main/java/lotto/model/LottoMachine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package lotto.model;

import java.util.ArrayList;
import java.util.List;
import lotto.util.RandomGenerator;

public class LottoMachine {
private static final String MONEY_ERROR_MESSAGE = "[ERROR] 구입 금액은 1,000원으로 나누어 떨어져야 합니다.";

private Integer money;
private RandomGenerator randomGenerator;

public LottoMachine(Integer money, RandomGenerator randomGenerator) {
validate(money);
this.money = money;
this.randomGenerator = randomGenerator;
}

private void validate(Integer money) {
if (money % 1000 != 0)
throw new IllegalArgumentException(MONEY_ERROR_MESSAGE);
}

public List<Lotto> makeLotto() {
List<Lotto> lottos = new ArrayList<>();
Integer count = this.money / 1000;

for (int i = 0; i < count; i++) {
Lotto lotto = new Lotto(randomGenerator.generate());
lottos.add(lotto);
}

return lottos;
}
}
Loading