Skip to content

2주차 - Step3 로또(2등) 리뷰 부탁드립니다. #249

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

Merged
merged 10 commits into from
Jun 27, 2019
Merged
Show file tree
Hide file tree
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
29 changes: 29 additions & 0 deletions src/main/java/step3/LottoApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package step3;

import step3.domain.LottoSeller;
import step3.domain.LottoTicket;
import step3.domain.ResultSheet;
import step3.view.InputView;
import step3.view.OutputView;

import java.util.List;

public class LottoApplication {

public static void main(String[] args) {
final int inputMoney = InputView.askMoneyToInput();
final int numberOfTicketsToBuy = LottoSeller.countLottoTickets(inputMoney);

OutputView.printNumberOfTickets(numberOfTicketsToBuy);

List<LottoTicket> lottoTickets = LottoSeller.issueLottoTicket(numberOfTicketsToBuy);
OutputView.printLottoTickets(lottoTickets);

LottoTicket luckyNumber = LottoSeller.getLuckyNumber(InputView.askLuckyNumber());
int bonusNumber = InputView.askBonusNumber();

ResultSheet result = ResultSheet.getResult(lottoTickets, luckyNumber, bonusNumber);
OutputView.printResult(result);
}
}

17 changes: 17 additions & 0 deletions src/main/java/step3/domain/LottoBalls.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package step3.domain;

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

public class LottoBalls {

private static List<Integer> lottoBalls = IntStream
.rangeClosed(LottoNumber.MINIMUM_LOTTO_NUMBER, LottoNumber.MAXIMUM_LOTTO_NUMBER)
.boxed()
.collect(Collectors.toList());

public static List<Integer> getLottoBalls() {
return lottoBalls;
}
}
47 changes: 47 additions & 0 deletions src/main/java/step3/domain/LottoNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package step3.domain;

import java.util.Objects;

public class LottoNumber {
static final String ALERT_OUT_OF_RANGE_OF_LOTTO_NUMBER = "로또번호는 1부터 45까지의 자연수만 가능합니다.";
static final int MINIMUM_LOTTO_NUMBER = 1;
static final int MAXIMUM_LOTTO_NUMBER = 45;
private int number;

private LottoNumber(int number) {
if (isOutOfRange(number)) {
throw new IllegalArgumentException(ALERT_OUT_OF_RANGE_OF_LOTTO_NUMBER);
}
this.number = number;
}

public static LottoNumber from(Integer number) {
return new LottoNumber(number);
}

private boolean isOutOfRange(int number) {
return number < MINIMUM_LOTTO_NUMBER || number > MAXIMUM_LOTTO_NUMBER;

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.

범위를 벗어난 경우에 true를 반환하고 있어서 OR 조건을 사용했습니닷

}

public int getNumber() {
return number;
}

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

@Override
public int hashCode() {
return Objects.hash(number);
}

@Override
public String toString() {
return number + "";
}
}
43 changes: 43 additions & 0 deletions src/main/java/step3/domain/LottoRank.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package step3.domain;

import java.util.Arrays;

public enum LottoRank {

FIRST_PLACE(6, 2_000_000_000),
SECOND_PLACE(5, 30_000_000),
THIRD_PLACE(5, 1_500_000),
FOURTH_PLACE(4, 50_000),
FIFTH_PLACE(3, 5_000),
LOSER(0, 0);

private int numberOfMatchedToLuckyNumber;
private int prizeMoney;

LottoRank(int numberOfMatchedToLuckyNumber, int prizeMoney) {
this.numberOfMatchedToLuckyNumber = numberOfMatchedToLuckyNumber;
this.prizeMoney = prizeMoney;
}

public static LottoRank from(int countMatchedNumbers, boolean isMatchedToBonusNumber) {
if ((countMatchedNumbers == SECOND_PLACE.numberOfMatchedToLuckyNumber) && isMatchedToBonusNumber) {
return Arrays.stream(LottoRank.values())
.filter(lottoRank -> lottoRank.prizeMoney == SECOND_PLACE.prizeMoney)
.findFirst()
.get();
}
return Arrays.stream(LottoRank.values())
.filter(lottoRank -> lottoRank.numberOfMatchedToLuckyNumber == countMatchedNumbers)
.findFirst()
.orElse(LOSER);
}

public int getNumberOfMatchingNumber() {
return numberOfMatchedToLuckyNumber;
}

public int getPrizeMoney() {
return prizeMoney;
}

}
37 changes: 37 additions & 0 deletions src/main/java/step3/domain/LottoSeller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package step3.domain;

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

