diff --git a/docs/README.md b/docs/README.md index e69de29bb2..584f4edef8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,27 @@ +- 로또 번호의 숫자 범위는 1~45까지이다 +- 1개의 로또를 발행할 때 중복되지 않는 6개의 숫자를 뽑는다 +- 당첨 번호 추첨 시 중복되지 않는 숫자 6개와 보너스 번호 1개를 뽑는다 +- 당첨은 1등부터 5등까지 있다 + - 1등: 6개 번호 일치 / 2,000,000,000원 + - 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원 + - 3등: 5개 번호 일치 / 1,500,000원 + - 4등: 4개 번호 일치 / 50,000원 + - 5등: 3개 번호 일치 / 5,000원 +- 로또 1장의 가격은 1000원 + +입력 +- 로또 구입 금액을 입력 받는다 + - "," 로 구분한다 +- 당첨 번호 입력 받는다 (6자리) +- 보너스 번호 입력 받는다 +출력 +- 로또 번호를 발행한다 + - 오름차순 정렬 +- 당첨 내역 출력 + - 수익률을 출력한다 +기능 +- 게임을 종료 시킨다 +예외 +- 잘못된 값 입력 시 IllegalArgumentException 발생. 에러 문구는 "[ERROR]"로 시작 +- 1000원 미만 +- 1000원으로 나누어 떨어지지 않는 금액 diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922ba4..525977e6d3 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,11 @@ package lotto; +import lotto.controller.LottoController; + public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 + LottoController lottoController = new LottoController(); + lottoController.run(); } } diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java deleted file mode 100644 index 519793d1f7..0000000000 --- a/src/main/java/lotto/Lotto.java +++ /dev/null @@ -1,20 +0,0 @@ -package lotto; - -import java.util.List; - -public class Lotto { - private final List numbers; - - public Lotto(List numbers) { - validate(numbers); - this.numbers = numbers; - } - - private void validate(List numbers) { - if (numbers.size() != 6) { - throw new IllegalArgumentException(); - } - } - - // TODO: 추가 기능 구현 -} diff --git a/src/main/java/lotto/controller/LottoController.java b/src/main/java/lotto/controller/LottoController.java new file mode 100644 index 0000000000..3e27f0709d --- /dev/null +++ b/src/main/java/lotto/controller/LottoController.java @@ -0,0 +1,42 @@ +package lotto.controller;// @ author ninaaano + +import lotto.model.*; +import lotto.view.InputView; +import lotto.view.OutputView; + +public class LottoController { + + public void run(){ + // 금액을 입력 받는다 + int money = InputValidator.isValidMoney(InputView.requestInputMoney()); // return money를 반환했다 + + // 입력받은 금액만큼 로또를 발행한다 + OutputView.printLottoTicket(buyLotto(money)); + + // 당첨 번호를 입력한다 + WinningNumber winningNumber = createWinningNumber(); + + // 보너스 번호를 입력한다 + BonusNumber bonusNumber = createBonusNumber(winningNumber); + + + // 당첨 내역을 출력한다 + + } + + private LottoTicket buyLotto(int money){ + int count = LotteryCalculator.calculator(money); + OutputView.printLottoNumber(count); + return new LottoTicket(count); + } + + private WinningNumber createWinningNumber(){ + return new WinningNumber(InputValidator.isValidNumber()); + } // retrurn 할때 이미 ,로 구분. 근데 입력받을때 ,안적어도 에러가 안난다??? + + private BonusNumber createBonusNumber(WinningNumber winningNumber){ + return new BonusNumber(InputValidator.isValidBonusNumber(),winningNumber.getLottoNumbers()); + } + + +} diff --git a/src/main/java/lotto/model/InputValidator.java b/src/main/java/lotto/model/InputValidator.java new file mode 100644 index 0000000000..b7cefbb791 --- /dev/null +++ b/src/main/java/lotto/model/InputValidator.java @@ -0,0 +1,118 @@ +package lotto.model;// @ author ninaaano + +import lotto.model.constant.InputValidMessage; +import lotto.view.InputView; +import lotto.model.Lotto; + +import java.util.*; +import java.util.stream.Collectors; + +import static lotto.model.constant.CommonCostants.IS_NUMBER; +import static lotto.model.constant.CommonCostants.MIN_LOTTO_PRICE; + +public class InputValidator { + + public InputValidator() { + } + + /** + * 입력받은 로또 번호 유효성 검사 + */ + public static List isValidNumber() { + List winningNumber = new ArrayList<>(); + try { + //isCheckNumber(inputNumber); + //int number = Integer.parseInt(inputNumber); + //validateLottoNumber(number); + String input = InputView.requestInputLottoNumber(); + winningNumber = Arrays.stream(input.split(",")) + .map(Integer::parseInt).collect(Collectors.toList()); + } catch (IllegalArgumentException e) { + //System.out.println(InputValidMessage.INPUT_NUMBER_ERROR.get()); + throw new IllegalArgumentException(InputValidMessage.AMOUNT_RANGE.get()); + } + return winningNumber; + } + + public static void validateLottoNumber(int number) { + if (!checkRange(number)) { + System.out.println("로또 번호는 1 ~ 45 사이의 번호여야 합니다."); + throw new IllegalArgumentException(InputValidMessage.AMOUNT_RANGE.get()); + } + } + + public static boolean checkRange(int number) { + return number >= 1 && number <= 45; + } + + public static int isValidBonusNumber() { + int bonusNumber = 0; + try { + bonusNumber = Integer.parseInt(InputView.requestInputBonusNumber()); + // validateDuplicates(Lotto lotto,bonusNumber); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(InputValidMessage.REDUPLICATION.get()); + } + return bonusNumber; + } + + public static void validateDuplicates(Lotto lotteryNumbers, int bonusNumber) { + if (lotteryNumbers.contains(bonusNumber)) { + throw new IllegalArgumentException(InputValidMessage.REDUPLICATION.get()); + } + } + + + + + + + /** + * 로또 번호 검사 + * @param numbers + */ + public static void validLottoNumberSize(List numbers) { + if(numbers.size() != 6){ + throw new IllegalArgumentException(InputValidMessage.REDUPLICATION.get()); + } + } + + public static void validDuplicate(List number){ + Set lottoNo = new HashSet<>(number); + + if(lottoNo.size() != number.size()){ + throw new IllegalArgumentException(InputValidMessage.REDUPLICATION.get()); + } + } + + + /** + * 입력받은 금액 유효성 검사 + * @param inputMoney + * @return + */ + + public static int isValidMoney(String inputMoney){ + int money = Integer.parseInt(inputMoney); + try { + isCheckNumber(inputMoney); + amoutRange(money); + return money; + }catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + } + return Integer.parseInt(InputView.requestInputMoney()); + } + + private static void amoutRange(int money) throws IllegalArgumentException{ + if(money < MIN_LOTTO_PRICE || (money % MIN_LOTTO_PRICE) != 0) { + throw new IllegalArgumentException(InputValidMessage.INPUT_MONEY_ERROR.get()); + } + } + + private static void isCheckNumber(String input) throws IllegalArgumentException{ + if(input == null || input.isBlank() || !input.matches(IS_NUMBER)){ + throw new IllegalArgumentException(InputValidMessage.INPUT_NUMBER_ERROR.get()); + } + } +} diff --git a/src/main/java/lotto/model/LotteryCalculator.java b/src/main/java/lotto/model/LotteryCalculator.java new file mode 100644 index 0000000000..4c504cd76e --- /dev/null +++ b/src/main/java/lotto/model/LotteryCalculator.java @@ -0,0 +1,20 @@ +package lotto.model;// @ author ninaaano + +import static lotto.model.constant.CommonCostants.MIN_LOTTO_PRICE; + +/** + * 입력받은 금액을 계산하는 클래스 + */ +public class LotteryCalculator { + private final int purchaseMoney; + + public LotteryCalculator(int money) { + this.purchaseMoney = money; + } + + + public static int calculator(int money){ + return money / MIN_LOTTO_PRICE; + } + +} diff --git a/src/main/java/lotto/model/Lotto.java b/src/main/java/lotto/model/Lotto.java new file mode 100644 index 0000000000..10015a0e45 --- /dev/null +++ b/src/main/java/lotto/model/Lotto.java @@ -0,0 +1,36 @@ +package lotto.model; + +import java.util.ArrayList; +import java.util.List; + +public class Lotto { + private final List numbers; + + public Lotto(List numbers) { + numbers.forEach(InputValidator::validateLottoNumber); + InputValidator.validLottoNumberSize(numbers); + InputValidator.validDuplicate(numbers); + this.numbers = numbers; + } + + + public boolean contains(int lottoNumber) { + return getLottoNumber().contains(lottoNumber); + } + + public List getLottoNumber() { + return new ArrayList<>(numbers); + } + + public int countMatchedNumbers(List winningNumbers) { + return (int) this.numbers.stream() + .filter(winningNumbers::contains) + .count(); + } + + // 내보내기 + // public LottoNumbersDTO export() { +// return new LottoNumbersDTO(numbers); +// } + +} diff --git a/src/main/java/lotto/model/LottoTicket.java b/src/main/java/lotto/model/LottoTicket.java new file mode 100644 index 0000000000..9284394703 --- /dev/null +++ b/src/main/java/lotto/model/LottoTicket.java @@ -0,0 +1,30 @@ +package lotto.model;// @ author ninaaano + +import camp.nextstep.edu.missionutils.Randoms; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class LottoTicket { + private final List lottoTickets = new ArrayList<>(); + public LottoTicket(int count) { + createLottoTickets(count); + } + + private void createLottoTickets(int ticketNumber) { + for (int i = 0; i < ticketNumber; i++) { + List lottoNumber = new ArrayList<>( + Randoms.pickUniqueNumbersInRange(1, 45, 6)); + Collections.sort(lottoNumber); + Lotto lotto = new Lotto(lottoNumber); + lottoTickets.add(lotto); + } + } + + public List getLottoTickets(){ + return lottoTickets; + } + + +} diff --git a/src/main/java/lotto/model/WinningNumber.java b/src/main/java/lotto/model/WinningNumber.java new file mode 100644 index 0000000000..301e12af34 --- /dev/null +++ b/src/main/java/lotto/model/WinningNumber.java @@ -0,0 +1,16 @@ +package lotto.model;// @ author ninaaano + +import java.util.List; + +public class WinningNumber { + + private final List lottoNumbers; + + public WinningNumber(List lottoNumbers) { + this.lottoNumbers = lottoNumbers; + } + + public List getLottoNumbers() { + return lottoNumbers; + } +} diff --git a/src/main/java/lotto/model/constant/CommonCostants.java b/src/main/java/lotto/model/constant/CommonCostants.java new file mode 100644 index 0000000000..cbdbe989b7 --- /dev/null +++ b/src/main/java/lotto/model/constant/CommonCostants.java @@ -0,0 +1,10 @@ +package lotto.model.constant;// @ author ninaaano + +public class CommonCostants { + + public static final int MIN_LOTTO_PRICE = 1000; + public static final String IS_NUMBER = "^[1-9][0-9]+$"; + + private CommonCostants() { + } +} diff --git a/src/main/java/lotto/model/constant/InputMessage.java b/src/main/java/lotto/model/constant/InputMessage.java new file mode 100644 index 0000000000..fff41581f8 --- /dev/null +++ b/src/main/java/lotto/model/constant/InputMessage.java @@ -0,0 +1,18 @@ +package lotto.model.constant;// @ author ninaaano + +public enum InputMessage { + + REQUEST_INPUT_MONEY("구입금액을 입력해 주세요."), + REQUEST_INPUT_LOTTO_NUMBER("당첨 번호를 입력해주세요."), + REQUEST_BONUS_NUMBER("보너스 번호를 입력해 주세요."); + + private final String message; + + private InputMessage (String message) { + this.message = message; + } + + public String get() { + return message; + } +} diff --git a/src/main/java/lotto/model/constant/InputValidMessage.java b/src/main/java/lotto/model/constant/InputValidMessage.java new file mode 100644 index 0000000000..0c53f5a353 --- /dev/null +++ b/src/main/java/lotto/model/constant/InputValidMessage.java @@ -0,0 +1,20 @@ +package lotto.model.constant;// @ author ninaaano + +public enum InputValidMessage { + INPUT_MONEY_ERROR("[ERROR] 정확한 금액을 입력해주세요"), + INPUT_NUMBER_ERROR("[ERROR] 숫자만 입력할 수 있습니다"), + REDUPLICATION("[ERROR] 중복된 숫자는 입력할 수 없습니다"), + AMOUNT_RANGE("[ERROR] 1-45사이의 숫자만 입력할 수 있습니다") + ; + + private final String message; + + private InputValidMessage (String message) { + this.message = message; + } + + public String get() { + return message; + } + +} diff --git a/src/main/java/lotto/model/constant/OutputMessage.java b/src/main/java/lotto/model/constant/OutputMessage.java new file mode 100644 index 0000000000..0e1aeaf62e --- /dev/null +++ b/src/main/java/lotto/model/constant/OutputMessage.java @@ -0,0 +1,17 @@ +package lotto.model.constant;// @ author ninaaano + +public enum OutputMessage { + + RESPONSE_LOTTO_TICKET("%d개를 구매했습니다."); + + private final String message; + + private OutputMessage (String message) { + this.message = message; + } + + public String get() { + return message; + } + +} diff --git a/src/main/java/lotto/view/InputView.java b/src/main/java/lotto/view/InputView.java new file mode 100644 index 0000000000..b99ced383b --- /dev/null +++ b/src/main/java/lotto/view/InputView.java @@ -0,0 +1,36 @@ +package lotto.view;// @ author ninaaano + +import lotto.model.constant.InputMessage; + +import static camp.nextstep.edu.missionutils.Console.readLine; + +public class InputView { + + public InputView() { + } + + /** + * 사용자의 금액을 입력받는다 + */ + public static String requestInputMoney(){ + System.out.println(InputMessage.REQUEST_INPUT_MONEY.get()); + return readLine(); + } + + /** + * 사용자의 로또 번호를 입력 받는다 + */ + public static String requestInputLottoNumber(){ + System.out.println(InputMessage.REQUEST_INPUT_LOTTO_NUMBER.get()); + return readLine(); + } + + /** + * 사용자의 보너스 번호를 입력 받는다 + */ + public static String requestInputBonusNumber(){ + System.out.println(InputMessage.REQUEST_BONUS_NUMBER.get()); + return readLine(); + } + +} diff --git a/src/main/java/lotto/view/OutputView.java b/src/main/java/lotto/view/OutputView.java new file mode 100644 index 0000000000..14a6cbd6b2 --- /dev/null +++ b/src/main/java/lotto/view/OutputView.java @@ -0,0 +1,31 @@ +package lotto.view;// @ author ninaaano + +import lotto.model.Lotto; +import lotto.model.LottoTicket; +import lotto.model.constant.OutputMessage; + +import java.util.List; + +public class OutputView { + public static void printLottoNumber(int count) { + System.out.printf(OutputMessage.RESPONSE_LOTTO_TICKET.get(),count); + System.out.println(); + } + + public static void printLottoTicket(LottoTicket lottoTicket){ + List lottoTickets = lottoTicket.getLottoTickets(); + for(Lotto lotto : lottoTickets){ + StringBuilder lottoNumbers = new StringBuilder("["); + createTicketPrint(lottoNumbers, lotto); + lottoNumbers.delete(lottoNumbers.length() - 2, lottoNumbers.length()) + .append("]"); + System.out.println(lottoNumbers); + } + } + + private static void createTicketPrint(StringBuilder lottoNumbers, Lotto lotto) { + for (Integer integer : lotto.getLottoNumber()) { + lottoNumbers.append(integer).append(", "); + } + } +} diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 0f3af0f6c4..19e699c453 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -1,5 +1,6 @@ package lotto; +import lotto.model.Lotto; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test;