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

[포키 && 필] 로또 3단계 - 수동구매 기능 추가 #55

Open
wants to merge 7 commits into
base: PhilSoGooood
Choose a base branch
from
Prev Previous commit
기능구현: 예외를 처리하는 기능을 구현하였습니다.
구매금액과 수동 구매 수량, 당첨번호, 보너스 번호 입력에
대해 예외처리를 하도록 했습니다.
PhilSoGooood committed Feb 25, 2022
commit ea47d09df9b8be226d532cb648a89cbf1f110716
66 changes: 54 additions & 12 deletions src/main/java/com/lotto/controller/Controller.java
Original file line number Diff line number Diff line change
@@ -6,37 +6,79 @@
import com.lotto.model.LottoResult;
import com.lotto.model.LottoTickets;
import com.lotto.model.WinningLotto;
import com.lotto.util.ValidationUtil;
import com.lotto.view.InputView;
import com.lotto.view.OutputView;

public class Controller {
private static final int TICKET_PRICE = 1_000;
private InputView inputView = new InputView();
private OutputView outputView = new OutputView();
private LottoGame lottoGame = new LottoGame();

public void run() {
inputView.initScanner();

int purchaseAmount = inputView.getPurchaseAmount();
int manualCount = inputView.inputManualCount();
LottoTickets lottoTickets;
if(manualCount > 0){
List<List<Integer>> manualNumbers = inputView.inputManualNumbers(manualCount);
lottoTickets = new LottoTickets(purchaseAmount, manualNumbers);
} else {
lottoTickets = new LottoTickets(purchaseAmount);
}
int purchaseAmount = getPurchaseAmount();
int manualCount = getManualCount(purchaseAmount);

LottoTickets lottoTickets = getLottoTickets(purchaseAmount, manualCount);
outputView.printTickets(lottoTickets);

List<Integer> winningNumbers = inputView.getWinningNumbers();
int bonusNumber = inputView.inputBonusNumber();
WinningLotto winningLotto = new WinningLotto(winningNumbers,bonusNumber);
WinningLotto winningLotto = getWinningLotto();
inputView.closeScanner();

LottoResult result = lottoGame.checkResult(lottoTickets, winningLotto);
double earningRate = lottoGame.calculateEarningRate(purchaseAmount, result);

outputView.printResult(result, earningRate);
}

private Integer getPurchaseAmount() {
int purchaseAmount;
while (true) {
purchaseAmount = inputView.inputPurchaseAmount();
if (purchaseAmount < TICKET_PRICE) {
System.out.printf("%s 이상의 금액을 입력해주세요.", TICKET_PRICE);
continue;
}
break;
}
return purchaseAmount;
}

private int getManualCount(int purchaseAmount) {
int manualCount;
try {
manualCount = inputView.inputManualCount();
ValidationUtil.validateManualCountRange(manualCount, purchaseAmount);
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
manualCount = getManualCount(purchaseAmount);
}
return manualCount;
}

private WinningLotto getWinningLotto() {
List<Integer> winningNumbers = inputView.inputWinningNumbers();
int bonusNumber = inputView.inputBonusNumber(winningNumbers);
WinningLotto winningLotto = new WinningLotto(winningNumbers, bonusNumber);
return winningLotto;
}

private LottoTickets getLottoTickets(int purchaseAmount, int manualCount) {
int ticketCount = calculateTicketAmounts(purchaseAmount);
LottoTickets lottoTickets;
if (manualCount > 0) {
List<List<Integer>> manualNumbers = inputView.inputManualNumbers(manualCount);

Choose a reason for hiding this comment

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

List<Integer> 는 여기에서 어떤 의미를 갖나요? 로또 번호에 대한 사용자 입력, 혹은 로또번호의 집합 그 자체가 될 수 있을 것 같은데요...
이걸 적절히 감싸서 리스트를 원소로 갖는 리스트, 즉 List<List<Integer>> 를 쓰지 않도록 리팩터링 부탁드려요.

lottoTickets = new LottoTickets(ticketCount, manualNumbers);
} else {
lottoTickets = new LottoTickets(ticketCount);
}
return lottoTickets;
}

private int calculateTicketAmounts(int purchaseAmount) {
return purchaseAmount / TICKET_PRICE;
}
}
11 changes: 3 additions & 8 deletions src/main/java/com/lotto/model/LottoTickets.java
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@