public class LottoSeller {
static final int PRICE_OF_A_LOTTO_TICKET = 1000;
static final String ALERT_MISSING_MONEY = "돈을 넣어주세요. 로또복권은 한 장당 1000원 입니다.";

public static int countLottoTickets(int inputMoney) {
validationInputMoney(inputMoney);
return inputMoney / PRICE_OF_A_LOTTO_TICKET;
}

public static List<LottoTicket> issueLottoTicket(int numberOfTicketsToBuy) {
List<LottoTicket> lottoTickets = new ArrayList<>();

for (int i = 0; i < numberOfTicketsToBuy; i++) {
lottoTickets.add(LottoTicketGenerator.issue());
}
return lottoTickets;
}

public static LottoTicket getLuckyNumber(List<Integer> inputLuckyNumber) {
List<LottoNumber> lottoTicket = inputLuckyNumber.stream()
.map(LottoNumber::from)
.collect(Collectors.toList());
return LottoTicketGenerator.issue(lottoTicket);
}

private static void validationInputMoney(int inputMoney) {
if (inputMoney < PRICE_OF_A_LOTTO_TICKET) {
throw new IllegalArgumentException(ALERT_MISSING_MONEY);
}
}
}
71 changes: 71 additions & 0 deletions src/main/java/step3/domain/LottoTicket.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package step3.domain;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

public class LottoTicket {
static final String ALERT_NUMBER_OVERLAP = "중복된 로또 번호가 존재합니다.";
static final String AlERT_DIFFERENT_SIZE_OF_NUMBERS = "로또번호의 개수가 6개가 아닙니다.";

private final List<LottoNumber> lottoTicket;

LottoTicket(List<LottoNumber> lottoTicket) {
validationNumberSize(lottoTicket);
validationNumberOverlap(lottoTicket);
this.lottoTicket = lottoTicket;
}

public int getNumberOfMatchedToLuckyNumber(LottoTicket luckyNumber) {
return (int) luckyNumber.getLottoTicket().stream()
.filter(lottoTicket::contains)
.count();
}

boolean isBonusNumberMatched(int bonusNumber) {
return lottoTicket.stream()
.mapToInt(LottoNumber::getNumber)
.anyMatch(i -> i == bonusNumber);
}

private void validationNumberSize(List<LottoNumber> lottoTicket) {
if (lottoTicket.size() != LottoTicketGenerator.BASIC_LOTTO_SIZE) {
throw new IllegalArgumentException(AlERT_DIFFERENT_SIZE_OF_NUMBERS);
}
}

private void validationNumberOverlap(List<LottoNumber> lottoTicket) {
long SizeOfLottoTicket = lottoTicket.stream()
.mapToLong(LottoNumber::getNumber)
.distinct()
.count();

if (SizeOfLottoTicket != LottoTicketGenerator.BASIC_LOTTO_SIZE) {
throw new IllegalArgumentException(ALERT_NUMBER_OVERLAP);
}
}

public List<LottoNumber> getLottoTicket() {
return Collections.unmodifiableList(lottoTicket);
}

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

@Override
public int hashCode() {
return Objects.hash(lottoTicket);
}

@Override
public String toString() {
return "LottoTicket{" +
"lottoTicket=" + lottoTicket +
'}';
}
}
31 changes: 31 additions & 0 deletions src/main/java/step3/domain/LottoTicketGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package step3.domain;

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

