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

[로또 미션] 최규원 미션 제출합니다. #8

Open
wants to merge 5 commits into
base: kyuwon-choi
Choose a base branch
from
Open
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
8 changes: 8 additions & 0 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import controller.LottoController;
public class Main {
public static void main(String[] args) {
LottoController lottoController = new LottoController();
lottoController.lottoStart();

}
}
30 changes: 30 additions & 0 deletions src/main/java/controller/LottoController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package controller;

import model.*;
import view.InputView;
import view.ResultView;

import java.util.List;

public class LottoController {

public void lottoStart() {

int price = InputView.getPrice();
int manualCount = InputView.getManualCount();
List<String> manualLottos = InputView.getManualLottos(manualCount);
BuyLotto buyLotto = new BuyLotto(price, manualCount, manualLottos);
LottoGenerator lottoGenerator = new LottoGenerator();
List<Lotto> lottos = lottoGenerator.generateLottos(buyLotto.calculateAutoLottoCount(), manualLottos);

ResultView.printLottos(manualCount, lottos);

WinLotto winLotto = new WinLotto(InputView.getWinLotto(), lottos, InputView.getBonusBall());
winLotto.updateWinningStates(lottos);
ResultView.printStatics(winLotto.getWinningStates());

ProfitCalculator profitCalculator = new ProfitCalculator();
ResultView.printProfit(profitCalculator.calculateProfit(winLotto.getWinPrize(), price));

}
}
23 changes: 23 additions & 0 deletions src/main/java/model/BuyLotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package model;

import java.util.List;

public class BuyLotto {
private LottoMoney totalPrice;
private int manualLottoCount;
private List<String> manualLottoList;

public BuyLotto(int totalPrice, int manualLottoCount, List<String> manualLottoList) {
this.totalPrice = new LottoMoney(String.valueOf(totalPrice));
this.manualLottoCount = manualLottoCount;
this.manualLottoList = manualLottoList;
}

public int calculateAutoLottoCount() {
return totalPrice.getAmount() / Constant.LOTTO_PRICE - manualLottoCount;
}

public List<String> getManualLottoList() {
return manualLottoList;
}
}
59 changes: 59 additions & 0 deletions src/main/java/model/Constant.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package model;

public class Constant {

public static final int LOTTO_PRICE = 1000;
public static final int LOTTO_SIZE = 6;
public static final int MAX_LOTTO_NUMBER = 45;
public static final int MIN_LOTTO_NUMBER = 1;
public static final int THREE_COUNT = 3;
public static final int FOUR_COUNT = 4;
public static final int FIVE_COUNT = 5;
public static final int SIX_COUNT = 6;
public static final int ZERO_COUNT = 0;

public static final int FIFTH_PRICE = 5000;
public static final int FOURTH_PRICE = 50000;
public static final int THIRD_PRICE = 1500000;
public static final int SECOND_PRICE = 30000000;
public static final int FIRST_PRICE = 2000000000;

public static final String SEPARATOR = ",";

// InputView

public static final String PRICE_QUERY = "구입금액을 입력해 주세요.";
public static final String WIN_LOTTO_QUERY = "지난 주 당첨 번호를 입력해 주세요.";
public static final String BONUS_QUERY = "보너스 볼을 입력해 주세요";
public static final String MANUAL_COUNT_QUERY = "수동으로 구매할 로또 수를 입력해 주세요.";
public static final String MANUAL_LOTTO_QUERY = "수동으로 구매할 번호를 입력해 주세요.";


// ResultView
public static final String WIN_RESULT = "당첨 통계";
public static final String LINES = "---------";
public static final String LOTTO_BUY_RESULT_1 = "수동으로 ";
public static final String LOTTO_BUY_RESULT_2 = "장 자동으로";
public static final String LOTTO_BUY_RESULT_3 = "개를 구매했습니다.";
public static final String PROFIT_RESULT_1 = "총 수익률은 ";
public static final String PROFIT_RESULT_2 = "입니다.";
public static final String STATICS_RESULT_1 = "개 일치";
public static final String STATICS_RESULT_2 = " 보너스볼 일치";
public static final String STATICS_RESULT_3 = "원";
public static final String STATICS_RESULT_4 = "개";
public static final String OPEN_PARENTHESES = "(";
public static final String CLOSE_PARENTHESES = ")";
public static final String DASH = "-";
public static final String BLANK = " ";

//exceptions
public static final String RANGE_EXCEPTION = "로또 번호는 1부터 45 사이여야 합니다.";
public static final String SIZE_EXCEPTION = "로또 번호는 6개입니다.";
public static final String DUPLICATE_EXCEPTION = "로또 번호는 중복이 불가합니다.";
public static final String VALUE_EXCEPTION = "로또 번호는 숫자여야 합니다.";
public static final String PRICE_VALUE_EXCEPTION = "가격은 숫자여야 합니다.";
public static final String BONUS_DUPLICATE_EXCEPTION = "보너스 볼은 중복이 불가합니다.";
public static final String LOTTO_PRICE_EXCEPTION = "로또는 천원 단위로만 구입이 가능합니다.";


}
41 changes: 41 additions & 0 deletions src/main/java/model/Lotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package model;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Lotto {
private List<LottoNumber> numbers = new ArrayList<>();

public Lotto(List<LottoNumber> numbers) {
validateSize(numbers);
validateDuplicate(numbers);
this.numbers = new ArrayList<>(numbers);
}

@Override
public String toString() {
return numbers.toString();
}

public List<LottoNumber> getNumbers() {
return new ArrayList<>(numbers);
}

private void validateSize(List<LottoNumber> numbers) {
if (numbers.size() != Constant.SIX_COUNT) {
throw new IllegalArgumentException(Constant.SIZE_EXCEPTION);
}
}

private void validateDuplicate(List<LottoNumber> numbers) {
Set<Integer> numberSet = new HashSet<>();
for (LottoNumber number : numbers) {
numberSet.add(number.getNumber());
}
if (numberSet.size() != Constant.SIX_COUNT) {
throw new IllegalArgumentException(Constant.DUPLICATE_EXCEPTION);
}
}
}
48 changes: 48 additions & 0 deletions src/main/java/model/LottoGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package model;

