From f18032d9c0986454f656e9a09f393acf17a697da Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Tue, 28 Mar 2023 17:01:23 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EB=8B=B9=EC=B2=A8?= =?UTF-8?q?=20=EB=93=B1=EC=88=98=20=ED=99=95=EC=9D=B8=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/domain/Lotto.java | 37 ++++++++++++++++-- src/main/java/lotto/domain/LottoRank.java | 29 ++++++++++++++ src/main/java/lotto/domain/WinNumbers.java | 30 ++++++++++++-- .../domain/rankvalidator/RankValidator.java | 9 +++++ src/test/java/lotto/domain/LottoRankTest.java | 39 +++++++++++++++++++ 5 files changed, 137 insertions(+), 7 deletions(-) create mode 100644 src/main/java/lotto/domain/LottoRank.java create mode 100644 src/main/java/lotto/domain/rankvalidator/RankValidator.java create mode 100644 src/test/java/lotto/domain/LottoRankTest.java diff --git a/src/main/java/lotto/domain/Lotto.java b/src/main/java/lotto/domain/Lotto.java index 89a3c3c3fc..9f8dd83128 100644 --- a/src/main/java/lotto/domain/Lotto.java +++ b/src/main/java/lotto/domain/Lotto.java @@ -1,6 +1,5 @@ package lotto.domain; -import java.util.ArrayList; import java.util.HashSet; import java.util.List; import lotto.domain.lottonumbercreator.LottoNumberCreator; @@ -16,7 +15,7 @@ public Lotto(List numbers) { validateSize(numbers); validateDuplicated(numbers); validateNumbersRange(numbers); - this.numbers = new ArrayList<>(numbers); + this.numbers = numbers; } private void validateSize(List numbers) { @@ -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); + } } diff --git a/src/main/java/lotto/domain/LottoRank.java b/src/main/java/lotto/domain/LottoRank.java new file mode 100644 index 0000000000..8a33bcbfb0 --- /dev/null +++ b/src/main/java/lotto/domain/LottoRank.java @@ -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] 일치하는 등수가 존재하지 않습니다")); + } +} diff --git a/src/main/java/lotto/domain/WinNumbers.java b/src/main/java/lotto/domain/WinNumbers.java index 68807fcb94..0b2298f879 100644 --- a/src/main/java/lotto/domain/WinNumbers.java +++ b/src/main/java/lotto/domain/WinNumbers.java @@ -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); + } } diff --git a/src/main/java/lotto/domain/rankvalidator/RankValidator.java b/src/main/java/lotto/domain/rankvalidator/RankValidator.java new file mode 100644 index 0000000000..7166c3615e --- /dev/null +++ b/src/main/java/lotto/domain/rankvalidator/RankValidator.java @@ -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); +} diff --git a/src/test/java/lotto/domain/LottoRankTest.java b/src/test/java/lotto/domain/LottoRankTest.java new file mode 100644 index 0000000000..9799473096 --- /dev/null +++ b/src/test/java/lotto/domain/LottoRankTest.java @@ -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 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 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); + } +}