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

[java-lotto] haon.lee(이민성) 미션 제출합니다. #3

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
5 changes: 4 additions & 1 deletion src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package lotto;

import lotto.controller.LottoController;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
final LottoController lottoController = new LottoController();
lottoController.runMachine();
}
}
20 changes: 0 additions & 20 deletions src/main/java/lotto/Lotto.java

This file was deleted.

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

import lotto.view.InputView;
import lotto.domain.Lotto;
import lotto.domain.*;
import lotto.domain.strategy.LottoGenerateStrategy;
import lotto.domain.strategy.LottoGenerator;
import lotto.domain.strategy.UserLottoGenerateStrategy;
import lotto.domain.strategy.WinningLottoGenerateStrategy;
import lotto.view.OutputView;

public class LottoController {
private final LottoGenerator lottoGenerator = new LottoGenerator();
private Budget budget;

public void runMachine() {
final Lottos userLottos = buyLotto();
final WinningLotto winningLotto = drawLotto();
final WinningStatistics winningStatistics = makeStatistics(userLottos, winningLotto);
OutputView.printWinningStaticstics(winningStatistics);
}

private Lottos buyLotto() {
try {
budget = Budget.from(InputView.getBudgetInput());
setLottoGeneratorStrategy(new UserLottoGenerateStrategy());
Lottos userMultipleLottos = lottoGenerator.generateLottosByBudget(budget);
return userMultipleLottos;
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
return buyLotto();
}
}

private WinningLotto drawLotto() {
try {
final Lotto lotto = getWinningLotto();
final Bonus bonus = getBonus();
return WinningLotto.of(lotto, bonus);
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
return drawLotto();
}
}

private Lotto getWinningLotto() {
try {
InputView.printRequireWinningNumbersMessage();
setLottoGeneratorStrategy(new WinningLottoGenerateStrategy());
return lottoGenerator.generateLotto();
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
return getWinningLotto();
}
}

private Bonus getBonus(){
try {
return Bonus.from(InputView.getBonusInput());
} catch (IllegalArgumentException e){
System.out.println(e.getMessage());
return getBonus();
}
}

private WinningStatistics makeStatistics(final Lottos userLottos, final WinningLotto winningLotto) {
return WinningStatistics.of(userLottos, winningLotto, budget);
}

public void setLottoGeneratorStrategy(final LottoGenerateStrategy lottoGenerateStrategy) {
this.lottoGenerator.setLottoGenerateStrategy(lottoGenerateStrategy);
}
}
38 changes: 38 additions & 0 deletions src/main/java/lotto/domain/Bonus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package lotto.domain;

public class Bonus {
private final int bonus;
private static final String NUMBER_FORMAT_EXCEPTION_MESSAGE = "[ERROR] 보너스 번호는 숫자만 입력할 수 있습니다.";
private static final String NUMBER_PARSE_EXCEPTION_MESSAGE = "[ERROR] 보너스 번호는 1부터 45 사이의 숫자를 입력해야 합니다.";
private static final int MAX_NUMBER = 45;
private static final int MIN_NUMBER = 1;

private Bonus(int bonus) {
validateOutOfRange(bonus);
this.bonus = bonus;
}

public static Bonus from(String bonus) {
return new Bonus(convertBonusNumber(bonus));
}

private static int convertBonusNumber(String bonusNumber) {
try {
Integer.parseInt(bonusNumber);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(NUMBER_FORMAT_EXCEPTION_MESSAGE);
}
return Integer.parseInt(bonusNumber);
}

public void validateOutOfRange(int bonus) {
if (bonus < MIN_NUMBER || bonus > MAX_NUMBER) {
throw new IllegalArgumentException(NUMBER_PARSE_EXCEPTION_MESSAGE);
}
}

public int getBonus() {
return bonus;
}
}

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

public class Budget {
private static final String NUMBER_FORMAT_EXCEPTION_MESSAGE = "[ERROR] 구입 금액은 숫자만 입력할 수 있습니다.";
private static final String DIVIDE_EXCEPTION_MESSAGE = "[ERROR] 구입 금액은 %d원 단위로 나누어 떨어져야합니다.";
private static final String MINIMUM_PRICE_EXCEPTION_MESSAGE = "[ERROR] 로또 구입 최소 금액은 %d원 입니다.";
private static final int LOTTO_UNIT_PRICE = 1000;
private static final int ZERO = 0;
private final int budget;

private Budget(final int budget) {
this.budget = budget;
}

public static Budget from(final String inputBudget) {
validateNumeric(inputBudget);
int budget = Integer.parseInt(inputBudget);
return new Budget(budget);
}

private static void validateNumeric(final String inputBudget) {
try {
Integer.parseInt(inputBudget);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(NUMBER_FORMAT_EXCEPTION_MESSAGE, e);
}
}

private static void validateDivideResultIsZero(final int inputBudget) {
if(inputBudget % LOTTO_UNIT_PRICE != ZERO) {
throw new IllegalArgumentException(String.format(DIVIDE_EXCEPTION_MESSAGE, LOTTO_UNIT_PRICE));
}
}

private static void validateLowerPrice(final int inputBudget) {
if(inputBudget < LOTTO_UNIT_PRICE) {
throw new IllegalArgumentException(String.format(MINIMUM_PRICE_EXCEPTION_MESSAGE, LOTTO_UNIT_PRICE));
}
}

public int getCountOfLottoLines() {
return budget / LOTTO_UNIT_PRICE;
}

public int getBudget() {
return budget;
}
}
56 changes: 56 additions & 0 deletions src/main/java/lotto/domain/Lotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package lotto.domain;

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

