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

임연지 - 로또 미션 #5

Open
wants to merge 50 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
a54d12f
docs: 구현할 기능 목록
yeonjy Aug 27, 2023
e162025
feat: 로또 번호 6개 & 중복X & 범위 내 숫자 검증 구현
yeonjy Aug 28, 2023
bd66c95
test: 로또 번호 범위 내 숫자 검증 테스트
yeonjy Aug 28, 2023
f1705bf
docs: 기능별 패키지 분할
yeonjy Aug 28, 2023
5c50af8
feat: 보너스 로또 숫자 중복X & 범위 내 숫자 검증 구현
yeonjy Aug 28, 2023
9e16f68
test: 보너스 로또 번호 중복X & 범위 내 숫자 검증 테스트
yeonjy Aug 28, 2023
31151e5
refactor: 상수 -> enum
yeonjy Aug 28, 2023
b3053e0
feat: 로또 실행 - 로또 구입 금액 입력 구현
yeonjy Aug 28, 2023
81604e3
feat: 로또 티켓 개수 도출 & 티켓 출력 로직 구현
yeonjy Aug 28, 2023
e64b7cc
feat: 로또 티켓 생성 구현
yeonjy Aug 28, 2023
1706015
feat: 입력 가이드 enum 구현
yeonjy Aug 28, 2023
dcc3ede
feat: 숫자X & 1000원 단위X 예외 구현
yeonjy Aug 28, 2023
02bb67e
refactor: 입력값 -> 사용가능한 데이터 Processor 구현
yeonjy Aug 28, 2023
231bb0e
refactor: Integer -> int
yeonjy Aug 28, 2023
e580531
refactor: ", " -> CRITERIA
yeonjy Aug 28, 2023
17777c7
feat: 상금 enum 클래스
yeonjy Aug 28, 2023
686d706
docs: 로또 추첨 실행
yeonjy Aug 28, 2023
e5afd8b
feat: 로또 번호 반환 get 메서드
yeonjy Aug 28, 2023
372a03d
feat: 로또 번호 일치 개수 enum
yeonjy Aug 28, 2023
59fb09a
feat: 출력 가이드 enum
yeonjy Aug 28, 2023
6920948
feat: 티켓 생성 로직 호출
yeonjy Aug 28, 2023
b592d6a
feat: 로또 개수 계산 & 출력
yeonjy Aug 28, 2023
1bd4d53
feat: 로또 번호 6개 & 보너스 번호 입력 Controller
yeonjy Aug 28, 2023
c72896a
refactor: 생성된 로또 티켓 playLotto 매개변수로 전달
yeonjy Aug 28, 2023
f957ced
feat: 로또 당첨별 상금 초기화 메서드 구현
yeonjy Aug 28, 2023
aaf844b
feat: 전체 당첨 로또 번호를 가진 DTO 구현
yeonjy Aug 28, 2023
91be437
docs: 당첨 번호 입력 Controller 분리
yeonjy Aug 29, 2023
b1c6a6f
refactor: 상금 int -> long
yeonjy Aug 29, 2023
8afe729
feat: 일치 개수 별 상금 & 당첨 로또 개수 구현
yeonjy Aug 29, 2023
90f2f33
docs: 로또 실행 결과
yeonjy Aug 29, 2023
4fd506c
feat: 로또 결과 출력 & 상금 구현
yeonjy Aug 29, 2023
1750911
feat: 로또 실행 결과 출력 가이드 enum
yeonjy Aug 29, 2023
5074a0d
feat: 로또 번호 6개 & 보너스 번호 DTO 생성
yeonjy Aug 29, 2023
e60ac08
refactor: enum 값 가져오기
yeonjy Aug 29, 2023
67b7705
refactor: 당첨 번호 쪼개기 기준 ", " -> ","
yeonjy Aug 29, 2023
1290c22
refactor: valueOf() -> getOf()
yeonjy Aug 29, 2023
2fea149
feat: 수익률 출력 가이드 enum
yeonjy Aug 29, 2023
d743688
refactor: 보너스 볼 출력 & 금액 콤마 적용
yeonjy Aug 29, 2023
c202f47
feat: 수익률 출력 구현
yeonjy Aug 29, 2023
1e7e496
feat: 에러 메세지 출력 구현
yeonjy Aug 29, 2023
b4c76dd
style: 코드 정리
yeonjy Aug 29, 2023
a9aa8f6
refactor: IllegalArgumentException -> NoSuchElementException
yeonjy Aug 29, 2023
0a2b7c8
fix: Lotto 클래스 import
yeonjy Aug 29, 2023
43e1b99
docs: 로또 실행 결과
yeonjy Aug 29, 2023
ca92263
feat: 티켓 클래스 생성
yeonjy Aug 30, 2023
910c714
refactor: List<List<Integer>> -> List<LottoTicket>
yeonjy Aug 30, 2023
1e4e6e2
style: Lotto & LottoRangeNumber repository 패키지로 이동
yeonjy Aug 30, 2023
3d1fded
style: InputProcessor controller 패키지로 이동
yeonjy Aug 30, 2023
616fd21
style: 예외 문구 오타 수정
yeonjy Aug 30, 2023
7c77afb
test: 1000원 단위 구매 검증 테스트
yeonjy Aug 30, 2023
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
86 changes: 86 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# 기능 목록

