diff --git a/README.md b/README.md index c9895841301..2dee1b72c5f 100644 --- a/README.md +++ b/README.md @@ -23,5 +23,9 @@ - [x] 1 ~ 45 범위의 랜덤한 숫자 6개를 뽑는다. - [x] 위 숫자 리스트 생산 비용을 1000으로 책정하여, 전달받은 금액만큼 생성한다. - [x] 당첨 번호와 숫자 일치 개수를 확인하여 당첨 통계를 낸다. -- [ ] 수익률을 계산한다. +- [x] 수익률을 계산한다. - [x] 해당 결과를 콘솔에 출력한다. + +### Step 3 +- [x] 보너스 번호를 입력받는다. +- [x] 보너스 번호로 2등 여부를 확인한다. diff --git a/src/main/java/step2/controller/LottoGameController.java b/src/main/java/step2/controller/LottoGameController.java index 0e36132e948..33788ce951f 100644 --- a/src/main/java/step2/controller/LottoGameController.java +++ b/src/main/java/step2/controller/LottoGameController.java @@ -23,20 +23,19 @@ public void playLottoGame() { List lottoTickets = lottoGames.buyLottoGame(gameCount); ResultView.printLottoTicket(lottoTickets); - LottoTicket winningNumber = lottoGames.readWinningNumber(InputView.readWinningNumbers()); + LottoTicket winningTicket = lottoGames.readWinningNumber(InputView.readWinningNumbers()); + int bonusNumber = InputView.readBonusNumber(); ResultView.printBlankLine(); ResultView.printMessage("당첨 통계"); LottoResultReport lottoResultReport = new LottoResultReport(); for (LottoTicket lottoTicket : lottoTickets) { - lottoResultReport.recordRank(winningNumber.countMatchingNumbers(lottoTicket)); + lottoResultReport.recordRank(lottoTicket.checkLottoTicket(winningTicket, bonusNumber)); } ResultView.printResultReport(lottoResultReport); double profit = lottoResultReport.calculateProfit(gameCount); ResultView.printMessage("총 수익률은 " + profit + "입니다."); - } - } diff --git a/src/main/java/step2/domain/LottoResultReport.java b/src/main/java/step2/domain/LottoResultReport.java index ba75c1ead18..ef077cd64d6 100644 --- a/src/main/java/step2/domain/LottoResultReport.java +++ b/src/main/java/step2/domain/LottoResultReport.java @@ -6,29 +6,20 @@ public class LottoResultReport { - static final int ZERO = 0; - - private Map lottoResultReport; + private Map lottoResultReport; public LottoResultReport() { lottoResultReport = new HashMap<>(); } - public int recordRank(PrizeMoney prizeMoney) { - if (lottoResultReport.containsKey(prizeMoney)) { - Integer cnt = lottoResultReport.get(prizeMoney); - lottoResultReport.put(prizeMoney, cnt + 1); - return cnt; - } - lottoResultReport.put(prizeMoney, 1); - return 1; + public int recordRank(Rank rank) { + Integer value = lottoResultReport.getOrDefault(rank, 0); + lottoResultReport.put(rank, value + 1); + return lottoResultReport.get(rank); } - public int findReportByMatchCount(PrizeMoney prizeMoney) { - if (lottoResultReport.containsKey(prizeMoney)) { - return lottoResultReport.get(prizeMoney); - } - return ZERO; + public int findReportByMatchCount(Rank rank) { + return lottoResultReport.getOrDefault(rank, 0); } public double calculateProfit(int gameCount) { @@ -38,7 +29,7 @@ public double calculateProfit(int gameCount) { } long sum() { - Set> entries = lottoResultReport.entrySet(); + Set> entries = lottoResultReport.entrySet(); return entries.stream().mapToLong(e -> e.getKey().prizeMoney() * e.getValue()).sum(); } diff --git a/src/main/java/step2/domain/LottoTicket.java b/src/main/java/step2/domain/LottoTicket.java index 1d5318485a4..03de60ec331 100644 --- a/src/main/java/step2/domain/LottoTicket.java +++ b/src/main/java/step2/domain/LottoTicket.java @@ -29,11 +29,16 @@ public boolean isContain(Integer number) { return this.lottoTicket.contains(number); } - public PrizeMoney countMatchingNumbers(LottoTicket compareTarget) { + public Rank checkLottoTicket(LottoTicket winningTicket, int bonusNumber) { int count = (int) lottoTicket.stream() - .filter(i -> compareTarget.isContain(i)) + .filter(i -> winningTicket.isContain(i)) .count(); - return PrizeMoney.toPrizeMoney(count); + + if(count == 5 && isContain(bonusNumber)) { + return Rank.SECOND; + } + + return Rank.toPrizeMoney(count); } public String printTicket() { diff --git a/src/main/java/step2/domain/PrizeMoney.java b/src/main/java/step2/domain/PrizeMoney.java deleted file mode 100644 index 1e4cd232ec8..00000000000 --- a/src/main/java/step2/domain/PrizeMoney.java +++ /dev/null @@ -1,37 +0,0 @@ -package step2.domain; - -import java.security.InvalidParameterException; -import java.util.Arrays; - -public enum PrizeMoney { - ZERO(0, 0), - ONE(1, 0), - TWO(2, 0), - THREE(3, 5000), - FORTH(4, 50000), - FIVE(5, 1500000), - SIX(6, 2000000000); - - private int matchCount; - private long prizeMoney; - - PrizeMoney(int matchCount, long prizeMoney) { - this.matchCount = matchCount; - this.prizeMoney = prizeMoney; - } - - public static PrizeMoney toPrizeMoney(int matchCount) { - return Arrays.stream(values()) - .filter(prizeMoney -> prizeMoney.matchCount == matchCount) - .findAny() - .orElseThrow(() -> new InvalidParameterException()); - } - - public int matchCount() { - return matchCount; - } - - public long prizeMoney() { - return prizeMoney; - } -} diff --git a/src/main/java/step2/domain/Rank.java b/src/main/java/step2/domain/Rank.java new file mode 100644 index 00000000000..47335eab13b --- /dev/null +++ b/src/main/java/step2/domain/Rank.java @@ -0,0 +1,49 @@ +package step2.domain; + +import java.security.InvalidParameterException; +import java.util.Arrays; + +public enum Rank { + MISS(0, 0, "0개 일치 (0)"), + FIFTH(3, 5_000, "3개 일치 (5000)"), + FOURTH(4, 50_000, "4개 일치 (50000)"), + THIRD(5, 1_500_000, "5개 일치 (1500000)"), + SECOND(5, 30_000_000, "5개 일치, 보너스 볼 일치(30000000원)"), + FIRST(6, 2_000_000_000, "6개 일치 (2000000000)"); + + private static final int THIRD_COUNT = 5; + + private int matchCount; + private long prizeMoney; + + private String message; + + Rank(int matchCount, long rank, String message) { + this.matchCount = matchCount; + this.prizeMoney = rank; + this.message = message; + } + + public static Rank toPrizeMoney(int matchCount) { + if (matchCount == THIRD_COUNT) { + return Rank.THIRD; + } + + return Arrays.stream(values()) + .filter(prizeMoney -> prizeMoney.matchCount == matchCount) + .findAny() + .orElse(Rank.MISS); + } + + public int matchCount() { + return this.matchCount; + } + + public long prizeMoney() { + return this.prizeMoney; + } + + public String message() { + return this.message; + } +} diff --git a/src/main/java/step2/view/InputView.java b/src/main/java/step2/view/InputView.java index d4a228c286f..8af390ef271 100644 --- a/src/main/java/step2/view/InputView.java +++ b/src/main/java/step2/view/InputView.java @@ -10,6 +10,10 @@ public static int readAmountOfPurchase() { return readInt("구매 금액을 입력해 주세요"); } + public static int readBonusNumber() { + return readInt("보너스 볼을 입력해 주세요."); + } + private static int readInt(String message) { System.out.println(message); return toInt(scanner.nextLine()); diff --git a/src/main/java/step2/view/ResultView.java b/src/main/java/step2/view/ResultView.java index d4ebcb317a1..5eaa427fce2 100644 --- a/src/main/java/step2/view/ResultView.java +++ b/src/main/java/step2/view/ResultView.java @@ -2,15 +2,12 @@ import step2.domain.LottoResultReport; import step2.domain.LottoTicket; -import step2.domain.PrizeMoney; +import step2.domain.Rank; import java.util.List; public class ResultView { - private static final int MINIMUM_MATH_COUNT = 3; - private static final int MAXIMUM_MATH_COUNT = 6; - public static void printMessage(String message) { System.out.println(message); } @@ -27,9 +24,16 @@ public static void printLottoTicket(List lottoTickets) { } public static void printResultReport(LottoResultReport lottoResultReport) { - for (int i = MINIMUM_MATH_COUNT; i < MAXIMUM_MATH_COUNT + 1; i++) { - PrizeMoney prizeMoney = PrizeMoney.toPrizeMoney(i); - printMessage(i + "개 일치 (" + PrizeMoney.toPrizeMoney(i).prizeMoney() + ") - " + lottoResultReport.findReportByMatchCount(prizeMoney) + "개"); + Rank[] values = Rank.values(); + for (Rank rank : values) { + printEachLottoRank(lottoResultReport, rank); + } + } + + private static void printEachLottoRank(LottoResultReport lottoResultReport, Rank rank) { + if (rank == Rank.MISS) { + return; } + printMessage(rank.message() + " - " + lottoResultReport.findReportByMatchCount(rank) + "개"); } } diff --git a/src/test/java/step2/domain/LottoResultReportTest.java b/src/test/java/step2/domain/LottoResultReportTest.java index 4043655573e..162f4d08a28 100644 --- a/src/test/java/step2/domain/LottoResultReportTest.java +++ b/src/test/java/step2/domain/LottoResultReportTest.java @@ -21,11 +21,11 @@ class LottoResultReportTest { List matchCountList = Arrays.asList(3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6); for (Integer count : matchCountList) { - lottoResultReport.recordRank(PrizeMoney.toPrizeMoney(count)); + lottoResultReport.recordRank(Rank.toPrizeMoney(count)); } for (int i = 3; i < 7; i++) { - assertThat(lottoResultReport.findReportByMatchCount(PrizeMoney.toPrizeMoney(i))).isEqualTo(i); + assertThat(lottoResultReport.findReportByMatchCount(Rank.toPrizeMoney(i))).isEqualTo(i); } } @@ -36,7 +36,7 @@ class LottoResultReportTest { LottoResultReport lottoResultReport = new LottoResultReport(); for (int i = 1; i <= 6; i++) { if (matchCounts[i] == 0) continue; - lottoResultReport.recordRank(PrizeMoney.toPrizeMoney(i)); + lottoResultReport.recordRank(Rank.toPrizeMoney(i)); } assertThat(lottoResultReport.sum()).isEqualTo(expected); } diff --git a/src/test/java/step2/domain/LottoTicketTest.java b/src/test/java/step2/domain/LottoTicketTest.java index 53db537ec43..038504737ad 100644 --- a/src/test/java/step2/domain/LottoTicketTest.java +++ b/src/test/java/step2/domain/LottoTicketTest.java @@ -18,7 +18,7 @@ class LottoTicketTest { @MethodSource("winningNumbersSample") public void 로또_숫자_일치_개수_비교(List winningNumbers, int matchCount) throws Exception { LottoTicket lottoTicket = new LottoTicket(Arrays.asList(1, 12, 22, 23, 34, 44)); - assertThat(lottoTicket.countMatchingNumbers(new LottoTicket(winningNumbers))).isEqualTo(PrizeMoney.toPrizeMoney(matchCount)); + assertThat(lottoTicket.checkLottoTicket(new LottoTicket(winningNumbers), 0)).isEqualTo(Rank.toPrizeMoney(matchCount)); } static Stream winningNumbersSample() throws Throwable { @@ -32,4 +32,19 @@ static Stream winningNumbersSample() throws Throwable { ); } + @DisplayName("2등 당첨 케이스를 테스트한다.") + @ParameterizedTest + @MethodSource("secondRankSample") + public void 로또_2등_당첨(List numbers, List winningNumbers, int bonusNumber) throws Exception { + LottoTicket winningTicket = new LottoTicket(winningNumbers); + assertThat(new LottoTicket(numbers).checkLottoTicket(winningTicket, bonusNumber)).isEqualTo(Rank.SECOND); + } + + static Stream secondRankSample() throws Throwable { + return Stream.of( + Arguments.of(Arrays.asList(1, 12, 13, 14, 27, 45), Arrays.asList(10, 12, 13, 14, 27, 45), 1), + Arguments.of(Arrays.asList(7, 8, 17, 18, 32, 33), Arrays.asList(7, 8, 17, 29, 32, 33), 18), + Arguments.of(Arrays.asList(10, 16, 21, 24, 39, 40), Arrays.asList(10, 16, 21, 24, 39, 41), 40) + ); + } } diff --git a/src/test/java/step2/domain/PrizeMoneyTest.java b/src/test/java/step2/domain/RankTest.java similarity index 82% rename from src/test/java/step2/domain/PrizeMoneyTest.java rename to src/test/java/step2/domain/RankTest.java index 92d7a920ba0..021e19d0932 100644 --- a/src/test/java/step2/domain/PrizeMoneyTest.java +++ b/src/test/java/step2/domain/RankTest.java @@ -6,13 +6,13 @@ import static org.assertj.core.api.Assertions.assertThat; -class PrizeMoneyTest { +class RankTest { @DisplayName("숫자 일치 갯수별 당첨 상금을 확인한다.") @ParameterizedTest @CsvSource(value = {"6:2000000000", "5:1500000", "4:50000", "3:5000", "2:0", "1:0"}, delimiter = ':') public void 당첨금_확인(int rank, long prizeMoney) throws Exception { - assertThat(PrizeMoney.toPrizeMoney(rank).prizeMoney()).isEqualTo(prizeMoney); + assertThat(Rank.toPrizeMoney(rank).prizeMoney()).isEqualTo(prizeMoney); } }