public class LottoTickets {
private static final List<Integer> numbers;
private static final int TICKET_PRICE = 1_000;
private final List<Lotto> tickets;

static {
@@ -17,14 +16,12 @@ public class LottoTickets {
}
}

public LottoTickets(int purchaseAmount) {
int ticketCount = calculateTicketAmounts(purchaseAmount);
public LottoTickets(int ticketCount) {
this.tickets = new ArrayList<>();
addAutoTickets(ticketCount);
}

public LottoTickets(int purchaseAmount, List<List<Integer>> manualTickets) {
int ticketCount = calculateTicketAmounts(purchaseAmount);
public LottoTickets(int ticketCount, List<List<Integer>> manualTickets) {
this.tickets = new ArrayList<>();
setManualTickets(manualTickets);
addAutoTickets(ticketCount- manualTickets.size());
@@ -59,7 +56,5 @@ private List<Integer> createRandomNumbers() {
return numbers.stream().limit(6).collect(Collectors.toList());
}

private int calculateTicketAmounts(int purchaseAmount) {
return purchaseAmount / TICKET_PRICE;
}

}
43 changes: 43 additions & 0 deletions src/main/java/com/lotto/util/ValidationUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.lotto.util;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

public class ValidationUtil {
private static final String NUMBER_PATTERN = "([1-9]|1[0-9]|2[0-9]|3[0-9]|4[0-5])((, )([1-9]|1[0-9]|2[0-9]|3[0-9]|4[0-5])){5}";

public static void validateManualCountRange(int count, int purchaseAmount) {
if (count > purchaseAmount / 1000 || count < 0) {
throw new IllegalArgumentException("숫자를 확인해주세요.");
}
}

public static String[] validateTicketFormat(String ticketNumbers) {

if (!Pattern.matches(NUMBER_PATTERN, ticketNumbers)) {
throw new IllegalArgumentException("형식이 올바르지 않습니다");
}
return ticketNumbers.replaceAll(" ", "").split(",");
}

public static void checkDuplicate(String[] ticketNumbers) {
Set<String> result = new HashSet<>();
for (String ticketNumber : ticketNumbers) {
result.add(ticketNumber);
}
if (result.size() != 6) {
throw new IllegalArgumentException("숫자가 중복되지 없도록 입력해주세요.");
}
}

public static void validateBonusNumber(int bonusNumber, List<Integer> winningNumbers) {
if (bonusNumber > 46 || bonusNumber < 1) {
throw new IllegalArgumentException("1 ~ 45 사이의 숫자를 입력해주세요.");
}
if (winningNumbers.contains(bonusNumber)) {
throw new IllegalArgumentException("당첨번호와 중복되지 않는 번호로 입력해주세요.");
}
}
}
70 changes: 54 additions & 16 deletions src/main/java/com/lotto/view/InputView.java
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@
import java.util.Scanner;
import java.util.stream.Collectors;

import com.lotto.util.ValidationUtil;

public class InputView {
private static final String REQUEST_AMOUNT_MESSAGE = "구입 금액을 입력해 주세요.";
private static final String REQUEST_WINNING_NUMBERS_MESSAGE = "당첨 번호를 입력해 주세요.";
@@ -15,41 +17,77 @@ public class InputView {

private Scanner scanner;

public int getPurchaseAmount() {
public int inputPurchaseAmount() {
System.out.println(REQUEST_AMOUNT_MESSAGE);
return Integer.parseInt(scanner.nextLine());
return inputNumber();
}

public List<Integer> getWinningNumbers() {
System.out.println(REQUEST_WINNING_NUMBERS_MESSAGE);
return inputNumbers();
}
public int inputManualCount(){
public int inputManualCount() {
System.out.println(REQUEST_MANUAL_NUMBER_COUNT_MESSAGE);
return Integer.parseInt(scanner.nextLine());
return inputNumber();
}

public List<Integer> inputWinningNumbers() {
System.out.println(REQUEST_WINNING_NUMBERS_MESSAGE);
return inputTicketNumbers();
}
public List<List<Integer>> inputManualNumbers(int count){

public List<List<Integer>> inputManualNumbers(int count) {
System.out.println(REQUEST_MANUAL_NUMBERS_MESSAGE);
List<List<Integer>> manualNumbers = new ArrayList<>();
for (int i = 0; i < count; i++) {
manualNumbers.add(inputNumbers());
manualNumbers.add(inputTicketNumbers());
}
return manualNumbers;
}
public int inputBonusNumber() {

public int inputBonusNumber(List<Integer> winningNumbers) {
System.out.println(REQUEST_BONUS_NUMBER_MESSAGE);
return scanner.nextInt();

int bonusNumber;
try {
bonusNumber = scanner.nextInt();
ValidationUtil.validateBonusNumber(bonusNumber, winningNumbers);
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
bonusNumber = inputBonusNumber(winningNumbers);
}
return bonusNumber;
}

public void initScanner(){
public void initScanner() {
this.scanner = new Scanner(System.in);
}

public void closeScanner(){
public void closeScanner() {
this.scanner.close();
}
private List<Integer> inputNumbers() {
String[] numbers = scanner.nextLine().replaceAll(" ", "").split(",");

private int inputNumber() {
int result;
try {
result = Integer.parseInt(scanner.nextLine());
} catch (NumberFormatException e) {
System.out.println("숫자를 입력해주세요.");
result = inputPurchaseAmount();
}
return result;
}

private List<Integer> inputTicketNumbers() {
String[] numbers;
while (true) {
try {
String input = scanner.nextLine();
numbers = ValidationUtil.validateTicketFormat(input);
ValidationUtil.checkDuplicate(numbers);
break;
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
continue;
}
}
return Arrays.stream(numbers).map(Integer::parseInt).collect(Collectors.toList());
}

}