import java.util.*;
import java.util.stream.Collectors;

public class LottoGenerator {
private List<Integer> numberList;

public LottoGenerator() {
numberList = new ArrayList<>();
for (int i = Constant.MIN_LOTTO_NUMBER; i <= Constant.MAX_LOTTO_NUMBER; i++) {
numberList.add(i);
}
}

public List<Lotto> generateLottos(int autoLottoCount, List<String> manualLottoList) {
List<Lotto> lottos = convertManualLottoList(manualLottoList);

for (int i = 0; i < autoLottoCount; i++) {
lottos.add(new Lotto(generateRandomNumbers()));
}

return lottos;
}

private List<Lotto> convertManualLottoList(List<String> manualLottoList) {
return manualLottoList.stream()
.map(this::parseLottoNumbers)
.collect(Collectors.toList());
}

private Lotto parseLottoNumbers(String lotto) {
List<LottoNumber> numbers = Arrays.stream(lotto.split(Constant.SEPARATOR))
.map(String::trim)
.map(LottoNumber::new)
.collect(Collectors.toList());
return new Lotto(numbers);
}

private List<LottoNumber> generateRandomNumbers() {
Collections.shuffle(numberList);
return numberList.subList(Constant.ZERO_COUNT, Constant.LOTTO_SIZE)
.stream()
.map(n -> new LottoNumber(String.valueOf(n)))
.sorted(Comparator.comparingInt(LottoNumber::getNumber))
.collect(Collectors.toList());
}
}
25 changes: 25 additions & 0 deletions src/main/java/model/LottoMoney.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package model;

public class LottoMoney {
private final int amount;

public LottoMoney(String inputAmount) {
try {
int amount = Integer.parseInt(inputAmount);
validateAmount(amount);
this.amount = amount;
} catch (NumberFormatException e) {
throw new IllegalArgumentException(Constant.PRICE_VALUE_EXCEPTION, e);
}
}

private void validateAmount(int amount) {
if (amount % Constant.LOTTO_PRICE != 0 || amount < Constant.LOTTO_PRICE) {
throw new IllegalArgumentException(Constant.LOTTO_PRICE_EXCEPTION);
}
}
Comment on lines +6 to +20
Copy link

Choose a reason for hiding this comment

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

각각의 예외처리가 잘들어간 것 같아요!


public int getAmount() {
return amount;
}
}
30 changes: 30 additions & 0 deletions src/main/java/model/LottoNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package model;

