Skip to content

[로또 게임 1단계] 리뷰 부탁드립니다 #11

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

Open
wants to merge 55 commits into
base: jiwoo-kimm
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
33a7d0d
docs: initial commit
jiwoo-kimm Jul 3, 2021
e9d2001
docs: 기능 구현 목록 작성
jiwoo-kimm Jul 3, 2021
05fbeba
feat:1000원 미만 입력 시 테스트메서드 작성
jiwoo-kimm Jul 3, 2021
538e6b8
feat: 1000의 배수 아닌 값 테스트메서드 작성
jiwoo-kimm Jul 3, 2021
96e6d63
feat: 금액 입력에 문자열 입력시 예외 처리 테스트 메서드 작성
jiwoo-kimm Jul 3, 2021
fd24a8d
refactor: perchasePrice, LottoController 생성
jiwoo-kimm Jul 3, 2021
862c243
refactor: 테스트 메서드 리팩토링
jiwoo-kimm Jul 3, 2021
27424d2
test: 공백 입력 처리 테스트 메서드 추가
jiwoo-kimm Jul 3, 2021
39be046
refactor: PurchasePrice -> PurchaseCount 변경
jiwoo-kimm Jul 3, 2021
c983156
feat: Lotto 클래스, 테스트클래스 생성
jiwoo-kimm Jul 3, 2021
f89c53e
feat: 로또 구매 개수만큼 생성해서 LottoSet에 저장
jiwoo-kimm Jul 3, 2021
27e69ac
feat: 당첨 번호 클래스 생성
jiwoo-kimm Jul 3, 2021
9680ee3
test: 숫자 개수 6개 확인 테스트 메서드 작성
chunghyeon-kimm Jul 5, 2021
8bd4e7f
test: 숫자가 아닌 값 입력 테스트 메서드 작성
chunghyeon-kimm Jul 5, 2021
3ee2d11
test: 로또 번호 입력범위 1~45 테스트 메서드 작성
chunghyeon-kimm Jul 5, 2021
0f0a9aa
feat: 당첨 조건 테스트 메서드 작성
chunghyeon-kimm Jul 5, 2021
6cb70d4
feat: 통계 클래스, 통계 테스트 클래스 추가
chunghyeon-kimm Jul 5, 2021
dcf4842
refactor: 패키지 구조 및 클래스 이름 변경
chunghyeon-kimm Jul 6, 2021
c512869
test: 보너스 번호 확인 테스트 작성
chunghyeon-kimm Jul 6, 2021
a6ef7de
feat: 로또 1 게임의 등수 계산
chunghyeon-kimm Jul 6, 2021
078bf69
feat: 로또 당첨 개수 구하기
chunghyeon-kimm Jul 7, 2021
4a83ad0
refactor: 테스트용 로또 클래스 생성
chunghyeon-kimm Jul 7, 2021
f8da3c5
feat: 총 상금액 계산 테스트 메서드 및 클래스 생성
chunghyeon-kimm Jul 7, 2021
a84a57e
feat: Controller, InputView, OutputView 1차 완성
chunghyeon-kimm Jul 7, 2021
016863a
refactor: DefaultNumbers 한 번만 생성하도록 수정
chunghyeon-kimm Jul 7, 2021
3b93395
refactor: Test 메서드 DisplayName 정리
chunghyeon-kimm Jul 7, 2021
ddff79a
refactor: DefaultNumbers 지네릭스 수정, 필요없는 클래스파일 삭제
chunghyeon-kimm Jul 7, 2021
e0d1880
refactor: View 로직과 가독성 개선
jiwoo-kimm Jul 7, 2021
f4d2c40
refactor: 리팩토링
jiwoo-kimm Jul 7, 2021
eaac136
refactor: 에러 메시지 출력 시 헤더 추가
jiwoo-kimm Jul 7, 2021
674ae96
refactor: Prize enum 하나로 합치기
jiwoo-kimm Jul 17, 2021
a0173ea
refactor: move Prize from constant package into domain package
jiwoo-kimm Jul 17, 2021
1bf5325
refactor: rename abbreviation calc into calculate
jiwoo-kimm Jul 17, 2021
ffed907
refactor: change parameter of WinningLotto constructor
jiwoo-kimm Jul 17, 2021
c48c8e1
refactor: abstract InputView and OutputView
jiwoo-kimm Jul 17, 2021
2c6da43
refactor: remove DTO postfix
jiwoo-kimm Jul 19, 2021
3e67178
refactor: remove unnecessary method wrapping
jiwoo-kimm Jul 19, 2021
8d185da
refactor: remove unncessary constants
jiwoo-kimm Jul 19, 2021
60c4c70
refactor: unwrap DefaultNumbers class into constant field of RandomLotto
jiwoo-kimm Jul 19, 2021
2119239
test: change Exception class type
jiwoo-kimm Jul 19, 2021
41d2147
refactor: rename non-negative integer validation
jiwoo-kimm Jul 19, 2021
36c204b
refactor: seperate exception cases of input for PurchaseCount
jiwoo-kimm Jul 19, 2021
1084404
refactor: merge RandomLottoSet into LottoSet
jiwoo-kimm Jul 19, 2021
2056c66
fix: prevent duplication of Lottos in LottoSet
jiwoo-kimm Jul 19, 2021
a44450b
refactor: validate input type at InputView not domain
jiwoo-kimm Jul 19, 2021
fb57be6
feat: validate duplication of LottoNumber in one Lotto
jiwoo-kimm Jul 19, 2021
a4809aa
refactor: rename fields of PrizeCount
jiwoo-kimm Jul 19, 2021
4357c37
refactor: remove unnecessary throws Exception
jiwoo-kimm Jul 19, 2021
d1e6740
test: move tests from WinningLottoTest to LottoTest and add validatio…
jiwoo-kimm Jul 19, 2021
0f0371e
refactor: add LottoMatcher to compare LottoSet and WinningLotto
jiwoo-kimm Jul 19, 2021
42ddc76
refactor: rename findPrize into getMatchPrize
jiwoo-kimm Jul 19, 2021
b65a98a
refactor: remove dependency between view and controller
jiwoo-kimm Jul 19, 2021
0f2c076
refactor: make Lotto unmodifiable
jiwoo-kimm Jul 19, 2021
eda9666
refactor: exception handling and print exception message
jiwoo-kimm Jul 19, 2021
ca56354
refactor: count match numbers with stream api
jiwoo-kimm Jul 19, 2021
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
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,30 @@
# java-lotto 게임
# java-Lotto 게임