---

## 입력
- [ ] 구입 금액 입력
- [ ] (예외처리) 숫자 여부 확인
- [ ] (예외처리) 1,000원 단위 확인
- [ ] 당첨 번호 입력
- [ ] (예외처리) 쉼표 기준 6개 확인
- [ ] (예외처리) 숫자 여부 확인
- [ ] (예외처리) 숫자 범위 1~45 확인
- [ ] 보너스 번호 입력
- [ ] (예외처리) 숫자 여부 확인
- [ ] (예외처리) 숫자 범위 1~45 확인

## 출력
- [ ] 발행 로또 수량 & 번호 출력
- [ ] 오름차순 정렬
- [ ] 당첨 내역 출력
- [ ] 수익률 출력
- [ ] 소수점 둘째 자리에서 반올림



## Application
- [x] 로또 프로그램 작동


### controller
## PlayController
- [x] 구입 금액 입력


## LottoAnswerController
- [x] 당첨 번호 입력
- [x] 보너스 번호


### dto
- [x] 로또 번호 6개 & 보너스 번호


### service
## PlayLottoService
- [x] 로또 번호 6개 & 보너스 번호 -> 하나의 DTO로 병합
- [x] 로또 추첨 로직 실행
- [x] 수익률 출력

## LottoTicketService
- [x] 구입 금액에 따른 로또 개수 계산
- [x] 구입 금액 1000원 단위 검증
- [x] 로또 구입 개수 출력
- [x] 로또 개수만큼 LottoNumberGenerator 호출
- [x] 로또 티켓 번호 출력

## OutcomeService
- [x] 일치 개수 계산
- [x] 3개 이상 일치한 로또 필터링
- [x] 총 수익금 계산



### repository
## LottoNumberGenerator
- [x] 로또 번호 생성

## Lotto
- [x] (예외처리) 숫자 6개 확인
- [x] (예외처리) 숫자 중복 없음 확인
- [x] (예외처리) 숫자 범위 1~45 확인

## BonusLotto
- [x] (예외처리) 숫자 범위 1~45 확인
- [x] (예외처리) 기존 6개 당첨 번호와 중복 없음 확인

## InputProcessor
- [x] 로또 구입 금액 & 보너스 번호 정수 변환
- [x] 당첨 번호 6개 정수 리스트 변환

## PrizeResult
- [x] 일치 개수 별 상금
- [x] 일치 개수 별 당첨 로또 개수



5 changes: 4 additions & 1 deletion src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package lotto;

import lotto.controller.PlayController;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
PlayController playController = new PlayController();
playController.start();
}
}
24 changes: 24 additions & 0 deletions src/main/java/lotto/ErrorMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package lotto;

public enum ErrorMessage {
NOT_SIX_NUMBERS("[ERROR] 당첨 번호는 6개를 입력해 주세요."),
DUPLICATED_NUMBERS("[ERROR] 당첨 번호의 중복을 제거해 주세요."),
OUT_OF_RANGE_NUMBER("[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다."),
NOT_NUMBER("[ERROR] 정확한 숫자를 입력해 주세요."),
INVALID_OF_MONEY_UNIT("[ERROR] 구입 금액은 1000원 단위로 입력해 주세요.");


private final String message;

ErrorMessage(final String message) {
this.message = message;
}

public String getMessage() {
return message;
}

public void print() {
System.out.println(message);
}
}
20 changes: 0 additions & 20 deletions src/main/java/lotto/Lotto.java

This file was deleted.

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