public class LottoNumber {
private final int number;

public LottoNumber(String number) {
try {
int parsedNumber = Integer.parseInt(number);
validateRange(parsedNumber);
this.number = parsedNumber;
} catch (NumberFormatException e) {
throw new IllegalArgumentException(Constant.VALUE_EXCEPTION, e);
}
}

private void validateRange(int number) {
if (number < Constant.MIN_LOTTO_NUMBER || number > Constant.MAX_LOTTO_NUMBER) {
throw new IllegalArgumentException(Constant.RANGE_EXCEPTION);
}
}

public int getNumber() {
return number;
}

@Override
public String toString() {
return String.valueOf(number);
}
}
32 changes: 32 additions & 0 deletions src/main/java/model/LottoPrize.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package model;

public enum LottoPrize {
FIFTH(Constant.THREE_COUNT, Constant.FIFTH_PRICE, false),
FOURTH(Constant.FOUR_COUNT, Constant.FOURTH_PRICE, false),
THIRD(Constant.FIVE_COUNT, Constant.THIRD_PRICE, false),
SECOND(Constant.FIVE_COUNT, Constant.SECOND_PRICE, true),
FIRST(Constant.SIX_COUNT, Constant.FIRST_PRICE, false);

private final int matchCount;
private final int prizeAmount;
private final boolean hasBonus;

LottoPrize(int matchCount, int prizeAmount, boolean hasBonus) {
this.matchCount = matchCount;
this.prizeAmount = prizeAmount;
this.hasBonus = hasBonus;
}

public int getMatchCount() {
return matchCount;
}

public int getPrizeAmount() {
return prizeAmount;
}

public boolean hasBonus() {
return hasBonus;
}

}
9 changes: 9 additions & 0 deletions src/main/java/model/ProfitCalculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package model;

public class ProfitCalculator {

public double calculateProfit(int winPrice, int totalPrice) {
return (double) winPrice / totalPrice;
}

}
68 changes: 68 additions & 0 deletions src/main/java/model/WinLotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package model;

import java.util.*;

public class WinLotto {
private List<LottoNumber> winnerLotto = new ArrayList<>();
private List<Lotto> userLottos;
private Map<LottoPrize, Integer> winningStates = new LinkedHashMap<>();
private int winPrize;
private LottoNumber bonusBall;

public WinLotto(String inputWinnerLotto, List<Lotto> userLottos, String bonusBall) {
Arrays.stream(inputWinnerLotto.split(Constant.SEPARATOR))
.forEach(e -> winnerLotto.add(new LottoNumber(e.trim())));
this.userLottos = userLottos;
this.winPrize = Constant.ZERO_COUNT;
LottoNumber tempBonusBall = new LottoNumber(bonusBall);
if (winnerLotto.stream().anyMatch(winnerNumber -> winnerNumber.getNumber() == tempBonusBall.getNumber())) {
throw new IllegalArgumentException(Constant.BONUS_DUPLICATE_EXCEPTION);
}
this.bonusBall = new LottoNumber(bonusBall);
for (LottoPrize prize : LottoPrize.values()) {
winningStates.put(prize, Constant.ZERO_COUNT);
}
}

private int compareHowManyNumberSame(Lotto lotto) {
return (int) lotto.getNumbers().stream()
.filter(number -> winnerLotto.stream().anyMatch(winnerNumber -> winnerNumber.getNumber() == number.getNumber()))
.count();
}

public int getWinPrize() {
return winPrize;
}

public Map<LottoPrize, Integer> getWinningStates() {
return winningStates;
}

public void updateWinningStates(List<Lotto> userLottos) {
userLottos.forEach(userLotto -> {
int matchedNumbers = compareHowManyNumberSame(userLotto);
boolean containsBonus = userLotto.getNumbers().stream().anyMatch(number -> number.getNumber() == bonusBall.getNumber());

if (matchedNumbers == Constant.SIX_COUNT) {
updateWinningState(LottoPrize.FIRST);
}
if (matchedNumbers == Constant.FIVE_COUNT && containsBonus) {
updateWinningState(LottoPrize.SECOND);
}
if (matchedNumbers == Constant.FIVE_COUNT && !containsBonus) {
updateWinningState(LottoPrize.THIRD);
}
if (matchedNumbers == Constant.FOUR_COUNT) {
updateWinningState(LottoPrize.FOURTH);
}
if (matchedNumbers == Constant.THREE_COUNT) {
updateWinningState(LottoPrize.FIFTH);
}
});
}
Comment on lines +41 to +62
Copy link

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 void updateWinningState(LottoPrize prize) {
winningStates.put(prize, winningStates.get(prize) + 1);
winPrize += prize.getPrizeAmount();
}
}
Loading