# 구현 기능 목록
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

구현 기능 목록 작성 👍


- [x] 구입금액 입력받기
- [x] 1000원 미만 입력 시 처리
- [x] 1000의 배수 아닌 값 입력 시 처리
- [x] 숫자가 아닌 값 (문자열)
- [x] 정상값 처리
- [x] 공백 처리
- [x] 구매 개수 구하기
- [x] 랜덤 로또번호 구매 개수만큼 만들기
- [x] defaultNumberSet 1번만 생성되도록 변경
- [x] RandomLottoTest 상수 리팩토링
- [x] PurchaseCount의 1000 접근
- [x] 지난 주 당첨 번호 입력받기
- [x] WinningNumbers 멤버변수 ArrayList 클래스 확인
- [x] 숫자 개수 6개 확인
- [x] 숫자가 아닌 값 포함
- [x] 범위 (1~45) 확인
- [x] 공백 처리
- [x] 보너스 볼 입력받기
- [x] 당첨 통계
- [x] 당첨 조건을 enum 처리
- [x] 일치 개수 찾기
- [x] 5개 일치 시 보너스 볼 일치 여부 확인
- [x] 로또 당첨 개수 구하기
- [x] 당첨값의 합 구하기
- [x] 수익률 구하기
- [x] 결과 출력
7 changes: 7 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ repositories {
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter:5.6.0')
testImplementation('org.assertj:assertj-core:3.15.0')

compileOnly 'org.projectlombok:lombok:1.18.20'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

롬복 플러그인을 활용하셨네요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵! getter와 빌더 패턴을 사용하려고 활용했습니다

annotationProcessor 'org.projectlombok:lombok:1.18.20'

testCompileOnly 'org.projectlombok:lombok:1.18.20'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'

}

