diff --git a/README.md b/README.md index 340487a618..1449ecf84a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,75 @@ -![1](description-img/3.로또_page-0001.jpg) -![2](description-img/3.로또_page-0002.jpg) -![3](description-img/3.로또_page-0003.jpg) -![4](description-img/3.로또_page-0004.jpg) -![5](description-img/3.로또_page-0005.jpg) -![6](description-img/3.로또_page-0006.jpg) +# 기능 구현 목록 + +## Model +### domain.Lotto +- [x] 주어진 필드와 메서드 구현 +- [x] 당첨번호를 받아서 몇개 일치하는지 반환하는 메서드 구현 +- [x] 당첨번호를 받아서 2등인지 반환하는 메서드 구현 +### domain.LottoList +- [x] 로또 객체를 저장하는 리스트 저장 +### domain.WinningNumber +- [x] 당첨 번호 리스트로 저장 +- [x] 보너스 번호 저장 + - [x] 값이 당첨번호중 하나와 같을 경우 예외 발생 +### domain.LottoResult +- [x] 등수별 개수 저장 +- [x] WinningConstant를 객체로 사용해 등수별 일치해야 하는 개수와 당첨 금액 데이터 사용 +- [x] 수익률 계산하는 메서드 구현 +### service.LottoService +- [x] 구입 금액에 대한 로또를 발행하는 메서드 구현 + - [x] 구입 금액 입력값에 대한 검증 + - [x] 검증 실패시(예외 발생시) 예외 메시지 출력 후 null 반환 + - [x] 구입 금액에 맞는 개수의 로또 발행 + - [x] 발행한 로또를 리스트로 저장 + - [x] 로또 리스트 객체 반환 +- [x] 당첨 번호를 저장하는 객체를 생성하고 반환하는 메서드 구현 + - [x] 당첨 번호 파싱 + - [x] 검증 실패시(예외 발생시) 예외 메시지 출력 후 null 반환 + - [x] 당첨 번호 객체 생성 후 반환 +- [x] 당첨 번호 객체에 보너스 번호 추가 + - [x] 보너스 번호 입력값에 대한 검증 + - [x] 검증 실패시(예외 발생시) 예외 메시지 출력 후 null 반환 + - [x] 객체 내부에 추가한 후 해당 객체 반환(예외일 경우 null 반환) + +## View +### view.InputView +- [x] 사용자로부터 구입 금액 입력받아서 반환하는 메서드 구현 +- [x] 사용자로부터 당첨 번호 입력받아서 반환하는 메서드 구현 +- [x] 사용자로부터 보너스 번호 입력받아서 반환하는 메서드 구현 +### view.OutputView +- [x] 발행한 로또 오름차순으로 출력 + +## Controller +### controller.LottoController +- [x] 입력값에 따른 예외 발생 시 다시 입력받을 수 있도록 반복문 사용 +- [x] 구입 금액 입력값을 받아서 Service로 넘김 +- [x] 구입 금액에 맞게 발행된 로또 리스트 받음 + - [x] 만약 null이 반환되었으면 사용자로부터 재입력 받음 +- [x] 당첨 번호 입력값을 받아서 Service로 넘김 +- [x] 당첨 번호 리스트가 저장된 객체 받음 + - [x] 만약 null이 반환되었으면 사용자로부터 재입력 받음. +- [x] 보너스 번호 입력값을 받아서 Service로 넘김 + - [x] 만약 null이 반환되었으면 사용자로부터 재입력 받음. + +## Others +### util.Validator +검증 실패 시 메시지와 함께 예외 던짐 +- [x] null 또는 공백만 입력한 경우 검증하는 메서드 구현 +- [x] 0이하의 값 입력한 경우 검증하는 메서드 구현 +- [x] 1000원 단위가 아닌 경우 검증하는 메서드 구현 +- [x] 10만원 초과하는 경우 검증하는 메서드 구현 +- [x] 당첨 번호 6개 아닌 경우 검증하는 메서드 구현 +- [x] 당첨 번호가 1~45의 정수가 아닌 경우(리스트) 검증하는 메서드 구현 +- [x] 당첨 번호가 1~45의 정수가 아닌 경우(값) 검증하는 메서드 구현 +### util.parser +- [x] 당첨 번호 입력값 쉼표로 구분하는 메서드 구현 +- [x] 쉼표로 구분해서 만든 리스트 검증 + - [x] 당첨 번호 6개 아닌 경우 + - [x] 당첨 번호가 1~45의 정수가 아닌 경우 +- [x] 당첨 번호 리스트 반환 +### random.RandomGenerator +- [x] 로또 번호 발행하는 메서드 구현 +### constant.ErrorMessage +- [x] 에러메시지 상수 보관 +### constant.Rank +- [x] 등수별 일치해야 하는 개수와 당첨 금액을 상수로 저장 \ No newline at end of file diff --git "a/description-img/3.\353\241\234\353\230\220_page-0001.jpg" "b/description-img/3.\353\241\234\353\230\220_page-0001.jpg" new file mode 100644 index 0000000000..01364db5d6 Binary files /dev/null and "b/description-img/3.\353\241\234\353\230\220_page-0001.jpg" differ diff --git "a/description-img/3.\353\241\234\353\230\220_page-0002.jpg" "b/description-img/3.\353\241\234\353\230\220_page-0002.jpg" new file mode 100644 index 0000000000..012e7806a1 Binary files /dev/null and "b/description-img/3.\353\241\234\353\230\220_page-0002.jpg" differ diff --git "a/description-img/3.\353\241\234\353\230\220_page-0003.jpg" "b/description-img/3.\353\241\234\353\230\220_page-0003.jpg" new file mode 100644 index 0000000000..882a99e941 Binary files /dev/null and "b/description-img/3.\353\241\234\353\230\220_page-0003.jpg" differ diff --git "a/description-img/3.\353\241\234\353\230\220_page-0004.jpg" "b/description-img/3.\353\241\234\353\230\220_page-0004.jpg" new file mode 100644 index 0000000000..459ff8c4f3 Binary files /dev/null and "b/description-img/3.\353\241\234\353\230\220_page-0004.jpg" differ diff --git "a/description-img/3.\353\241\234\353\230\220_page-0005.jpg" "b/description-img/3.\353\241\234\353\230\220_page-0005.jpg" new file mode 100644 index 0000000000..1116d93578 Binary files /dev/null and "b/description-img/3.\353\241\234\353\230\220_page-0005.jpg" differ diff --git "a/description-img/3.\353\241\234\353\230\220_page-0006.jpg" "b/description-img/3.\353\241\234\353\230\220_page-0006.jpg" new file mode 100644 index 0000000000..b6518967ac Binary files /dev/null and "b/description-img/3.\353\241\234\353\230\220_page-0006.jpg" differ diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922ba4..bd3502847a 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,11 @@ package lotto; +import java.util.ArrayList; +import java.util.List; + public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 + new ApplicationStarter().start(); } } diff --git a/src/main/java/lotto/ApplicationStarter.java b/src/main/java/lotto/ApplicationStarter.java new file mode 100644 index 0000000000..a39fdfbc20 --- /dev/null +++ b/src/main/java/lotto/ApplicationStarter.java @@ -0,0 +1,18 @@ +package lotto; + +import lotto.controller.LottoController; +import lotto.service.LottoService; +import lotto.view.InputView; +import lotto.view.OutputView; + +public class ApplicationStarter { + + public void start() { + LottoController controller = new LottoController( + new LottoService(), + new InputView(), + new OutputView() + ); + controller.run(); + } +} diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java deleted file mode 100644 index 88fc5cf12b..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("[ERROR] 로또 번호는 6개여야 합니다."); - } - } - - // TODO: 추가 기능 구현 -} diff --git a/src/main/java/lotto/constant/ErrorMessage.java b/src/main/java/lotto/constant/ErrorMessage.java new file mode 100644 index 0000000000..02c409d79f --- /dev/null +++ b/src/main/java/lotto/constant/ErrorMessage.java @@ -0,0 +1,22 @@ +package lotto.constant; + +public enum ErrorMessage { + LOTTO_NUMBER_COUNT_ERROR("[ERROR] 로또 번호는 6개여야 합니다."), + BONUS_NUMBER_NOT_UNIQUE_ERROR("[ERROR] 보너스 번호는 당첨 번호와 달라야 합니다."), + INVALID_INPUT_FORMAT_ERROR("[ERROR] 올바르지 않은 형식의 입력입니다."), + NOT_POSITIVE_ERROR("[ERROR] 양수를 입력해주세요."), + MAX_PURCHASE_AMOUNT_ERROR("[ERROR] 최대 10만원까지만 구매 가능합니다."), + PURCHASE_AMOUNT_UNIT_ERROR("[ERROR] 1000원 단위로 입력해주세요."), + LOTTO_NUMBER_RANGE_ERROR("[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다."), + LOTTO_NUMBER_NOT_UNIQUE_ERROR("[ERROR] 로또 번호는 중복이 없어야 합니다."); + + private final String message; + + ErrorMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/lotto/constant/Rank.java b/src/main/java/lotto/constant/Rank.java new file mode 100644 index 0000000000..3e47478b86 --- /dev/null +++ b/src/main/java/lotto/constant/Rank.java @@ -0,0 +1,33 @@ +package lotto.constant; + +public enum Rank { + FIRST(1, 2000000000, 6), + SECOND(2, 30000000, 5), + THIRD(3, 1500000, 5), + FOURTH(4, 50000, 4), + FIFTH(5, 5000, 3); + + Rank(Integer rank, int prize, int matchingCount) { + this.rank = rank; + this.prize = prize; + this.matchingCount = matchingCount; + } + + private final Integer rank; + private final int prize; + private final int matchingCount; + + public Integer getRank() { + return rank; + } + + public int getPrize() { + return prize; + } + + public int getMatchingCount() { + return matchingCount; + } + + +} diff --git a/src/main/java/lotto/controller/LottoController.java b/src/main/java/lotto/controller/LottoController.java new file mode 100644 index 0000000000..56cd8a68c5 --- /dev/null +++ b/src/main/java/lotto/controller/LottoController.java @@ -0,0 +1,49 @@ +package lotto.controller; + +import lotto.domain.LottoList; +import lotto.domain.LottoResult; +import lotto.domain.WinningNumber; +import lotto.service.LottoService; +import lotto.view.InputView; +import lotto.view.OutputView; + +public class LottoController { + private final LottoService service; + private final InputView inputView; + private final OutputView outputView; + + public LottoController(LottoService service, InputView inputView, OutputView outputView) { + this.service = service; + this.inputView = inputView; + this.outputView = outputView; + } + + public void run() { + String inputPurchaseAmount; + String inputWinningNumber; + String inputBonusNumber; + LottoList lottoList; + WinningNumber winningNumber; + boolean isNull; + + do { + inputPurchaseAmount = inputView.readPurchaseAmount(); + lottoList = service.getLottoList(inputPurchaseAmount); + } while (lottoList == null); + + outputView.printLottoList(lottoList); + + do { + inputWinningNumber = inputView.readWinningNumber(); + winningNumber = service.getWinningNUmber(inputWinningNumber); + } while (winningNumber == null); + + do { + inputBonusNumber = inputView.readBonusNumber(); + isNull = service.getWinningNumberWithBonusNumber(winningNumber, inputBonusNumber); + } while (!isNull); + + LottoResult lottoResult = service.getLottoResult(winningNumber, lottoList); + outputView.printLottoResult(lottoResult); + } +} diff --git a/src/main/java/lotto/domain/Lotto.java b/src/main/java/lotto/domain/Lotto.java new file mode 100644 index 0000000000..b8e57f898d --- /dev/null +++ b/src/main/java/lotto/domain/Lotto.java @@ -0,0 +1,40 @@ +package lotto.domain; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static lotto.constant.ErrorMessage.LOTTO_NUMBER_COUNT_ERROR; +import static lotto.util.Validator.validateLottoNumberUnique; + +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(LOTTO_NUMBER_COUNT_ERROR.getMessage()); + } + validateLottoNumberUnique(numbers); + } + + // TODO: 추가 기능 구현 + public List getNumbers() { + return numbers.stream().sorted().toList(); + } + + public int getWinningNumberCount(List winningNumber) { + Set numbersSet = new HashSet<>(numbers); + Set winningNumberSet = new HashSet<>(winningNumber); + numbersSet.retainAll(winningNumberSet); + return numbersSet.size(); + } + + public boolean checkBonusNumber(int bonusNumber) { + return numbers.contains(bonusNumber); + } +} diff --git a/src/main/java/lotto/domain/LottoList.java b/src/main/java/lotto/domain/LottoList.java new file mode 100644 index 0000000000..0e11baf47c --- /dev/null +++ b/src/main/java/lotto/domain/LottoList.java @@ -0,0 +1,28 @@ +package lotto.domain; + +import java.util.ArrayList; +import java.util.List; + +public class LottoList { + private final List lottoList; + + private LottoList(List lottoList) { + this.lottoList = lottoList; + } + + public static LottoList of() { + return new LottoList(new ArrayList<>()); + } + + public void add(Lotto lotto) { + lottoList.add(lotto); + } + + public int getLottoCount() { + return lottoList.size(); + } + + public List getLottoList() { + return lottoList; + } +} diff --git a/src/main/java/lotto/domain/LottoResult.java b/src/main/java/lotto/domain/LottoResult.java new file mode 100644 index 0000000000..3c550e88c4 --- /dev/null +++ b/src/main/java/lotto/domain/LottoResult.java @@ -0,0 +1,44 @@ +package lotto.domain; + +import lotto.constant.Rank; + +import java.util.Comparator; +import java.util.Map; +import java.util.TreeMap; + +public class LottoResult { + private final Map matchedCount = new TreeMap<>(Comparator.comparing(Rank::getRank).reversed()); + private double profitRate; + + public LottoResult() { + for (Rank rank : Rank.values()) { + matchedCount.put(rank, 0); + } + } + + public Map getMatchedCount() { + return matchedCount; + } + + public double getProfitRate() { + return profitRate; + } + + public void confirmRank(WinningNumber winningNumber, LottoList lottoList) { + for (Lotto lotto : lottoList.getLottoList()) { + Rank rank = winningNumber.getRank(lotto); + if (rank != null) { + matchedCount.put(rank, matchedCount.getOrDefault(rank, 0) + 1); + } + } + } + + public void calculateProfitRate(LottoList lottoList) { + int purchaseAmount = lottoList.getLottoCount() * 1000; + int profit = 0; + for (Rank rank : matchedCount.keySet()) { + profit += rank.getPrize() * matchedCount.get(rank); + } + profitRate = (double) profit / purchaseAmount * 100; + } +} diff --git a/src/main/java/lotto/domain/WinningNumber.java b/src/main/java/lotto/domain/WinningNumber.java new file mode 100644 index 0000000000..231a0ff002 --- /dev/null +++ b/src/main/java/lotto/domain/WinningNumber.java @@ -0,0 +1,44 @@ +package lotto.domain; + +import lotto.constant.Rank; + +import java.util.List; + +import static lotto.constant.ErrorMessage.BONUS_NUMBER_NOT_UNIQUE_ERROR; +import static lotto.constant.Rank.*; + +public class WinningNumber { + private final List winningNumber; + private int bonusNumber = 0; + private static WinningNumber winningNumberObject; + + private WinningNumber(List winningNumber) { + this.winningNumber = winningNumber; + } + + public static WinningNumber getInstance(List winningNumber) { + if (winningNumberObject == null) { + winningNumberObject = new WinningNumber(winningNumber); + } + + return winningNumberObject; + } + + public void setBonusNumber(int bonusNumber) { + if (winningNumber.contains(bonusNumber)) { + throw new IllegalArgumentException(BONUS_NUMBER_NOT_UNIQUE_ERROR.getMessage()); + } + this.bonusNumber = bonusNumber; + } + + public Rank getRank(Lotto lotto) { + int matchedCount = lotto.getWinningNumberCount(winningNumber); + boolean isSecond = lotto.checkBonusNumber(bonusNumber); + if (matchedCount == 6) return FIRST; + if (matchedCount == 5 && isSecond) return SECOND; + if (matchedCount == 5) return THIRD; + if (matchedCount == 4) return FOURTH; + if (matchedCount == 3) return FIFTH; + return null; + } +} \ No newline at end of file diff --git a/src/main/java/lotto/random/RandomGenerator.java b/src/main/java/lotto/random/RandomGenerator.java new file mode 100644 index 0000000000..7864bf8ff6 --- /dev/null +++ b/src/main/java/lotto/random/RandomGenerator.java @@ -0,0 +1,11 @@ +package lotto.random; + +import camp.nextstep.edu.missionutils.Randoms; + +import java.util.List; + +public class RandomGenerator { + public static List generateRandomLottoNumber() { + return Randoms.pickUniqueNumbersInRange(1, 45, 6); + } +} diff --git a/src/main/java/lotto/service/LottoService.java b/src/main/java/lotto/service/LottoService.java new file mode 100644 index 0000000000..45f8673717 --- /dev/null +++ b/src/main/java/lotto/service/LottoService.java @@ -0,0 +1,96 @@ +package lotto.service; + +import lotto.domain.Lotto; +import lotto.domain.LottoList; +import lotto.domain.LottoResult; +import lotto.domain.WinningNumber; +import lotto.random.RandomGenerator; + +import java.util.List; + +import static lotto.util.Parser.*; +import static lotto.util.Validator.*; + +public class LottoService { + public LottoList getLottoList(String inputPurchaseAmount) { + Integer purchaseAmount = parsePurchaseAmount(inputPurchaseAmount); + if (purchaseAmount == null) return null; + + return generateLottoList(purchaseAmount); + } + + private Integer parsePurchaseAmount(String inputPurchaseAmount) { + int purchaseAmount; + try { + validateEmpty(inputPurchaseAmount); + purchaseAmount = parseInt(inputPurchaseAmount); + validatePositive(purchaseAmount); + validateAmountOver(purchaseAmount); + validateAmountUnit(purchaseAmount); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return null; + } + return purchaseAmount; + } + + private LottoList generateLottoList(int purchaseAmount) { + int lottoCount = purchaseAmount / 1000; + LottoList lottoList = LottoList.of(); + for (int i = 0; i < lottoCount; i++) { + try { + lottoList.add(new Lotto(RandomGenerator.generateRandomLottoNumber())); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return null; + } + } + return lottoList; + } + + + public WinningNumber getWinningNUmber(String inputWinningNumber) { + List winningNumber = parseWinningNumber(inputWinningNumber); + if (winningNumber == null) return null; + + return WinningNumber.getInstance(winningNumber); + } + + private List parseWinningNumber(String inputWinningNumber) { + List winningNumber; + try { + validateEmpty(inputWinningNumber); + winningNumber = parseInt(split(inputWinningNumber)); + validateLottoNumberRange(winningNumber); + validateWinningNumberCount(winningNumber); + validateLottoNumberUnique(winningNumber); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return null; + } + return winningNumber; + } + + public boolean getWinningNumberWithBonusNumber(WinningNumber winningNumber, String inputBonusNumber) { + int bonusNumber; + try { + validateEmpty(inputBonusNumber); + bonusNumber = parseInt(inputBonusNumber); + validateLottoNumberRange(bonusNumber); + winningNumber.setBonusNumber(bonusNumber); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return false; + } + + return true; + } + + public LottoResult getLottoResult(WinningNumber winningNumber, LottoList lottoList) { + LottoResult lottoResult = new LottoResult(); + lottoResult.confirmRank(winningNumber, lottoList); + lottoResult.calculateProfitRate(lottoList); + + return lottoResult; + } +} diff --git a/src/main/java/lotto/util/Parser.java b/src/main/java/lotto/util/Parser.java new file mode 100644 index 0000000000..a164a15e34 --- /dev/null +++ b/src/main/java/lotto/util/Parser.java @@ -0,0 +1,35 @@ +package lotto.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import static lotto.constant.ErrorMessage.INVALID_INPUT_FORMAT_ERROR; + +public class Parser { + private static final String DELIMITER = ","; + + public static int parseInt(String input) { + try { + return Integer.parseInt(input.strip()); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(INVALID_INPUT_FORMAT_ERROR.getMessage()); + } + } + + public static List parseInt(List inputs) { + List inputList = new ArrayList<>(); + for (String input : inputs) { + try { + inputList.add(Integer.parseInt(input.strip())); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(INVALID_INPUT_FORMAT_ERROR.getMessage()); + } + } + return inputList; + } + + public static List split(String input) { + return Stream.of(input.strip().split(DELIMITER)).toList(); + } +} diff --git a/src/main/java/lotto/util/Validator.java b/src/main/java/lotto/util/Validator.java new file mode 100644 index 0000000000..0ee1e4c1f7 --- /dev/null +++ b/src/main/java/lotto/util/Validator.java @@ -0,0 +1,55 @@ +package lotto.util; + +import java.util.List; + +import static lotto.constant.ErrorMessage.*; + +public class Validator { + public static void validateEmpty(String input) { + if (input == null || input.isBlank()) { + throw new IllegalArgumentException(INVALID_INPUT_FORMAT_ERROR.getMessage()); + } + } + + public static void validatePositive(int value) { + if (value <= 0) { + throw new IllegalArgumentException(NOT_POSITIVE_ERROR.getMessage()); + } + } + + public static void validateAmountOver(int value) { + if (value > 100000) { + throw new IllegalArgumentException(MAX_PURCHASE_AMOUNT_ERROR.getMessage()); + } + } + + public static void validateAmountUnit(int value) { + if (value % 1000 != 0) { + throw new IllegalArgumentException(PURCHASE_AMOUNT_UNIT_ERROR.getMessage()); + } + } + + public static void validateLottoNumberRange(int number) { + if (number < 1 || number > 45) { + throw new IllegalArgumentException(LOTTO_NUMBER_RANGE_ERROR.getMessage()); + } + } + + public static void validateLottoNumberRange(List numbers) { + for (Integer number : numbers) { + validateLottoNumberRange(number); + } + } + + public static void validateWinningNumberCount(List winningNumbers) { + if (winningNumbers.size() != 6) { + throw new IllegalArgumentException(LOTTO_NUMBER_COUNT_ERROR.getMessage()); + } + } + + public static void validateLottoNumberUnique(List lottoNumbers) { + if (lottoNumbers.size() != lottoNumbers.stream().distinct().toList().size()) { + throw new IllegalArgumentException(LOTTO_NUMBER_NOT_UNIQUE_ERROR.getMessage()); + } + } +} diff --git a/src/main/java/lotto/view/InputView.java b/src/main/java/lotto/view/InputView.java new file mode 100644 index 0000000000..c6598a66b8 --- /dev/null +++ b/src/main/java/lotto/view/InputView.java @@ -0,0 +1,24 @@ +package lotto.view; + +import camp.nextstep.edu.missionutils.Console; + +public class InputView { + private static final String REQUEST_PURCHASE_AMOUNT = "\n구입금액을 입력해 주세요."; + private static final String REQUEST_WINNING_NUMBER = "\n당첨 번호를 입력해 주세요."; + private static final String REQUEST_BONUS_NUMBER = "\n보너스 번호를 입력해 주세요."; + + public String readPurchaseAmount() { + System.out.println(REQUEST_PURCHASE_AMOUNT); + return Console.readLine(); + } + + public String readWinningNumber() { + System.out.println(REQUEST_WINNING_NUMBER); + return Console.readLine(); + } + + public String readBonusNumber() { + System.out.println(REQUEST_BONUS_NUMBER); + return Console.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..51ed88aee3 --- /dev/null +++ b/src/main/java/lotto/view/OutputView.java @@ -0,0 +1,48 @@ +package lotto.view; + +import lotto.constant.Rank; +import lotto.domain.Lotto; +import lotto.domain.LottoList; +import lotto.domain.LottoResult; + +import java.text.DecimalFormat; +import java.util.Map; + +public class OutputView { + private static final String LOTTO_LIST_PRINT_MESSAGE = "\n%d개를 구매했습니다.\n"; + private static final String STATISTICS_MESSAGE = "\n당첨 통계\n---"; + private static final String SECOND_MESSAGE = "%s개 일치, 보너스 볼 일치 (%s원) - %s개\n"; + private static final String OTHER_RANK_MESSAGE = "%s개 일치 (%s원) - %s개\n"; + private static final String PROFIT_RATE_MESSAGE = "총 수익률은 %.1f%%입니다.\n"; + + DecimalFormat df = new DecimalFormat("###,###"); + + public void printLottoList(LottoList lottoList) { + System.out.printf(LOTTO_LIST_PRINT_MESSAGE, lottoList.getLottoCount()); + for (Lotto lotto : lottoList.getLottoList()) { + System.out.println(lotto.getNumbers()); + } + } + + public void printLottoResult(LottoResult lottoResult) { + System.out.println(STATISTICS_MESSAGE); + Map matchedCount = lottoResult.getMatchedCount(); + for (Rank rank : matchedCount.keySet()) { + if (rank == Rank.SECOND) { + System.out.printf(SECOND_MESSAGE, + rank.getMatchingCount(), + df.format(rank.getPrize()), + matchedCount.get(rank) + ); + continue; + } + + System.out.printf(OTHER_RANK_MESSAGE, + rank.getMatchingCount(), + df.format(rank.getPrize()), + matchedCount.get(rank) + ); + } + System.out.printf(PROFIT_RATE_MESSAGE, lottoResult.getProfitRate()); + } +} diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 309f4e50ae..a1af64972f 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -1,5 +1,6 @@ package lotto; +import lotto.domain.Lotto; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -22,4 +23,5 @@ class LottoTest { } // TODO: 추가 기능 구현에 따른 테스트 코드 작성 + }