Skip to content

Commit

Permalink
feat: 로또 당첨 등수 확인 로직 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
seong-wooo committed Mar 28, 2023
1 parent ebb73f7 commit f18032d
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 7 deletions.
37 changes: 33 additions & 4 deletions src/main/java/lotto/domain/Lotto.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package lotto.domain;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import lotto.domain.lottonumbercreator.LottoNumberCreator;
Expand All @@ -16,7 +15,7 @@ public Lotto(List<Integer> numbers) {
validateSize(numbers);
validateDuplicated(numbers);
validateNumbersRange(numbers);
this.numbers = new ArrayList<>(numbers);
this.numbers = numbers;
}

private void validateSize(List<Integer> numbers) {
Expand All @@ -43,10 +42,40 @@ public static Lotto from(LottoNumberCreator creator) {
return new Lotto(creator.create(MIN_LOTTO_NUMBER, MAX_LOTTO_NUMBER, LOTTO_NUMBERS_SIZE));
}

public boolean isPossible(Integer bonusBall) {
final boolean isInRange = bonusBall < MIN_LOTTO_NUMBER || bonusBall > MAX_LOTTO_NUMBER;
public boolean isPossible(int bonusBall) {
final boolean isInRange = bonusBall >= MIN_LOTTO_NUMBER && bonusBall <= MAX_LOTTO_NUMBER;
final boolean isNotLottoNumber = !numbers.contains(bonusBall);

return isInRange && isNotLottoNumber;
}

public boolean isFirstRank(Lotto lotto) {
return containCount(lotto) == LOTTO_NUMBERS_SIZE;
}

public boolean isThirdRank(Lotto lotto) {
return containCount(lotto) == LOTTO_NUMBERS_SIZE - 1 ;
}

public boolean isFourthRank(Lotto lotto) {
return containCount(lotto) == LOTTO_NUMBERS_SIZE - 2;
}

public boolean isFifthRank(Lotto lotto) {
return containCount(lotto) == LOTTO_NUMBERS_SIZE - 3;
}

public boolean isOutOfRank(Lotto lotto) {
return containCount(lotto) < LOTTO_NUMBERS_SIZE - 3;
}

private int containCount(Lotto other) {
return (int) other.numbers.stream()
.filter(this::contain)
.count();
}

public boolean contain(Integer number) {
return this.numbers.contains(number);
}
}
29 changes: 29 additions & 0 deletions src/main/java/lotto/domain/LottoRank.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package lotto.domain;

import java.util.Arrays;
import lotto.domain.rankvalidator.RankValidator;

public enum LottoRank {
FIRST(2_000_000_000, WinNumbers::isFirstRank),
SECOND(30_000_000, WinNumbers::isSecondRank),
THIRD(1_500_000, WinNumbers::isThirdRank),
FOURTH(50_000, WinNumbers::isFourthRank),
FIFTH(5_000, WinNumbers::isFifthRank),
OTHER(0, WinNumbers::isOutOfRank);


private final int prize;
private final RankValidator rankValidator;

LottoRank(int prize, RankValidator rankValidator) {
this.prize = prize;
this.rankValidator = rankValidator;
}

public static LottoRank calculateRank(WinNumbers winNumbers, Lotto lotto) {
return Arrays.stream(LottoRank.values())
.filter(rank -> rank.rankValidator.isRanked(winNumbers, lotto))
.findAny()
.orElseThrow(() -> new IllegalArgumentException("[ERROR] 일치하는 등수가 존재하지 않습니다"));
}
}
30 changes: 27 additions & 3 deletions src/main/java/lotto/domain/WinNumbers.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,41 @@ public class WinNumbers {

private final Lotto lotto;

private final Integer bonusBall;
private final int bonusBall;

public WinNumbers(Lotto lotto, Integer bonusBall) {
public WinNumbers(Lotto lotto, int bonusBall) {
validateBonusBall(lotto, bonusBall);
this.lotto = lotto;
this.bonusBall = bonusBall;
}

private void validateBonusBall(Lotto lotto, Integer bonusBall) {
private void validateBonusBall(Lotto lotto, int bonusBall) {
if (!lotto.isPossible(bonusBall)) {
throw new IllegalArgumentException(String.format("[ERROR] %d는 보너스 볼이 될 수 없습니다.", bonusBall));
}
}

public boolean isFirstRank(Lotto other) {
return this.lotto.isFirstRank(other);
}

public boolean isSecondRank(Lotto other) {
return this.lotto.isThirdRank(other) && other.contain(this.bonusBall);
}

public boolean isThirdRank(Lotto other) {
return this.lotto.isThirdRank(other) && !other.contain(this.bonusBall);
}

public boolean isFourthRank(Lotto other) {
return this.lotto.isFourthRank(other);
}

public boolean isFifthRank(Lotto other) {
return this.lotto.isFifthRank(other);
}

public boolean isOutOfRank(Lotto other) {
return this.lotto.isOutOfRank(other);
}
}
9 changes: 9 additions & 0 deletions src/main/java/lotto/domain/rankvalidator/RankValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package lotto.domain.rankvalidator;

import lotto.domain.Lotto;
import lotto.domain.WinNumbers;

public interface RankValidator {

boolean isRanked(WinNumbers winNumbers, Lotto lotto);
}
39 changes: 39 additions & 0 deletions src/test/java/lotto/domain/LottoRankTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package lotto.domain;

import java.util.List;
import java.util.stream.Stream;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

class LottoRankTest {

public static Stream<Arguments> findRank() {
return Stream.of(
Arguments.of(List.of(1, 2, 3, 4, 5, 6), LottoRank.FIRST),
Arguments.of(List.of(1, 2, 3, 4, 5, 7), LottoRank.SECOND),
Arguments.of(List.of(1, 2, 3, 4, 5, 8), LottoRank.THIRD),
Arguments.of(List.of(1, 2, 3, 4, 7, 8), LottoRank.FOURTH),
Arguments.of(List.of(1, 2, 3, 7, 8, 9), LottoRank.FIFTH),
Arguments.of(List.of(1, 2, 7, 8, 9, 10), LottoRank.OTHER)
);
}

@ParameterizedTest
@MethodSource("findRank")
void 로또_당첨_등수를_확인한다(List<Integer> numbers, LottoRank expect) {
// given
final Lotto winLotto = new Lotto(List.of(1, 2, 3, 4, 5, 6));
final int bonusBall = 7;
final WinNumbers winNumbers = new WinNumbers(winLotto, bonusBall);

final Lotto lotto = new Lotto(numbers);

// when
final LottoRank actual = LottoRank.calculateRank(winNumbers, lotto);

// then
Assertions.assertThat(actual).isEqualTo(expect);
}
}

0 comments on commit f18032d

Please sign in to comment.