test {
Expand Down
Empty file removed src/main/java/empty.txt
Empty file.
33 changes: 33 additions & 0 deletions src/main/java/lotto/LottoApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package lotto;

import lotto.controller.LottoController;
import lotto.domain.dto.LottoResult;
import lotto.domain.dto.PurchaseInput;
import lotto.domain.dto.PurchaseResult;
import lotto.domain.dto.WinningLottoInput;
import lotto.exception.ExceptionMessage;
import lotto.view.ConsoleInputView;
import lotto.view.ConsoleOutputView;
import lotto.view.View;

public class LottoApplication {

public static void main(String[] args) {
View view = new View(new ConsoleInputView(), new ConsoleOutputView());
LottoController lottoController = new LottoController();

try {
PurchaseInput purchaseInput = view.getPurchasePrice();
PurchaseResult purchaseResult = lottoController.purchase(purchaseInput);
view.printLottoPurchaseResult(purchaseResult);

WinningLottoInput winningLottoInput = view.getWinningLottoAndBonus();
LottoResult lottoResult = lottoController.calculateResult(purchaseResult, winningLottoInput);
view.printLottoStatistics(lottoResult);
} catch (NumberFormatException e) {
view.printException(ExceptionMessage.NON_NUMBER_INPUT.getMessage());
} catch (IllegalArgumentException e) {
view.printException(e.getMessage());
}
}
}
24 changes: 24 additions & 0 deletions src/main/java/lotto/controller/LottoController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package lotto.controller;

import lotto.domain.dto.LottoResult;
import lotto.domain.dto.PurchaseInput;
import lotto.domain.dto.PurchaseResult;
import lotto.domain.dto.WinningLottoInput;
import lotto.service.LottoService;

public class LottoController {

private final LottoService lottoService;

public LottoController() {
this.lottoService = new LottoService();
}

public PurchaseResult purchase(PurchaseInput purchaseInput) throws IllegalArgumentException {
return lottoService.purchase(purchaseInput);
}

public LottoResult calculateResult(PurchaseResult purchaseResult, WinningLottoInput winningLottoInput) throws IllegalArgumentException {
return lottoService.calculateResult(purchaseResult, winningLottoInput);
}
}
51 changes: 51 additions & 0 deletions src/main/java/lotto/domain/Lotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package lotto.domain;

import lombok.Getter;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static lotto.exception.ExceptionMessage.DUPLICATE_LOTTO_NUMBER_INPUT_FOR_LOTTO;
import static lotto.exception.ExceptionMessage.INVALID_LENGTH_INPUT_FOR_LOTTO;

public class Lotto {

public static final int PRICE = 1000;
public static final int LOTTO_NUMBER_SIZE = 6;

@Getter
private final List<LottoNumber> lottoNumbers;

public Lotto(List<Integer> numbers) throws IllegalArgumentException {
validate(numbers);

numbers.sort(Integer::compare);
this.lottoNumbers = Collections.unmodifiableList(numbers.stream()
.map(LottoNumber::new)
.collect(Collectors.toList()));
}

private void validate(List<Integer> numbers) throws IllegalArgumentException {
if (numbers.size() != Lotto.LOTTO_NUMBER_SIZE) {
throw new IllegalArgumentException(INVALID_LENGTH_INPUT_FOR_LOTTO.getMessage());
}
if (numbers.size() != numbers.stream().distinct().count()) {
throw new IllegalArgumentException(DUPLICATE_LOTTO_NUMBER_INPUT_FOR_LOTTO.getMessage());
}
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Lotto lotto = (Lotto) o;
return Objects.equals(lottoNumbers, lotto.lottoNumbers);
}

@Override
public int hashCode() {
return Objects.hash(lottoNumbers);
}
}
31 changes: 31 additions & 0 deletions src/main/java/lotto/domain/LottoMatcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package lotto.domain;

public class LottoMatcher {

private final WinningLotto winningLotto;
private final LottoSet lottoSet;

public LottoMatcher(WinningLotto winningLotto, LottoSet lottoSet) {
this.winningLotto = winningLotto;
this.lottoSet = lottoSet;
}

public PrizeCount countPrizes() {
PrizeCount prizeCount = new PrizeCount();
for (Lotto lotto : lottoSet.getLottoSet()) {
Prize prize = Prize.getMatchPrize(getMatchNumbersCount(lotto), isBonusMatch(lotto));
prizeCount.addPrize(prize);
}
return prizeCount;
}

private int getMatchNumbersCount(Lotto targetLotto) {
return (int) targetLotto.getLottoNumbers().stream()
.filter(lottoNumber -> winningLotto.getLottoNumbers().contains(lottoNumber))
.count();
}

private boolean isBonusMatch(Lotto targetLotto) {
return targetLotto.getLottoNumbers().contains(winningLotto.getBonusNumber());
}
}
53 changes: 53 additions & 0 deletions src/main/java/lotto/domain/LottoNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package lotto.domain;

import lombok.Getter;

import java.util.Objects;

import static lotto.exception.ExceptionMessage.OUT_OF_BOUND_INPUT_FOR_LOTTO_NUMBER;

public class LottoNumber {

public static final int LOWER_BOUND = 1;
public static final int UPPER_BOUND = 45;

@Getter
private final int lottoNumber;

public LottoNumber(int lottoNumber) throws IllegalArgumentException {
validate(lottoNumber);

this.lottoNumber = lottoNumber;
}

private void validate(int lottoNumber) throws IllegalArgumentException {
if (isOutOfBound(lottoNumber)) {
throw new IllegalArgumentException(OUT_OF_BOUND_INPUT_FOR_LOTTO_NUMBER.getMessage());
}
}

private boolean isOutOfBound(int lottoNumber) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

return lottoNumber < LOWER_BOUND || lottoNumber > UPPER_BOUND;
}

public boolean isGreaterThan(LottoNumber winningNumber) {
return this.getLottoNumber() > winningNumber.getLottoNumber();
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LottoNumber that = (LottoNumber) o;
return lottoNumber == that.lottoNumber;
}

@Override
public int hashCode() {
return Objects.hash(lottoNumber);
}
}
29 changes: 29 additions & 0 deletions src/main/java/lotto/domain/LottoSet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package lotto.domain;

