Skip to content
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

feat: 4단계 로또 수동 #2816

Merged
merged 2 commits into from
Nov 17, 2022
Merged
Changes from all commits
Commits
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
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) {

Choose a reason for hiding this comment

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

case문이 제거가 됐네요 훨씬 구조가 나아진거같습니다.

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

public long findReward() {
return reward;
}
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 {

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.

넵넵!알겠습니다~!

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;
Comment on lines +8 to +10

Choose a reason for hiding this comment

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

불필요한 변수를 잘 제거해주셨습니다!
다만 8,10라인 선언 위치만 변경부탁드려요 :)


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
@@ -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;
}
16 changes: 1 addition & 15 deletions src/main/java/domain/lottery/RewardLotteryTickets.java
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@
import java.util.ArrayList;
import java.util.List;

import static constant.LotteryRules.*;

public class RewardLotteryTickets {
private final List<Rank> ranks;
@@ -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() {
13 changes: 9 additions & 4 deletions src/main/java/domain/lottery/WinnerLotteryTicket.java
Original file line number Diff line number Diff line change
@@ -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;
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;

@@ -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);
}

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));
}
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;
@@ -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);
}

Loading