public class LottoTicketGenerator {
static final int BASIC_LOTTO_SIZE = 6;

static LottoTicket issue() {
return new LottoTicket(pickLottoBalls(LottoBalls.getLottoBalls()));
}

static LottoTicket issue(List<LottoNumber> lottoTicket) {
return new LottoTicket(lottoTicket);
}

static List<LottoNumber> pickLottoBalls(List<Integer> lottoBalls) {
shuffleLottoBalls(lottoBalls);
return lottoBalls.stream()
.limit(BASIC_LOTTO_SIZE)
.sorted()
.map(LottoNumber::from)
.collect(Collectors.toList());
}

static void shuffleLottoBalls(List<Integer> lottoBalls) {
Collections.shuffle(lottoBalls);
}

}
60 changes: 60 additions & 0 deletions src/main/java/step3/domain/ResultSheet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package step3.domain;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ResultSheet {
private static final int LOTTO_TICKET_PRICE = 1000;

private Map<LottoRank, Integer> resultSheet;

private ResultSheet(Map<LottoRank, Integer> resultSheet) {
this.resultSheet = resultSheet;
}

public static ResultSheet getResult(List<LottoTicket> lottoTickets, LottoTicket luckyNumber, int bonusNumber) {
Map<LottoRank, Integer> lottoResultMap = new HashMap<>();

for (LottoTicket ticket : lottoTickets) {

Choose a reason for hiding this comment

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

ResultSheet를 잘 빼주셨네요ㅎㅎ
뭔가 지저분한 느낌은 List lottoTickets도 일급 객체화 시키면 많이 해소될 듯 보입니다.

LottoRank lottoRank = LottoRank.from(ticket.getNumberOfMatchedToLuckyNumber(luckyNumber), ticket.isBonusNumberMatched(bonusNumber));
int numberOfTicketsCorrespondingToRank = lottoResultMap.getOrDefault(lottoRank, 0);
lottoResultMap.put(lottoRank, ++numberOfTicketsCorrespondingToRank);
}
return new ResultSheet(lottoResultMap);
}

private int getTotalTicketsBought() {
return resultSheet.values()
.stream()
.reduce(Integer::sum)
.get();
}

private int totalMoneySpentForTickets() {
return getTotalTicketsBought() * LOTTO_TICKET_PRICE;
}

private int getNumberOfTicketsCorrespondingToRank(LottoRank lottoRank) {
return resultSheet.getOrDefault(lottoRank, 0);
}

private int getEachPrizeMoney(LottoRank lottoRank) {
return lottoRank.getPrizeMoney() * this.getNumberOfTicketsCorrespondingToRank(lottoRank);
}

private int getTotalPrizeMoney() {
return resultSheet.keySet()
.stream()
.mapToInt(this::getEachPrizeMoney)
.sum();
}

public double getEarningRate() {
return getTotalPrizeMoney() / totalMoneySpentForTickets();
}

public Map<LottoRank, Integer> getResultMap() {
return resultSheet;
}
}
39 changes: 39 additions & 0 deletions src/main/java/step3/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package step3.view;

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

public class InputView {
private static final String LUCKY_NUMBER_SEPARATOR = ",";
private static Scanner scanner = new Scanner(System.in);

public static int askMoneyToInput() {
System.out.println("구입금액을 입력해 주세요.");
return scanner.nextInt();
}

public static List<Integer> askLuckyNumber() {
printBlackLine();
scanner.nextLine();
System.out.println("지난 주 당첨 번호를 입력해주세요.");
String inputLuckyNumber = scanner.nextLine();
printBlackLine();

return Arrays.stream(inputLuckyNumber.split(LUCKY_NUMBER_SEPARATOR))
.map(String::trim)
.mapToInt(Integer::parseInt)
.boxed()
.collect(Collectors.toList());
}

public static int askBonusNumber() {
System.out.println("보너스 볼을 입력해 주세요.");
return scanner.nextInt();
}

private static void printBlackLine() {
System.out.println();
}
}
Loading