Skip to content

Commit

Permalink
feat: 4단계 로또 수동 (#2816)
Browse files Browse the repository at this point in the history
* feat: 4단계 로또 수동(#2810)

* squash commit

Co-authored-by: annelguplus <annelguplus@gmail.com>
  • Loading branch information
AnneMayor and annelguplus authored Nov 17, 2022
1 parent cb97e23 commit 298ad08
Show file tree
Hide file tree
Showing 19 changed files with 444 additions and 77 deletions.
4 changes: 2 additions & 2 deletions src/main/java/JavaLottoApplication.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import ui.AutoResultView;
import ui.ManualResultView;
import ui.common.ResultView;

public class JavaLottoApplication {
public static void main(String... args) {
ResultView.lottoResult(new AutoResultView());
ResultView.lottoResult(new ManualResultView());
}
}
23 changes: 16 additions & 7 deletions src/main/java/constant/Rank.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
package constant;

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

public enum Rank {
FIRST(2000000000L),
SECOND(1500000L),
SECOND_WITH_BONUS(30000000L),
THIRD(50000L),
FOURTH(5000L),
UNKNOWN(0L);
FIRST(6, 2000000000L),
SECOND(5, 1500000L),
SECOND_WITH_BONUS(7, 30000000L),
THIRD(4, 50000L),
FOURTH(3, 5000L),
UNKNOWN(0, 0L);

private final int countOfMatchedNumber;
private final long reward;

Rank(long reward) {
Rank(int countOfMatchedNumber, long reward) {
this.countOfMatchedNumber = countOfMatchedNumber;
this.reward = reward;
}

public static Rank findRank(int countOfMatchedNumber) {
return Arrays.stream(Rank.values()).filter(rank -> rank.countOfMatchedNumber == countOfMatchedNumber).collect(Collectors.toList()).get(0);
}

public long findReward() {
return reward;
}
Expand Down
38 changes: 38 additions & 0 deletions src/main/java/domain/lottery/LotteryNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package domain.lottery;

import java.util.Objects;

public class LotteryNumber {
private static final int MIN_NUMBER = 1;
private static final int MAX_NUMBER = 45;
private final int number;

private LotteryNumber(int number) {
this.number = number;

if (number < MIN_NUMBER || number > MAX_NUMBER) {
throw new IllegalArgumentException("유효하지 않은 번호입니다.");
}
}

public static LotteryNumber of(int number) {
return new LotteryNumber(number);
}

public int number() {
return number;
}

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

@Override
public int hashCode() {
return Objects.hash(number);
}
}
24 changes: 21 additions & 3 deletions src/main/java/domain/lottery/LotteryTicket.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,33 @@
package domain.lottery;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class LotteryTicket {
private final List<Integer> ticketNumbers;
private final List<LotteryNumber> ticketNumbers;

public LotteryTicket(List<Integer> ticketNumbers) {
private static final int COUNT_OF_LOTTERY_NUMBERS = 6;

private LotteryTicket(List<LotteryNumber> ticketNumbers) {
this.ticketNumbers = ticketNumbers;

ticketNumbers = ticketNumbers.stream().distinct().collect(Collectors.toList());

if (ticketNumbers.size() < COUNT_OF_LOTTERY_NUMBERS) {
throw new IllegalArgumentException("복권번호가 중복됩니다.");
}
}

public List<Integer> getTicketNumbers() {
public static LotteryTicket of(List<LotteryNumber> ticketNumbers) {
return new LotteryTicket(Optional.ofNullable(ticketNumbers).get());
}

public List<LotteryNumber> getTicketNumbers() {
return ticketNumbers;
}

public void add(LotteryNumber lotteryNumber) {
ticketNumbers.add(lotteryNumber);
}
}
13 changes: 12 additions & 1 deletion src/main/java/domain/lottery/LotteryTickets.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,25 @@ public LotteryTickets(long amount) {
int countOfLotteryTickets = (int) Calculator.divide(amount, DEFAULT_LOTTERY_TICKET_PRICE);
lotteryTickets = new ArrayList<>(countOfLotteryTickets);
for (long count = 1; count <= countOfLotteryTickets; count++) {
lotteryTickets.add(new LotteryTicket(RandomNumberGenerator.generateNumbers()));
lotteryTickets.add(LotteryTicket.of(RandomNumberGenerator.generateNumbers()));
}
}

public LotteryTickets(int numberOfLotteryTickets) {
lotteryTickets = new ArrayList<>(numberOfLotteryTickets);
for (long count = 1; count <= numberOfLotteryTickets; count++) {
lotteryTickets.add(LotteryTicket.of(RandomNumberGenerator.generateNumbers()));
}
}

public LotteryTickets(List<LotteryTicket> lotteryTickets) {
this.lotteryTickets = lotteryTickets;
}

public void add(LotteryTicket lotteryTicket) {
lotteryTickets.add(lotteryTicket);
}

public List<LotteryTicket> getLotteryTickets() {
return lotteryTickets;
}
Expand Down
16 changes: 1 addition & 15 deletions src/main/java/domain/lottery/RewardLotteryTickets.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import java.util.ArrayList;
import java.util.List;

import static constant.LotteryRules.*;

public class RewardLotteryTickets {
private final List<Rank> ranks;
Expand All @@ -22,20 +21,7 @@ public RewardLotteryTickets(LotteryTickets lotteryTickets, WinnerLotteryTicket w
}

public long countOfRank(int countOfMatchedNumber) {
switch (countOfMatchedNumber) {
case NUMBER_OF_MATCHED_TICKET_NUMBER_FOR_FOURTH_PLACE:
return ranks.stream().filter(rank -> rank == Rank.FOURTH).count();
case NUMBER_OF_MATCHED_TICKET_NUMBER_FOR_THIRD_PLACE:
return ranks.stream().filter(rank -> rank == Rank.THIRD).count();
case NUMBER_OF_MATCHED_TICKET_NUMBER_FOR_SECOND_PLACE:
return ranks.stream().filter(rank -> rank == Rank.SECOND).count();
case NUMBER_OF_MATCHED_TICKET_NUMBER_FOR_SECOND_WITH_BONUS_PLACE:
return ranks.stream().filter(rank -> rank == Rank.SECOND_WITH_BONUS).count();
case NUMBER_OF_MATCHED_TICKET_NUMBER_FOR_FIRST_PLACE:
return ranks.stream().filter(rank -> rank == Rank.FIRST).count();
default:
return ranks.stream().filter(rank -> rank == Rank.UNKNOWN).count();
}
return ranks.stream().filter(rank -> rank == Rank.findRank(countOfMatchedNumber)).count();
}

public long sumAllRewards() {
Expand Down
13 changes: 9 additions & 4 deletions src/main/java/domain/lottery/WinnerLotteryTicket.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@

public class WinnerLotteryTicket {
private final LotteryTicket winnerLotteryTicket;
private final int bonusTicketNumber;
private final LotteryNumber bonusTicketNumber;

public WinnerLotteryTicket(LotteryTicket winnerTicket, int bonusTicketNumber) {
public WinnerLotteryTicket(LotteryTicket winnerTicket, LotteryNumber bonusTicketNumber) {
this.winnerLotteryTicket = winnerTicket;
this.bonusTicketNumber = bonusTicketNumber;

if (winnerLotteryTicket.getTicketNumbers().contains(bonusTicketNumber)) {
throw new IllegalArgumentException("당첨번호와 보너스 번호가 중복됩니다.");
}
}

public boolean hasBonusTicketNumber(LotteryTicket lotteryTicket) {
return lotteryTicket.getTicketNumbers().stream().anyMatch(number -> number == bonusTicketNumber);
return lotteryTicket.getTicketNumbers().stream().anyMatch(lotteryNumber -> lotteryNumber.equals(bonusTicketNumber));
}

public Rank findRank(LotteryTicket lotteryTicket) {
int countOfMatchedNumber = (int) lotteryTicket.getTicketNumbers().stream().filter(winnerLotteryTicket.getTicketNumbers()::contains).count();
if (lotteryTicket.getTicketNumbers().contains(bonusTicketNumber) && countOfMatchedNumber < NUMBER_OF_MATCHED_TICKET_NUMBER_FOR_FIRST_PLACE) countOfMatchedNumber += 2;
if (lotteryTicket.getTicketNumbers().contains(bonusTicketNumber) && countOfMatchedNumber == NUMBER_OF_MATCHED_TICKET_NUMBER_FOR_SECOND_PLACE)
countOfMatchedNumber += 2;
switch (countOfMatchedNumber) {
case NUMBER_OF_MATCHED_TICKET_NUMBER_FOR_FOURTH_PLACE:
return Rank.FOURTH;
Expand Down
7 changes: 2 additions & 5 deletions src/main/java/ui/AutoResultView.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package ui;

import domain.lottery.RewardLotteryTickets;
import domain.lottery.*;
import service.LotteryService;
import ui.common.InputView;
import ui.common.Result;
import domain.lottery.LotteryTicket;
import domain.lottery.LotteryTickets;
import domain.lottery.WinnerLotteryTicket;
import util.Calculator;
import util.Converter;

Expand Down Expand Up @@ -45,7 +42,7 @@ public void printTicketNumbers() {

System.out.println("보너스 볼을 입력해 주세요.");
int bonusTicketNumber = InputView.inputInteger();
winnerLotteryTicket = new WinnerLotteryTicket(winnerTicket, bonusTicketNumber);
winnerLotteryTicket = new WinnerLotteryTicket(winnerTicket, LotteryNumber.of(bonusTicketNumber));
rewardLotteryTickets = new RewardLotteryTickets(lotteryTickets, winnerLotteryTicket);
}

Expand Down
74 changes: 74 additions & 0 deletions src/main/java/ui/ManualResultView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package ui;

import domain.lottery.*;
import service.LotteryService;
import ui.common.InputView;
import ui.common.Result;
import util.Calculator;
import util.Converter;

import static constant.LotteryRules.DEFAULT_LOTTERY_TICKET_PRICE;

public class ManualResultView implements Result {
private final String DELIMITER = ", ";
private LotteryTickets lotteryTickets;
private WinnerLotteryTicket winnerLotteryTicket;
private RewardLotteryTickets rewardLotteryTickets;

@Override
public void printAll() {
LotteryService lotteryService = new LotteryService();

printTicketNumbers();
printLotteryResult(lotteryService);
}

@Override
public void printTicketNumbers() {
System.out.println("구입금액을 입력해 주세요.");

long amount = InputView.inputInteger();
int totalNumberOfLotteryTickets = (int) Calculator.divide(amount, DEFAULT_LOTTERY_TICKET_PRICE);

System.out.println();
System.out.println("수동으로 구매할 로또 수를 입력해 주세요.");
int numberOfManualLotteryTickets = InputView.inputInteger();

lotteryTickets = new LotteryTickets(totalNumberOfLotteryTickets - numberOfManualLotteryTickets);

System.out.println();
System.out.println("수동으로 구매할 번호를 입력해 주세요.");
for (int count = 1; count <= numberOfManualLotteryTickets; count++) {
lotteryTickets.add(Converter.convertStringToLotteryTicket(InputView.inputString().split(DELIMITER)));
}

System.out.println();
System.out.println("수동으로 " + numberOfManualLotteryTickets + "장, 자동으로 " + (totalNumberOfLotteryTickets - numberOfManualLotteryTickets) + "개를 구매했습니다.");
for (LotteryTicket lotteryTicket : lotteryTickets.getLotteryTickets()) {
System.out.println(lotteryTicket.getTicketNumbers());
}

System.out.println();
System.out.println("지난 주 당첨 번호를 입력해 주세요.");
LotteryTicket winnerTicket = Converter.convertStringToLotteryTicket(InputView.inputString().split(DELIMITER));

System.out.println("보너스 볼을 입력해 주세요.");
int bonusTicketNumber = InputView.inputInteger();
winnerLotteryTicket = new WinnerLotteryTicket(winnerTicket, LotteryNumber.of(bonusTicketNumber));
rewardLotteryTickets = new RewardLotteryTickets(lotteryTickets, winnerLotteryTicket);
}

@Override
public void printLotteryResult(LotteryService lotteryService) {
System.out.println();
System.out.println("당첨 통계");
System.out.println("---------");

System.out.println("3개 일치 (5000원)- " + lotteryService.countOfLotteryWinners(3, rewardLotteryTickets) + "개");
System.out.println("4개 일치 (50000원)- " + lotteryService.countOfLotteryWinners(4, rewardLotteryTickets) + "개");
System.out.println("5개 일치 (1500000원)- " + lotteryService.countOfLotteryWinners(5, rewardLotteryTickets) + "개");
System.out.println("5개 일치, 보너스 볼 일치(30000000원)- " + lotteryService.countOfLotteryWinners(7, rewardLotteryTickets) + "개");
System.out.println("6개 일치 (2000000000원)- " + lotteryService.countOfLotteryWinners(6, rewardLotteryTickets) + "개");
System.out.println("총 수익률은 " + Calculator.rateOfProfit((long) lotteryTickets.getLotteryTickets().size() * DEFAULT_LOTTERY_TICKET_PRICE, lotteryService.findTotalRewards(new RewardLotteryTickets(lotteryTickets, winnerLotteryTicket))) + "입니다.(기준이 1이기 때문에 결과적으로 손해라는 의미임)");
}
}
9 changes: 5 additions & 4 deletions src/main/java/util/Converter.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package util;

import domain.lottery.LotteryNumber;
import domain.lottery.LotteryTicket;

import java.util.ArrayList;
import java.util.List;

public class Converter {
public static LotteryTicket convertStringToLotteryTicket(String[] numbers) {
List<Integer> lotteryTicketNumbers = new ArrayList<>();

LotteryTicket lotteryTicket = LotteryTicket.of(new ArrayList<>());
for (String number : numbers) {
lotteryTicketNumbers.add(Integer.parseInt(number));
lotteryTicket.add(LotteryNumber.of(Integer.parseInt(number)));
}

return new LotteryTicket(lotteryTicketNumbers);
return lotteryTicket;
}
}
10 changes: 6 additions & 4 deletions src/main/java/util/RandomNumberGenerator.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package util;

import domain.lottery.LotteryNumber;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class RandomNumberGenerator {
public static List<Integer> generateNumbers() {
List<Integer> numberCandidates = new ArrayList<>();
public static List<LotteryNumber> generateNumbers() {
List<LotteryNumber> numberCandidates = new ArrayList<>();

for (int number = 1; number <= 45; number++) {
numberCandidates.add(number);
numberCandidates.add(LotteryNumber.of(number));
}

Collections.shuffle(numberCandidates);

List<Integer> ticketNumbers = new ArrayList<>();
List<LotteryNumber> ticketNumbers = new ArrayList<>();
for (int index = 0; index < 6; index++) {
ticketNumbers.add(numberCandidates.get(index));
}
Expand Down
5 changes: 4 additions & 1 deletion src/test/java/ConverterTest.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import domain.lottery.LotteryNumber;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import util.Converter;
Expand All @@ -14,7 +15,9 @@ public class ConverterTest {
@Order(1)
public void 복권변환_성공() {
String[] numbers = {"1", "2", "3", "4", "5", "6"};
List<Integer> expected = Arrays.asList(1, 2, 3, 4, 5, 6);
List<LotteryNumber> expected = Arrays.asList(
LotteryNumber.of(1), LotteryNumber.of(2), LotteryNumber.of(3),
LotteryNumber.of(4), LotteryNumber.of(5), LotteryNumber.of(6));
assertThat(Converter.convertStringToLotteryTicket(numbers).getTicketNumbers()).isEqualTo(expected);
}

Expand Down
Loading

0 comments on commit 298ad08

Please sign in to comment.