public class Lotto {
private final List<Integer> numbers;
private static final String SPLIT_CHAR = ", ";
private static final int LOTTO_SIZE = 6;
private static final int MAX_NUMBER = 45;
private static final int MIN_NUMBER = 1;
private static final String OUT_OF_RANGE_EXCEPTION_MESSAGE = "[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다.";
private static final String DUPLICATION_EXCEPTION_MESSAGE = "[ERROR] 로또 번호는 중복없이 6개의 번호들로 구성되어야 합니다.";
private static final String LOTTO_SIZE_EXCEPTION_MESSAGE = "[ERROR] 로또는 6개의 숫자로 구성되어야 합니다.";

public Lotto(List<Integer> numbers) {
validate(numbers);
validateRange(numbers);
validateDuplication(numbers);
this.numbers = numbers;
}

private void validate(List<Integer> numbers) {
if (numbers.size() != LOTTO_SIZE) {
throw new IllegalArgumentException(LOTTO_SIZE_EXCEPTION_MESSAGE);
}
}

private void validateRange(List<Integer> numbers) {
if (numbers.stream().anyMatch(number -> number < MIN_NUMBER || number > MAX_NUMBER)) {
throw new IllegalArgumentException(OUT_OF_RANGE_EXCEPTION_MESSAGE);
}
}

private void validateDuplication(List<Integer> numbers) {
if (numbers.stream().distinct().count() != numbers.size()) {
throw new IllegalArgumentException(DUPLICATION_EXCEPTION_MESSAGE);
}
}

@Override
public String toString() {
return numbers.stream()
.sorted().map(Objects::toString)
.collect(Collectors.joining(SPLIT_CHAR));
}

public boolean isContain(int bonusNumber) {
return numbers.contains(bonusNumber);
}

public List<Integer> getNumbers() {
return numbers;
}
}
19 changes: 19 additions & 0 deletions src/main/java/lotto/domain/Lottos.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package lotto.domain;

import java.util.List;

public class Lottos {
private final List<Lotto> lottos;

private Lottos(final List<Lotto> lottos) {
this.lottos = lottos;
}

public static Lottos from(List<Lotto> lottos) {
return new Lottos(lottos);
}

public List<Lotto> getLottos() {
return lottos;
}
}
31 changes: 31 additions & 0 deletions src/main/java/lotto/domain/WinningLotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package lotto.domain;

public class WinningLotto {
Copy link
Member

Choose a reason for hiding this comment

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

Lotto를 extends 하는 방식도 좋을 것 같습니다!
두 방식에 어떤 차이가 있는지 저도 고민해봐야겠습니다.

private final Lotto lotto;
private final Bonus bonus;
private static final String BONUS_NUMBER_DUPLICATE_ERROR_MESSAGE = "[ERROR] 보너스 번호는 당첨 번호와 중복될 수 없습니다.";

private WinningLotto(Lotto lotto, Bonus bonus) {
this.lotto = lotto;
this.bonus = bonus;
}

public static WinningLotto of(Lotto lotto, Bonus bonus) {
validateBonusNumberDuplicate(lotto, bonus.getBonus());
return new WinningLotto(lotto, bonus);
}

private static void validateBonusNumberDuplicate(Lotto lotto, int bonusNumber) {
if (lotto.isContain(bonusNumber)) {
throw new IllegalArgumentException(BONUS_NUMBER_DUPLICATE_ERROR_MESSAGE);
}
}

public Lotto getLotto() {
return lotto;
}

public Bonus getBonus() {
return bonus;
}
}
40 changes: 40 additions & 0 deletions src/main/java/lotto/domain/WinningRank.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package lotto.domain;

import java.util.Arrays;

public enum WinningRank {
FIRST(6, false, 2000000000, "6개 일치"),
SECOND(5, true, 30000000, "5개 일치, 보너스 볼 일치"),
THIRD(5, false, 1500000, "5개 일치"),
FOURTH(4, false, 50000, "4개 일치"),
FIFTH(3, false, 5000, "3개 일치"),
NOTHING(0, false, 0, "");

private final int match;
private final boolean isBonus;
private final int prize;
private final String message;

WinningRank(int match, boolean isBonus, int prize, String message) {
this.match = match;
this.isBonus = isBonus;
this.prize = prize;
this.message = message;
}

public static WinningRank from(int match, boolean isBonus) {
return Arrays.stream(WinningRank.values())
.filter(rank -> rank.match == match)
.filter(rank -> rank.isBonus == isBonus)
.findAny()
.orElse(NOTHING);
}

public int getPrize() {
return prize;
}

public String getMessage() {
return message;
}
}
Loading