import lombok.Getter;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class LottoSet {

@Getter
private final Set<Lotto> lottoSet;

public LottoSet(Set<Lotto> lottoSet) {
this.lottoSet = Collections.unmodifiableSet(lottoSet);
}

public LottoSet(PurchaseCount purchaseCount) {
this(generateRandomLottoSet(purchaseCount));
}

private static Set<Lotto> generateRandomLottoSet(PurchaseCount purchaseCount) {
Set<Lotto> lottoSet = new HashSet<>();
while (lottoSet.size() < purchaseCount.getPurchaseCount()) {
lottoSet.add(new RandomLotto());
}
return lottoSet;
}
}
22 changes: 22 additions & 0 deletions src/main/java/lotto/domain/LottoStatistics.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package lotto.domain;

import lombok.Builder;
import lombok.Getter;

public class LottoStatistics {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

통계를 담는 객체를 만든 것 아주 좋습니다 👍


@Getter
private final PrizeCount prizeCount;
private final PurchaseCount purchaseCount;

@Builder
public LottoStatistics(PrizeCount prizeCount, PurchaseCount purchaseCount) {
this.prizeCount = prizeCount;
this.purchaseCount = purchaseCount;
}

public double calculateProfitRate() {
return (double) Prize.sumOfPrizeMoney(prizeCount)
/ (purchaseCount.getPurchaseCount() * Lotto.PRICE);
}
}
55 changes: 55 additions & 0 deletions src/main/java/lotto/domain/Prize.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package lotto.domain;

import lombok.Getter;

@Getter
public enum Prize {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enum 활용 👏


FIRST(6, false, 2000000000),
SECOND(5, true, 30000000),
THIRD(5, false, 1500000),
FOURTH(4, false, 50000),
FIFTH(3, false, 5000),
LOSE(2, false, 0);

private final int matchNumbersCount;
private final boolean isBonus;
private final long prizeMoney;

Prize(int matchNumbersCount, boolean isBonus, long prizeMoney) {
this.matchNumbersCount = matchNumbersCount;
this.isBonus = isBonus;
this.prizeMoney = prizeMoney;
}

public static Prize getMatchPrize(int matchNumbersCount, boolean isBonus) {
if (matchNumbersCount <= LOSE.matchNumbersCount) {
return LOSE;
}
if (matchNumbersCount == FIFTH.matchNumbersCount) {
return FIFTH;
}
if (matchNumbersCount == FOURTH.matchNumbersCount) {
return FOURTH;
}
if (matchNumbersCount == FIRST.matchNumbersCount) {
return FIRST;
}
return dissolveSecondOrThird(isBonus);
}

private static Prize dissolveSecondOrThird(boolean isBonus) {
if (isBonus) {
return Prize.SECOND;
}
return Prize.THIRD;
}

public static long sumOfPrizeMoney(PrizeCount prizeCount) {
return prizeCount.getFirst() * FIRST.prizeMoney
+ prizeCount.getSecond() * SECOND.prizeMoney
+ prizeCount.getThird() * THIRD.prizeMoney
+ prizeCount.getFourth() * FOURTH.prizeMoney
+ prizeCount.getFifth() * FIFTH.prizeMoney;
}
}
35 changes: 35 additions & 0 deletions src/main/java/lotto/domain/PrizeCount.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package lotto.domain;

import lombok.Getter;

@Getter
public class PrizeCount {

private int first;
private int second;
private int third;
private int fourth;
private int fifth;

public void addPrize(Prize prize) {
if (prize == Prize.FIRST) {
first++;
return;
}
if (prize == Prize.SECOND) {
second++;
return;
}
if (prize == Prize.THIRD) {
third++;
return;
}
if (prize == Prize.FOURTH) {
fourth++;
return;
}
if (prize == Prize.FIFTH) {
fifth++;
}
}
}
Loading