public enum PrizeMoney {
THREE_EQUAL_MONEY(5_000L),
FOUR_EQUAL_MONEY(50_000L),
FIVE_EQUAL_MONEY(1_500_000L),
BONUS_EQUAL_MONEY(30_000_000L),
SIX_EQUAL_MONEY(2_000_000_000L);

private final long number;

PrizeMoney(final long number) {
this.number = number;
}

public long getNumber() {
return number;
}

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

import lotto.dto.AllLottoes;
import lotto.repositroy.BonusLotto;
import lotto.repositroy.LottoTicket;
import lotto.service.MatchNum;

import java.util.*;

public class PrizeResult {
private static final int ZERO = 0;
private final Map<MatchNum, Integer> playResult = new EnumMap<>(MatchNum.class);
private final Map<MatchNum, PrizeMoney> prizeMoneyMap = new EnumMap<>(MatchNum.class);

public void initialize() {
initializePlayResult();
initializePrizeMoneyMap();
}

private void initializePlayResult() {
Arrays.stream(MatchNum.values()).forEach(m -> playResult.put(m, ZERO));
}

private void initializePrizeMoneyMap() {
Iterator<PrizeMoney> prizeMoneyIterator = Arrays.stream(PrizeMoney.values()).iterator();
for (MatchNum matchNum : MatchNum.values()) {
prizeMoneyMap.put(matchNum, prizeMoneyIterator.next());
}
}

public void makeResult(AllLottoes allLottoes, List<LottoTicket> tickets) {
for (LottoTicket ticket : tickets) {
MatchNum match = checkTicket(ticket.toList(), allLottoes);
if (match != null) {
playResult.put(match, playResult.get(match) + 1);
}
}
}

private MatchNum checkTicket(List<Integer> ticket, AllLottoes allLottoes) {
int count = (int) ticket.stream().filter(num -> allLottoes.getLotto().getNumbers().contains(num)).count();
if (count == MatchNum.FIVE_MATCH.getNum()) {
return checkBonusLotto(ticket, allLottoes.getBonusLotto());
}
return MatchNum.getOf(count);
}

private MatchNum checkBonusLotto(List<Integer> ticket, BonusLotto bonusLotto) {
if (isBonusLotto(ticket, bonusLotto)) {
return MatchNum.BONUS_MATCH;
}
return MatchNum.FIVE_MATCH;
}

private boolean isBonusLotto(List<Integer> ticket, BonusLotto bonusLotto) {
return ticket.contains(bonusLotto.getNumber());
}

public Map<MatchNum, Integer> getPlayResult() {
return playResult;
}

public Map<MatchNum, PrizeMoney> getPrizeMoneyMap() {
return prizeMoneyMap;
}
}
17 changes: 17 additions & 0 deletions src/main/java/lotto/controller/InputGuide.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package lotto.controller;

public enum InputGuide {
INPUT_MONEY("구입금액을 입력해 주세요."),
INPUT_LOTTO_ANSWER("당첨 번호를 입력해 주세요."),
INPUT_BONUS_ANSWER("보너스 번호를 입력해 주세요.");

private final String content;

InputGuide(final String content) {
this.content = content;
}

public String getContent() {
return content;
}
}
26 changes: 26 additions & 0 deletions src/main/java/lotto/controller/InputProcessor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package lotto.controller;

import lotto.ErrorMessage;

import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;

public class InputProcessor {
private static final String CRITERIA = ",";

public int changeToInt(String money) {
try {
return Integer.parseInt(money);
} catch (NumberFormatException e) {
ErrorMessage.NOT_NUMBER.print();
throw new NoSuchElementException(ErrorMessage.NOT_NUMBER.getMessage());
}
}

public List<Integer> changeToIntegerList(String s) {
return Arrays.stream(s.split(CRITERIA))
.map(Integer::parseInt).collect(Collectors.toList());
}
}
39 changes: 39 additions & 0 deletions src/main/java/lotto/controller/LottoAnswerController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package lotto.controller;

import camp.nextstep.edu.missionutils.Console;
import lotto.dto.AllLottoes;
import lotto.repositroy.LottoTicket;
import lotto.service.PlayLottoService;

import java.util.List;

public class LottoAnswerController {
private final InputProcessor inputProcessor;
private final PlayLottoService playLottoService;

public LottoAnswerController() {
this.inputProcessor = new InputProcessor();
this.playLottoService = new PlayLottoService();
}

public void playLotto(List<LottoTicket> tickets, double paidMoney) {
List<Integer> lottoAnswers = inputAnswerNumber();
int bonusAnswer = intputBonusNumber();

AllLottoes allLottoes = playLottoService.getAllLottoes(lottoAnswers, bonusAnswer);
long totalPrizeMoney = playLottoService.playLotto(allLottoes, tickets);

playLottoService.printEarningRate(totalPrizeMoney / paidMoney);
}

private List<Integer> inputAnswerNumber() {
System.out.println(InputGuide.INPUT_LOTTO_ANSWER.getContent());
return inputProcessor.changeToIntegerList(Console.readLine());
}

private int intputBonusNumber() {
System.out.println(InputGuide.INPUT_BONUS_ANSWER.getContent());
return inputProcessor.changeToInt(Console.readLine());
}

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

import camp.nextstep.edu.missionutils.Console;
import lotto.repositroy.LottoTicket;
import lotto.service.LottoTicketService;

import java.util.List;

public class PlayController {
private final LottoTicketService ticketService;
private final InputProcessor inputProcessor;
private final LottoAnswerController answerController;

public PlayController() {
this.ticketService = new LottoTicketService();
this.inputProcessor = new InputProcessor();
this.answerController = new LottoAnswerController();
}

public void start() {
int money = inputMoney();
List<LottoTicket> tickets = ticketService.createLottoTickets(money);
answerController.playLotto(tickets, money);
}

private int inputMoney() {
System.out.println(InputGuide.INPUT_MONEY.getContent());
return inputProcessor.changeToInt(Console.readLine());
}
}
22 changes: 22 additions & 0 deletions src/main/java/lotto/dto/AllLottoes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package lotto.dto;

import lotto.repositroy.BonusLotto;
import lotto.repositroy.Lotto;

public class AllLottoes {
private final Lotto lotto;
private final BonusLotto bonusLotto;

public AllLottoes(Lotto lotto, BonusLotto bonusLotto) {
this.lotto = lotto;
this.bonusLotto = bonusLotto;
}

public Lotto getLotto() {
return lotto;
}

public BonusLotto getBonusLotto() {
return bonusLotto;
}
}
Loading