From c87fff746a0e72e4cc5b9a1d5b3e7facf13a76eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A4=80=EC=84=9D=28YunJunSeok=29?= Date: Wed, 19 Feb 2025 23:11:45 +0900 Subject: [PATCH 1/9] =?UTF-8?q?Feat:=20=EA=B5=AC=ED=98=84=ED=95=9C=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=EB=A5=BC=20=EC=BB=A4=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Application.java | 9 ++++ src/main/java/controller/LottoController.java | 34 ++++++++++++ src/main/java/model/Lotto.java | 54 +++++++++++++++++++ src/main/java/view/InputView.java | 16 ++++++ src/main/java/view/ResultView.java | 16 ++++++ 5 files changed, 129 insertions(+) create mode 100644 src/main/java/Application.java create mode 100644 src/main/java/controller/LottoController.java create mode 100644 src/main/java/model/Lotto.java create mode 100644 src/main/java/view/InputView.java create mode 100644 src/main/java/view/ResultView.java diff --git a/src/main/java/Application.java b/src/main/java/Application.java new file mode 100644 index 00000000..6db9f734 --- /dev/null +++ b/src/main/java/Application.java @@ -0,0 +1,9 @@ +import controller.LottoController; + +public class Application { + + public static void main(String[] args) { + LottoController lottoController = new LottoController(); + lottoController.run(); + } +} diff --git a/src/main/java/controller/LottoController.java b/src/main/java/controller/LottoController.java new file mode 100644 index 00000000..c6633cc1 --- /dev/null +++ b/src/main/java/controller/LottoController.java @@ -0,0 +1,34 @@ +package controller; + +import model.Lotto; +import view.InputView; +import view.ResultView; + +import java.util.List; +import java.util.stream.Collectors; + +public class LottoController { + + public void run() { + int purchaseAmount = InputView.getPurchaseAmount(); + + int ticketCount = Lotto.getTicketCount(purchaseAmount); + + List tickets = Lotto.generateLottoTickets(ticketCount); + + ResultView.printOrderTickets(ticketCount); + ResultView.printTickets(ticketCount, formatTickets(tickets)); + } + + public List formatTickets(List tickets) { + List formattedTickets = tickets.stream() + .map(lotto -> lotto.getNumbers() + .stream() + .sorted() + .map(String::valueOf) + .collect(Collectors.joining(",","[","]"))) + .toList(); + + return formattedTickets; + } +} diff --git a/src/main/java/model/Lotto.java b/src/main/java/model/Lotto.java new file mode 100644 index 00000000..07694d77 --- /dev/null +++ b/src/main/java/model/Lotto.java @@ -0,0 +1,54 @@ +package model; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class Lotto { + + // 로또 번호 관련 상수 선언 + public static final int LOTTO_MIN_NUMBER = 1; + public static final int LOTTO_MAX_NUMBER = 45; + public static final int LOTTO_CREATE_SIZE = 6; + public static final int LOTTO_PRICE = 1000; + public static final List LOTTO_NUMBER_POOL = + IntStream + .rangeClosed(LOTTO_MIN_NUMBER,LOTTO_MAX_NUMBER) + .boxed() + .collect(Collectors.toList()); + + private List numbers = new ArrayList<>(); + + public static int getTicketCount(int purchaseAmount){ + return purchaseAmount / LOTTO_PRICE; + } + + public Lotto(){ + this.numbers = createLottoNumbers(); + } + + private List createLottoNumbers(){ + List shuffledNumbers = new ArrayList<>(LOTTO_NUMBER_POOL); + Collections.shuffle(shuffledNumbers); + numbers = shuffledNumbers.subList(0, LOTTO_CREATE_SIZE); + + return numbers; + } + + public static List generateLottoTickets(int ticketCount){ + List tickets = new ArrayList<>(); + + for (int i = 0; i < ticketCount; i++){ + tickets.add(new Lotto()); + } + + return tickets; + } + + public List getNumbers() { + List sortedNumbers = new ArrayList<>(numbers); + Collections.sort(sortedNumbers); + + return sortedNumbers; + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 00000000..539b51e2 --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,16 @@ +package view; + +import java.util.Scanner; + +public class InputView { + + private static final Scanner scanner = new Scanner(System.in); + + public static int getPurchaseAmount(){ + System.out.println("구입금액을 입력해 주세요."); + int purchaseAmount = scanner.nextInt(); + scanner.close(); + + return purchaseAmount; + } +} diff --git a/src/main/java/view/ResultView.java b/src/main/java/view/ResultView.java new file mode 100644 index 00000000..dff86d0f --- /dev/null +++ b/src/main/java/view/ResultView.java @@ -0,0 +1,16 @@ +package view; +import java.util.List; + +public class ResultView { + + public static void printOrderTickets(int ticketCount){ + System.out.println(); + System.out.println(ticketCount + "개를 구매했습니다."); + } + + public static void printTickets(int ticketCount ,List formattedTickets){ + for (String ticket : formattedTickets) { + System.out.println(ticket); + } + } +} From a701b7b1fc8522b5a5da185682d399264e017710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A4=80=EC=84=9D=28YunJunSeok=29?= <83647215+junseok0304@users.noreply.github.com> Date: Sat, 22 Feb 2025 16:12:06 +0900 Subject: [PATCH 2/9] Update src/main/java/model/Lotto.java commit suggest Co-authored-by: Ji_Yun <84395062+dd-jiyun@users.noreply.github.com> --- src/main/java/model/Lotto.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/model/Lotto.java b/src/main/java/model/Lotto.java index 07694d77..8d76cafb 100644 --- a/src/main/java/model/Lotto.java +++ b/src/main/java/model/Lotto.java @@ -19,7 +19,7 @@ public class Lotto { private List numbers = new ArrayList<>(); - public static int getTicketCount(int purchaseAmount){ + public static int getTicketCount(int purchaseAmount) { return purchaseAmount / LOTTO_PRICE; } From cbcbfb52d0445672b5986d82a13ab1e37873739a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A4=80=EC=84=9D=28YunJunSeok=29?= Date: Sun, 23 Feb 2025 16:19:23 +0900 Subject: [PATCH 3/9] =?UTF-8?q?Feat:=201=EB=8B=A8=EA=B3=84=20=EB=AF=B8?= =?UTF-8?q?=EC=85=98=20=EB=B3=B4=EC=99=84=20=EC=BB=A4=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/LottoController.java | 24 ++++++++------- src/main/java/model/Lotto.java | 30 ++++++++----------- src/main/java/view/InputView.java | 7 ++--- src/main/java/view/ResultView.java | 6 +++- 4 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/main/java/controller/LottoController.java b/src/main/java/controller/LottoController.java index c6633cc1..e369fae5 100644 --- a/src/main/java/controller/LottoController.java +++ b/src/main/java/controller/LottoController.java @@ -1,34 +1,38 @@ package controller; +import java.util.stream.Collectors; import model.Lotto; import view.InputView; import view.ResultView; import java.util.List; -import java.util.stream.Collectors; public class LottoController { public void run() { - int purchaseAmount = InputView.getPurchaseAmount(); + int purchaseAmount; + int ticketCount; - int ticketCount = Lotto.getTicketCount(purchaseAmount); + do { + purchaseAmount = InputView.getPurchaseAmount(); + ticketCount = Lotto.getTicketCount(purchaseAmount); + if (ticketCount == -1) { + ResultView.printInvalidAmountMessage(); + } + } while (ticketCount == -1); List tickets = Lotto.generateLottoTickets(ticketCount); ResultView.printOrderTickets(ticketCount); - ResultView.printTickets(ticketCount, formatTickets(tickets)); + ResultView.printTickets(formatTickets(tickets)); } - public List formatTickets(List tickets) { - List formattedTickets = tickets.stream() + private List formatTickets(List tickets) { + return tickets.stream() .map(lotto -> lotto.getNumbers() .stream() - .sorted() .map(String::valueOf) - .collect(Collectors.joining(",","[","]"))) + .collect(Collectors.joining(", ", "[", "]"))) .toList(); - - return formattedTickets; } } diff --git a/src/main/java/model/Lotto.java b/src/main/java/model/Lotto.java index 07694d77..dfd8feff 100644 --- a/src/main/java/model/Lotto.java +++ b/src/main/java/model/Lotto.java @@ -6,49 +6,45 @@ public class Lotto { - // 로또 번호 관련 상수 선언 public static final int LOTTO_MIN_NUMBER = 1; public static final int LOTTO_MAX_NUMBER = 45; public static final int LOTTO_CREATE_SIZE = 6; public static final int LOTTO_PRICE = 1000; public static final List LOTTO_NUMBER_POOL = - IntStream - .rangeClosed(LOTTO_MIN_NUMBER,LOTTO_MAX_NUMBER) + IntStream.rangeClosed(LOTTO_MIN_NUMBER, LOTTO_MAX_NUMBER) .boxed() .collect(Collectors.toList()); - private List numbers = new ArrayList<>(); + private final List numbers; - public static int getTicketCount(int purchaseAmount){ - return purchaseAmount / LOTTO_PRICE; + public Lotto() { + this.numbers = createLottoNumbers(); } - public Lotto(){ - this.numbers = createLottoNumbers(); + public static int getTicketCount(int purchaseAmount) { + if (purchaseAmount % LOTTO_PRICE != 0) { + return -1; + } + return purchaseAmount / LOTTO_PRICE; } - private List createLottoNumbers(){ + private List createLottoNumbers() { List shuffledNumbers = new ArrayList<>(LOTTO_NUMBER_POOL); Collections.shuffle(shuffledNumbers); - numbers = shuffledNumbers.subList(0, LOTTO_CREATE_SIZE); - - return numbers; + return shuffledNumbers.subList(0, LOTTO_CREATE_SIZE); } - public static List generateLottoTickets(int ticketCount){ + public static List generateLottoTickets(int ticketCount) { List tickets = new ArrayList<>(); - - for (int i = 0; i < ticketCount; i++){ + for (int i = 0; i < ticketCount; i++) { tickets.add(new Lotto()); } - return tickets; } public List getNumbers() { List sortedNumbers = new ArrayList<>(numbers); Collections.sort(sortedNumbers); - return sortedNumbers; } } diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 539b51e2..4a91a42f 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -6,11 +6,8 @@ public class InputView { private static final Scanner scanner = new Scanner(System.in); - public static int getPurchaseAmount(){ + public static int getPurchaseAmount() { System.out.println("구입금액을 입력해 주세요."); - int purchaseAmount = scanner.nextInt(); - scanner.close(); - - return purchaseAmount; + return scanner.nextInt(); } } diff --git a/src/main/java/view/ResultView.java b/src/main/java/view/ResultView.java index dff86d0f..dae27364 100644 --- a/src/main/java/view/ResultView.java +++ b/src/main/java/view/ResultView.java @@ -3,12 +3,16 @@ public class ResultView { + public static void printInvalidAmountMessage() { + System.out.println("1000원 단위로 입력해주세요."); + } + public static void printOrderTickets(int ticketCount){ System.out.println(); System.out.println(ticketCount + "개를 구매했습니다."); } - public static void printTickets(int ticketCount ,List formattedTickets){ + public static void printTickets(List formattedTickets){ for (String ticket : formattedTickets) { System.out.println(ticket); } From 0ab362a4b38d39da692e9124d535c29cd9949de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A4=80=EC=84=9D=28YunJunSeok=29?= Date: Sun, 23 Feb 2025 16:22:01 +0900 Subject: [PATCH 4/9] =?UTF-8?q?Fix:=20=EA=B4=84=ED=98=B8=20=EC=97=B4?= =?UTF-8?q?=EA=B8=B0=20=EC=A0=84=20=EB=9D=84=EC=96=B4=EC=93=B0=EA=B8=B0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/ResultView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/view/ResultView.java b/src/main/java/view/ResultView.java index dae27364..e26b58e4 100644 --- a/src/main/java/view/ResultView.java +++ b/src/main/java/view/ResultView.java @@ -7,12 +7,12 @@ public static void printInvalidAmountMessage() { System.out.println("1000원 단위로 입력해주세요."); } - public static void printOrderTickets(int ticketCount){ + public static void printOrderTickets(int ticketCount) { System.out.println(); System.out.println(ticketCount + "개를 구매했습니다."); } - public static void printTickets(List formattedTickets){ + public static void printTickets(List formattedTickets) { for (String ticket : formattedTickets) { System.out.println(ticket); } From e45c0d35321b2c46f2343c6173cbf71d193e3581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A4=80=EC=84=9D=28YunJunSeok=29?= Date: Sun, 2 Mar 2025 23:41:42 +0900 Subject: [PATCH 5/9] =?UTF-8?q?Feat:=202,3,4=EB=8B=A8=EA=B3=84=20=EB=A1=9C?= =?UTF-8?q?=EB=98=90=20=EB=AF=B8=EC=85=98=20=EC=88=98=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Application.java | 15 ++- src/main/java/config/LottoConstants.java | 18 ++++ src/main/java/controller/LottoController.java | 38 ------- .../controller/LottoMachineController.java | 40 +++++++ src/main/java/model/Lotto.java | 61 +++++------ src/main/java/model/LottoMachine.java | 46 ++++++++ src/main/java/model/LottoResultChecker.java | 51 +++++++++ src/main/java/view/InputView.java | 100 +++++++++++++++++- src/main/java/view/ResultView.java | 26 +++-- 9 files changed, 308 insertions(+), 87 deletions(-) create mode 100644 src/main/java/config/LottoConstants.java delete mode 100644 src/main/java/controller/LottoController.java create mode 100644 src/main/java/controller/LottoMachineController.java create mode 100644 src/main/java/model/LottoMachine.java create mode 100644 src/main/java/model/LottoResultChecker.java diff --git a/src/main/java/Application.java b/src/main/java/Application.java index 6db9f734..17b79435 100644 --- a/src/main/java/Application.java +++ b/src/main/java/Application.java @@ -1,9 +1,18 @@ -import controller.LottoController; +import controller.LottoMachineController; public class Application { public static void main(String[] args) { - LottoController lottoController = new LottoController(); - lottoController.run(); + LottoMachineController lottoMachine = new LottoMachineController(); + lottoMachine.run(); } } + +// 일단 고민을 해보자. +// 로또 수동 모델과 로또 자동 모델을 나누어서 진행하는 방안이 어떨까? +// 1. 사용자 구입 금액 입력 -> 수동 구매 장수 입력 -> 수동 구매 번호 입력 -> +// 2. 수동 n장 자동 m장 수량 출력 -> 수동 구매 번호 출력, 자동 구매 번호 출력 +// 3. 지난 주 당첨 번호 입력(6개), 보너스 볼(1개) 입력 +// 4. 당첨 통계 출력 (3,4,5,5+보,6 개 일치) 일치 갯수, 총 수익률 출력 +// 로또 서비스를 만들자 (자동,수동 로또 생성을 담당하게 해서 컨트롤러의 기능을 분산해줌) +// 당첨 결과를 분리해서 만들자. diff --git a/src/main/java/config/LottoConstants.java b/src/main/java/config/LottoConstants.java new file mode 100644 index 00000000..cf74fdf3 --- /dev/null +++ b/src/main/java/config/LottoConstants.java @@ -0,0 +1,18 @@ +package config; + +public enum LottoConstants { + MIN_NUMBER(1), + MAX_NUMBER(45), + LOTTO_SIZE(6), + LOTTO_PRICE(1000); + + private final int value; + + LottoConstants(int value) { + this.value = value; + } + + public int getValue() { + return value; + } +} diff --git a/src/main/java/controller/LottoController.java b/src/main/java/controller/LottoController.java deleted file mode 100644 index e369fae5..00000000 --- a/src/main/java/controller/LottoController.java +++ /dev/null @@ -1,38 +0,0 @@ -package controller; - -import java.util.stream.Collectors; -import model.Lotto; -import view.InputView; -import view.ResultView; - -import java.util.List; - -public class LottoController { - - public void run() { - int purchaseAmount; - int ticketCount; - - do { - purchaseAmount = InputView.getPurchaseAmount(); - ticketCount = Lotto.getTicketCount(purchaseAmount); - if (ticketCount == -1) { - ResultView.printInvalidAmountMessage(); - } - } while (ticketCount == -1); - - List tickets = Lotto.generateLottoTickets(ticketCount); - - ResultView.printOrderTickets(ticketCount); - ResultView.printTickets(formatTickets(tickets)); - } - - private List formatTickets(List tickets) { - return tickets.stream() - .map(lotto -> lotto.getNumbers() - .stream() - .map(String::valueOf) - .collect(Collectors.joining(", ", "[", "]"))) - .toList(); - } -} diff --git a/src/main/java/controller/LottoMachineController.java b/src/main/java/controller/LottoMachineController.java new file mode 100644 index 00000000..82607415 --- /dev/null +++ b/src/main/java/controller/LottoMachineController.java @@ -0,0 +1,40 @@ +package controller; + +import model.Lotto; +import model.LottoMachine; +import model.LottoResultChecker; +import view.InputView; +import view.ResultView; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class LottoMachineController { + public void run() { + int purchaseAmount = InputView.getPurchaseAmount(); + int totalTicketCount = LottoMachine.getTicketCount(purchaseAmount); + + int manualTicketCount = InputView.getManualTicketCount(); + int autoTicketCount = totalTicketCount - manualTicketCount; + + List> manualNumbers = InputView.getManualLottoNumbers(manualTicketCount); + List tickets = LottoMachine.generateLottos(manualNumbers, purchaseAmount); + + List formattedTickets = tickets.stream() + .map(Lotto::toString) + .collect(Collectors.toList()); + + ResultView.printOrderTickets(manualTicketCount, autoTicketCount); + ResultView.printTickets(formattedTickets); + + List winningNumbers = InputView.getWinningNumbers(); + int bonusNumber = InputView.getBonusNumber(); + + Map results = LottoResultChecker.checkWinningResults(tickets, winningNumbers, bonusNumber); + int totalPrize = results.get("totalPrize"); + double profitRate = LottoResultChecker.calculateProfitRate(totalPrize, purchaseAmount); + + ResultView.printWinningStatistics(results, profitRate); + } +} diff --git a/src/main/java/model/Lotto.java b/src/main/java/model/Lotto.java index dfd8feff..aff32c8c 100644 --- a/src/main/java/model/Lotto.java +++ b/src/main/java/model/Lotto.java @@ -1,50 +1,41 @@ package model; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.IntStream; +import config.LottoConstants; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; -public class Lotto { - - public static final int LOTTO_MIN_NUMBER = 1; - public static final int LOTTO_MAX_NUMBER = 45; - public static final int LOTTO_CREATE_SIZE = 6; - public static final int LOTTO_PRICE = 1000; - public static final List LOTTO_NUMBER_POOL = - IntStream.rangeClosed(LOTTO_MIN_NUMBER, LOTTO_MAX_NUMBER) - .boxed() - .collect(Collectors.toList()); +public class Lotto { private final List numbers; - public Lotto() { - this.numbers = createLottoNumbers(); + public Lotto(List numbers) { + validateNumbers(numbers); + this.numbers = new ArrayList<>(numbers); + Collections.sort(this.numbers); } - public static int getTicketCount(int purchaseAmount) { - if (purchaseAmount % LOTTO_PRICE != 0) { - return -1; + private void validateNumbers(List numbers) { + if (numbers.size() != LottoConstants.LOTTO_SIZE.getValue()) { + throw new IllegalArgumentException("로또 번호는 6개여야 합니다."); } - return purchaseAmount / LOTTO_PRICE; - } - - private List createLottoNumbers() { - List shuffledNumbers = new ArrayList<>(LOTTO_NUMBER_POOL); - Collections.shuffle(shuffledNumbers); - return shuffledNumbers.subList(0, LOTTO_CREATE_SIZE); - } - - public static List generateLottoTickets(int ticketCount) { - List tickets = new ArrayList<>(); - for (int i = 0; i < ticketCount; i++) { - tickets.add(new Lotto()); + if (new HashSet<>(numbers).size() != LottoConstants.LOTTO_SIZE.getValue()) { + throw new IllegalArgumentException("로또 번호는 중복될 수 없습니다."); + } + for (int number : numbers) { + if (number < LottoConstants.MIN_NUMBER.getValue() || number > LottoConstants.MAX_NUMBER.getValue()) { + throw new IllegalArgumentException("로또 번호는 1~45 사이여야 합니다."); + } } - return tickets; } public List getNumbers() { - List sortedNumbers = new ArrayList<>(numbers); - Collections.sort(sortedNumbers); - return sortedNumbers; + return new ArrayList<>(numbers); + } + + @Override + public String toString() { + return numbers.toString(); } } diff --git a/src/main/java/model/LottoMachine.java b/src/main/java/model/LottoMachine.java new file mode 100644 index 00000000..11a83901 --- /dev/null +++ b/src/main/java/model/LottoMachine.java @@ -0,0 +1,46 @@ +package model; + +import config.LottoConstants; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.IntStream; + +public class LottoMachine { + private static final int LOTTO_PRICE = LottoConstants.LOTTO_PRICE.getValue(); + private static final List LOTTO_NUMBER_POOL = + IntStream.rangeClosed(LottoConstants.MIN_NUMBER.getValue(), LottoConstants.MAX_NUMBER.getValue()) + .boxed() + .toList(); + + public static int getTicketCount(int purchaseAmount) { + if (purchaseAmount % LOTTO_PRICE != 0) { + throw new IllegalArgumentException("구매 금액은 1000원 단위여야 합니다."); + } + return purchaseAmount / LOTTO_PRICE; + } + + private static Lotto generateAutoLotto() { + List shuffledNumbers = new ArrayList<>(LOTTO_NUMBER_POOL); + Collections.shuffle(shuffledNumbers); + return new Lotto(shuffledNumbers.subList(0, LottoConstants.LOTTO_SIZE.getValue())); + } + + public static List generateLottos(List> manualNumbers, int purchaseAmount) { + int totalTicketCount = getTicketCount(purchaseAmount); + int manualCount = manualNumbers.size(); + int autoCount = totalTicketCount - manualCount; + + if (manualCount > totalTicketCount) { + throw new IllegalArgumentException("구매 가능한 로또 개수를 초과했습니다."); + } + + List lottos = new ArrayList<>(); + manualNumbers.forEach(numbers -> lottos.add(new Lotto(numbers))); + for (int i = 0; i < autoCount; i++) { + lottos.add(generateAutoLotto()); + } + + return lottos; + } +} diff --git a/src/main/java/model/LottoResultChecker.java b/src/main/java/model/LottoResultChecker.java new file mode 100644 index 00000000..3efba6fc --- /dev/null +++ b/src/main/java/model/LottoResultChecker.java @@ -0,0 +1,51 @@ +package model; + +import java.util.*; + +public class LottoResultChecker { + private static final Map WINNING_PRIZE_MAP = Map.of( + 3, 5000, + 4, 50000, + 5, 1500000, + 6, 2000000000 + ); + + private static final int BONUS_MATCH_PRIZE = 30000000; + + public static Map checkWinningResults(List purchasedLottos, List winningNumbers, int bonusNumber) { + Map result = new LinkedHashMap<>(); + result.put("3개 일치 (5000원)", 0); + result.put("4개 일치 (50000원)", 0); + result.put("5개 일치 (1500000원)", 0); + result.put("5개 일치, 보너스 볼 일치(30000000원)", 0); + result.put("6개 일치 (2000000000원)", 0); + + int totalPrize = 0; + Set winningSet = new HashSet<>(winningNumbers); + + for (Lotto lotto : purchasedLottos) { + Set lottoNumbers = new HashSet<>(lotto.getNumbers()); + int matchCount = (int) lottoNumbers.stream().filter(winningSet::contains).count(); + boolean hasBonus = lottoNumbers.contains(bonusNumber); + + if (matchCount == 6) { + totalPrize += WINNING_PRIZE_MAP.get(6); + result.put("6개 일치 (2000000000원)", result.get("6개 일치 (2000000000원)") + 1); + } else if (matchCount == 5 && hasBonus) { + totalPrize += BONUS_MATCH_PRIZE; + result.put("5개 일치, 보너스 볼 일치(30000000원)", result.get("5개 일치, 보너스 볼 일치(30000000원)") + 1); + } else if (WINNING_PRIZE_MAP.containsKey(matchCount)) { + totalPrize += WINNING_PRIZE_MAP.get(matchCount); + String key = matchCount + "개 일치 (" + WINNING_PRIZE_MAP.get(matchCount) + "원)"; + result.put(key, result.getOrDefault(key, 0) + 1); + } + } + + result.put("totalPrize", totalPrize); + return result; + } + + public static double calculateProfitRate(int totalPrize, int purchaseAmount) { + return purchaseAmount == 0 ? 0 : (double) totalPrize / purchaseAmount; + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 4a91a42f..691bd718 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -1,13 +1,109 @@ package view; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; import java.util.Scanner; +import java.util.Set; public class InputView { - private static final Scanner scanner = new Scanner(System.in); public static int getPurchaseAmount() { System.out.println("구입금액을 입력해 주세요."); - return scanner.nextInt(); + while (true) { + try { + int amount = Integer.parseInt(scanner.nextLine().trim()); + if (amount <= 0) { + throw new IllegalArgumentException("금액은 0보다 커야 합니다."); + } + return amount; + } catch (IllegalArgumentException e) { + System.out.println("유효한 금액을 입력하세요. (1000원 단위의 숫자)"); + } + } + } + + public static int getManualTicketCount() { + System.out.println("수동으로 구매할 로또 수를 입력해 주세요."); + while (true) { + try { + int count = Integer.parseInt(scanner.nextLine().trim()); + if (count < 0) { + throw new IllegalArgumentException("수동 구매 개수는 0 이상이어야 합니다."); + } + return count; + } catch (IllegalArgumentException e) { + System.out.println("유효한 개수를 입력하세요. (0 이상의 숫자)"); + } + } + } + + public static List> getManualLottoNumbers(int count) { + System.out.println("수동으로 구매할 번호를 입력해 주세요."); + List> manualNumbers = new ArrayList<>(); + for (int i = 0; i < count; i++) { + while (true) { + try { + System.out.printf("로또 번호 %d/%d 입력: ", i + 1, count); + String input = scanner.nextLine().trim(); + List numbers = parseLottoNumbers(input); + manualNumbers.add(numbers); + break; + } catch (IllegalArgumentException e) { + System.out.println("1~45 사이의 중복되지 않은 6개의 숫자를 입력하세요."); + } + } + } + return manualNumbers; + } + + public static List getWinningNumbers() { + System.out.println("지난 주 당첨 번호를 입력해 주세요."); + while (true) { + try { + return parseLottoNumbers(scanner.nextLine().trim()); + } catch (IllegalArgumentException e) { + System.out.println("1~45 사이의 중복되지 않은 6개의 숫자를 입력하세요."); + } + } + } + + public static int getBonusNumber() { + System.out.println("보너스 볼을 입력해 주세요."); + while (true) { + try { + int bonus = Integer.parseInt(scanner.nextLine().trim()); + if (bonus < 1 || bonus > 45) { + throw new IllegalArgumentException("보너스 번호는 1~45 사이여야 합니다."); + } + return bonus; + } catch (IllegalArgumentException e) { + System.out.println("1~45 사이의 보너스 번호를 입력하세요."); + } + } + } + + private static List parseLottoNumbers(String input) { + List numbers = Arrays.stream(input.split(",")) + .map(String::trim) + .map(Integer::parseInt) + .toList(); + + if (numbers.size() != 6) { + throw new IllegalArgumentException("로또 번호는 6개여야 합니다."); + } + + Set uniqueNumbers = new HashSet<>(numbers); + if (uniqueNumbers.size() != 6) { + throw new IllegalArgumentException("로또 번호는 중복될 수 없습니다."); + } + + if (numbers.stream().anyMatch(n -> n < 1 || n > 45)) { + throw new IllegalArgumentException("로또 번호는 1~45 사이여야 합니다."); + } + + return new ArrayList<>(uniqueNumbers); } } diff --git a/src/main/java/view/ResultView.java b/src/main/java/view/ResultView.java index e26b58e4..1599b6b0 100644 --- a/src/main/java/view/ResultView.java +++ b/src/main/java/view/ResultView.java @@ -1,20 +1,28 @@ package view; + import java.util.List; +import java.util.Map; public class ResultView { - - public static void printInvalidAmountMessage() { - System.out.println("1000원 단위로 입력해주세요."); + + public static void printOrderTickets(int manualCount, int autoCount) { + System.out.printf("수동으로 %d장, 자동으로 %d개를 구매했습니다.\n", manualCount, autoCount); } - public static void printOrderTickets(int ticketCount) { - System.out.println(); - System.out.println(ticketCount + "개를 구매했습니다."); + public static void printTickets(List tickets) { + tickets.forEach(System.out::println); } - public static void printTickets(List formattedTickets) { - for (String ticket : formattedTickets) { - System.out.println(ticket); + public static void printWinningStatistics(Map results, double profitRate) { + System.out.println("\n당첨 통계"); + System.out.println("---------"); + for (Map.Entry entry : results.entrySet()) { + if (!entry.getKey().equals("totalPrize")) { + System.out.println(entry.getKey() + " - " + entry.getValue() + "개"); + } } + + System.out.printf("총 수익률은 %.2f입니다. (기준이 1이기 때문에 결과적으로 %s라는 의미임)\n", + profitRate, profitRate >= 1 ? "이득" : "손해"); } } From 8346e52e26b4fe1abf75984f5faa5f6f8e451992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A4=80=EC=84=9D=28YunJunSeok=29?= Date: Mon, 3 Mar 2025 00:01:13 +0900 Subject: [PATCH 6/9] =?UTF-8?q?Fix:=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C?= =?UTF-8?q?=20=EC=A3=BC=EC=84=9D=20=EC=82=AD=EC=A0=9C=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B0=9C=ED=96=89=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Application.java | 9 --------- src/main/java/view/ResultView.java | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/main/java/Application.java b/src/main/java/Application.java index 17b79435..7f3db658 100644 --- a/src/main/java/Application.java +++ b/src/main/java/Application.java @@ -7,12 +7,3 @@ public static void main(String[] args) { lottoMachine.run(); } } - -// 일단 고민을 해보자. -// 로또 수동 모델과 로또 자동 모델을 나누어서 진행하는 방안이 어떨까? -// 1. 사용자 구입 금액 입력 -> 수동 구매 장수 입력 -> 수동 구매 번호 입력 -> -// 2. 수동 n장 자동 m장 수량 출력 -> 수동 구매 번호 출력, 자동 구매 번호 출력 -// 3. 지난 주 당첨 번호 입력(6개), 보너스 볼(1개) 입력 -// 4. 당첨 통계 출력 (3,4,5,5+보,6 개 일치) 일치 갯수, 총 수익률 출력 -// 로또 서비스를 만들자 (자동,수동 로또 생성을 담당하게 해서 컨트롤러의 기능을 분산해줌) -// 당첨 결과를 분리해서 만들자. diff --git a/src/main/java/view/ResultView.java b/src/main/java/view/ResultView.java index 1599b6b0..68d1dddf 100644 --- a/src/main/java/view/ResultView.java +++ b/src/main/java/view/ResultView.java @@ -4,7 +4,7 @@ import java.util.Map; public class ResultView { - + public static void printOrderTickets(int manualCount, int autoCount) { System.out.printf("수동으로 %d장, 자동으로 %d개를 구매했습니다.\n", manualCount, autoCount); } From 08f759e1876e4671e7c38814dbd492ff32fccdeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A4=80=EC=84=9D=28YunJunSeok=29?= Date: Tue, 4 Mar 2025 12:17:03 +0900 Subject: [PATCH 7/9] =?UTF-8?q?Fix:=20=EC=82=BC=ED=95=AD=EC=97=B0=EC=82=B0?= =?UTF-8?q?=EC=9E=90=20=EC=82=AD=EC=A0=9C,=20=EC=9A=B0=EC=8A=B9=EC=9E=90?= =?UTF-8?q?=EB=9E=AD=ED=81=AC=20enum=20=EC=82=AC=EC=9A=A9,=20else=EB=AC=B8?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/config/WinningRank.java | 40 ++++++++++++ src/main/java/model/LottoResultChecker.java | 72 ++++++++++++--------- 2 files changed, 81 insertions(+), 31 deletions(-) create mode 100644 src/main/java/config/WinningRank.java diff --git a/src/main/java/config/WinningRank.java b/src/main/java/config/WinningRank.java new file mode 100644 index 00000000..63630b0e --- /dev/null +++ b/src/main/java/config/WinningRank.java @@ -0,0 +1,40 @@ +package config; + +import java.util.Arrays; +import java.util.Optional; + +public enum WinningRank { + MATCH_3(3, 5000, "3개 일치 (5000원)"), + MATCH_4(4, 50000, "4개 일치 (50000원)"), + MATCH_5(5, 1500000, "5개 일치 (1500000원)"), + MATCH_5_BONUS(5, 30000000, "5개 일치, 보너스 볼 일치(30000000원)"), + MATCH_6(6, 2000000000, "6개 일치 (2000000000원)"), + NO_MATCH(0, 0, "꽝"); + + private final int matchCount; + private final int prize; + private final String description; + + WinningRank(int matchCount, int prize, String description) { + this.matchCount = matchCount; + this.prize = prize; + this.description = description; + } + + public int getPrize() { + return prize; + } + + public String getDescription() { + return description; + } + + public static Optional findByMatchCount(int matchCount, boolean hasBonus) { + if (matchCount == 5 && hasBonus) { + return Optional.of(MATCH_5_BONUS); + } + return Arrays.stream(values()) + .filter(rank -> rank.matchCount == matchCount) + .findFirst(); + } +} diff --git a/src/main/java/model/LottoResultChecker.java b/src/main/java/model/LottoResultChecker.java index 3efba6fc..aed44663 100644 --- a/src/main/java/model/LottoResultChecker.java +++ b/src/main/java/model/LottoResultChecker.java @@ -1,51 +1,61 @@ package model; +import config.WinningRank; import java.util.*; public class LottoResultChecker { - private static final Map WINNING_PRIZE_MAP = Map.of( - 3, 5000, - 4, 50000, - 5, 1500000, - 6, 2000000000 - ); - - private static final int BONUS_MATCH_PRIZE = 30000000; public static Map checkWinningResults(List purchasedLottos, List winningNumbers, int bonusNumber) { - Map result = new LinkedHashMap<>(); - result.put("3개 일치 (5000원)", 0); - result.put("4개 일치 (50000원)", 0); - result.put("5개 일치 (1500000원)", 0); - result.put("5개 일치, 보너스 볼 일치(30000000원)", 0); - result.put("6개 일치 (2000000000원)", 0); - + Map result = initializeResultMap(); int totalPrize = 0; Set winningSet = new HashSet<>(winningNumbers); for (Lotto lotto : purchasedLottos) { - Set lottoNumbers = new HashSet<>(lotto.getNumbers()); - int matchCount = (int) lottoNumbers.stream().filter(winningSet::contains).count(); - boolean hasBonus = lottoNumbers.contains(bonusNumber); - - if (matchCount == 6) { - totalPrize += WINNING_PRIZE_MAP.get(6); - result.put("6개 일치 (2000000000원)", result.get("6개 일치 (2000000000원)") + 1); - } else if (matchCount == 5 && hasBonus) { - totalPrize += BONUS_MATCH_PRIZE; - result.put("5개 일치, 보너스 볼 일치(30000000원)", result.get("5개 일치, 보너스 볼 일치(30000000원)") + 1); - } else if (WINNING_PRIZE_MAP.containsKey(matchCount)) { - totalPrize += WINNING_PRIZE_MAP.get(matchCount); - String key = matchCount + "개 일치 (" + WINNING_PRIZE_MAP.get(matchCount) + "원)"; - result.put(key, result.getOrDefault(key, 0) + 1); - } + int matchCount = getMatchCount(lotto, winningSet); + boolean hasBonus = hasBonusMatch(lotto, bonusNumber); + totalPrize += updateResults(result, matchCount, hasBonus); } result.put("totalPrize", totalPrize); return result; } + private static Map initializeResultMap() { + Map result = new LinkedHashMap<>(); + for (WinningRank rank : WinningRank.values()) { + if (rank != WinningRank.NO_MATCH) { + result.put(rank.getDescription(), 0); // 🛠️ 당첨 개수 0으로 초기화 + } + } + return result; + } + + private static int getMatchCount(Lotto lotto, Set winningSet) { + return (int) lotto.getNumbers().stream().filter(winningSet::contains).count(); + } + + private static boolean hasBonusMatch(Lotto lotto, int bonusNumber) { + return lotto.getNumbers().contains(bonusNumber); + } + + private static int updateResults(Map result, int matchCount, boolean hasBonus) { + Optional rank = WinningRank.findByMatchCount(matchCount, hasBonus); + if (rank.isEmpty()) { + return 0; + } + + WinningRank winningRank = rank.get(); + String key = winningRank.getDescription(); + + result.put(key, result.getOrDefault(key, 0) + 1); + + return winningRank.getPrize(); + } + public static double calculateProfitRate(int totalPrize, int purchaseAmount) { - return purchaseAmount == 0 ? 0 : (double) totalPrize / purchaseAmount; + if (purchaseAmount == 0) { + return 0.0; + } + return (double) totalPrize / purchaseAmount; } } From be25676d9f31eb656a50670cad21805ca841d82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A4=80=EC=84=9D=28YunJunSeok=29?= Date: Tue, 4 Mar 2025 12:35:32 +0900 Subject: [PATCH 8/9] =?UTF-8?q?Fix:=20=EC=82=BC=ED=95=AD=EC=97=B0=EC=82=B0?= =?UTF-8?q?=EC=9E=90=20=EC=82=AD=EC=A0=9C,=20LottoValidator=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=20InputView,=20ResultView=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/config/LottoValidator.java | 48 ++++++++++ .../controller/LottoMachineController.java | 72 +++++++++++++-- src/main/java/view/InputView.java | 88 ++----------------- src/main/java/view/ResultView.java | 31 ++++++- 4 files changed, 150 insertions(+), 89 deletions(-) create mode 100644 src/main/java/config/LottoValidator.java diff --git a/src/main/java/config/LottoValidator.java b/src/main/java/config/LottoValidator.java new file mode 100644 index 00000000..7ad8f858 --- /dev/null +++ b/src/main/java/config/LottoValidator.java @@ -0,0 +1,48 @@ +package config; + +import java.util.*; + +public class LottoValidator { + public static void validatePurchaseAmount(int amount) { + if (amount <= 0) { + throw new IllegalArgumentException("구매 금액은 0보다 커야 합니다."); + } + if (amount % 1000 != 0) { + throw new IllegalArgumentException("구매 금액은 1000원 단위여야 합니다."); + } + } + + public static void validateManualTicketCount(int count) { + if (count < 0) { + throw new IllegalArgumentException("수동 구매 개수는 0 이상이어야 합니다."); + } + } + + public static List validateAndParseLottoNumbers(String input) { + List numbers = Arrays.stream(input.split(",")) + .map(String::trim) + .map(Integer::parseInt) + .toList(); + + if (numbers.size() != 6) { + throw new IllegalArgumentException("로또 번호는 6개여야 합니다."); + } + + Set uniqueNumbers = new HashSet<>(numbers); + if (uniqueNumbers.size() != 6) { + throw new IllegalArgumentException("로또 번호는 중복될 수 없습니다."); + } + + if (numbers.stream().anyMatch(n -> n < 1 || n > 45)) { + throw new IllegalArgumentException("로또 번호는 1~45 사이여야 합니다."); + } + + return new ArrayList<>(uniqueNumbers); + } + + public static void validateBonusNumber(int bonus) { + if (bonus < 1 || bonus > 45) { + throw new IllegalArgumentException("보너스 번호는 1~45 사이여야 합니다."); + } + } +} diff --git a/src/main/java/controller/LottoMachineController.java b/src/main/java/controller/LottoMachineController.java index 82607415..0da47d59 100644 --- a/src/main/java/controller/LottoMachineController.java +++ b/src/main/java/controller/LottoMachineController.java @@ -3,6 +3,7 @@ import model.Lotto; import model.LottoMachine; import model.LottoResultChecker; +import config.LottoValidator; import view.InputView; import view.ResultView; @@ -12,24 +13,77 @@ public class LottoMachineController { public void run() { - int purchaseAmount = InputView.getPurchaseAmount(); + int purchaseAmount; + + while (true) { + try { + purchaseAmount = InputView.getPurchaseAmount(); + LottoValidator.validatePurchaseAmount(purchaseAmount); + break; + } catch (IllegalArgumentException e) { + ResultView.printInvalidAmountMessage(); + } + } + int totalTicketCount = LottoMachine.getTicketCount(purchaseAmount); - int manualTicketCount = InputView.getManualTicketCount(); + int manualTicketCount; + while (true) { + try { + manualTicketCount = InputView.getManualTicketCount(); + LottoValidator.validateManualTicketCount(manualTicketCount); + if (manualTicketCount > totalTicketCount) { + ResultView.printInvalidManualTicketMessage(); + continue; + } + break; + } catch (IllegalArgumentException e) { + ResultView.printInvalidManualCountMessage(); + } + } + int autoTicketCount = totalTicketCount - manualTicketCount; - List> manualNumbers = InputView.getManualLottoNumbers(manualTicketCount); - List tickets = LottoMachine.generateLottos(manualNumbers, purchaseAmount); + List> manualNumbers; + while (true) { + try { + List inputNumbers = InputView.getManualLottoNumbers(manualTicketCount); + manualNumbers = inputNumbers.stream() + .map(LottoValidator::validateAndParseLottoNumbers) + .collect(Collectors.toList()); + break; + } catch (IllegalArgumentException e) { + ResultView.printInvalidLottoNumbersMessage(); + } + } - List formattedTickets = tickets.stream() - .map(Lotto::toString) - .collect(Collectors.toList()); + List tickets = LottoMachine.generateLottos(manualNumbers, purchaseAmount); + List formattedTickets = tickets.stream().map(Lotto::toString).collect(Collectors.toList()); ResultView.printOrderTickets(manualTicketCount, autoTicketCount); ResultView.printTickets(formattedTickets); - List winningNumbers = InputView.getWinningNumbers(); - int bonusNumber = InputView.getBonusNumber(); + List winningNumbers; + while (true) { + try { + String input = InputView.getWinningNumbers(); + winningNumbers = LottoValidator.validateAndParseLottoNumbers(input); + break; + } catch (IllegalArgumentException e) { + ResultView.printInvalidWinningNumbersMessage(); + } + } + + int bonusNumber; + while (true) { + try { + bonusNumber = InputView.getBonusNumber(); + LottoValidator.validateBonusNumber(bonusNumber); + break; + } catch (IllegalArgumentException e) { + ResultView.printInvalidBonusNumberMessage(); + } + } Map results = LottoResultChecker.checkWinningResults(tickets, winningNumbers, bonusNumber); int totalPrize = results.get("totalPrize"); diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 691bd718..32e86c86 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -1,109 +1,39 @@ package view; import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; import java.util.List; import java.util.Scanner; -import java.util.Set; public class InputView { private static final Scanner scanner = new Scanner(System.in); public static int getPurchaseAmount() { System.out.println("구입금액을 입력해 주세요."); - while (true) { - try { - int amount = Integer.parseInt(scanner.nextLine().trim()); - if (amount <= 0) { - throw new IllegalArgumentException("금액은 0보다 커야 합니다."); - } - return amount; - } catch (IllegalArgumentException e) { - System.out.println("유효한 금액을 입력하세요. (1000원 단위의 숫자)"); - } - } + return Integer.parseInt(scanner.nextLine().trim()); } public static int getManualTicketCount() { System.out.println("수동으로 구매할 로또 수를 입력해 주세요."); - while (true) { - try { - int count = Integer.parseInt(scanner.nextLine().trim()); - if (count < 0) { - throw new IllegalArgumentException("수동 구매 개수는 0 이상이어야 합니다."); - } - return count; - } catch (IllegalArgumentException e) { - System.out.println("유효한 개수를 입력하세요. (0 이상의 숫자)"); - } - } + return Integer.parseInt(scanner.nextLine().trim()); } - public static List> getManualLottoNumbers(int count) { + public static List getManualLottoNumbers(int count) { System.out.println("수동으로 구매할 번호를 입력해 주세요."); - List> manualNumbers = new ArrayList<>(); + List manualNumbers = new ArrayList<>(); for (int i = 0; i < count; i++) { - while (true) { - try { - System.out.printf("로또 번호 %d/%d 입력: ", i + 1, count); - String input = scanner.nextLine().trim(); - List numbers = parseLottoNumbers(input); - manualNumbers.add(numbers); - break; - } catch (IllegalArgumentException e) { - System.out.println("1~45 사이의 중복되지 않은 6개의 숫자를 입력하세요."); - } - } + System.out.printf("로또 번호 %d/%d 입력: ", i + 1, count); + manualNumbers.add(scanner.nextLine().trim()); } return manualNumbers; } - public static List getWinningNumbers() { + public static String getWinningNumbers() { System.out.println("지난 주 당첨 번호를 입력해 주세요."); - while (true) { - try { - return parseLottoNumbers(scanner.nextLine().trim()); - } catch (IllegalArgumentException e) { - System.out.println("1~45 사이의 중복되지 않은 6개의 숫자를 입력하세요."); - } - } + return scanner.nextLine().trim(); } public static int getBonusNumber() { System.out.println("보너스 볼을 입력해 주세요."); - while (true) { - try { - int bonus = Integer.parseInt(scanner.nextLine().trim()); - if (bonus < 1 || bonus > 45) { - throw new IllegalArgumentException("보너스 번호는 1~45 사이여야 합니다."); - } - return bonus; - } catch (IllegalArgumentException e) { - System.out.println("1~45 사이의 보너스 번호를 입력하세요."); - } - } - } - - private static List parseLottoNumbers(String input) { - List numbers = Arrays.stream(input.split(",")) - .map(String::trim) - .map(Integer::parseInt) - .toList(); - - if (numbers.size() != 6) { - throw new IllegalArgumentException("로또 번호는 6개여야 합니다."); - } - - Set uniqueNumbers = new HashSet<>(numbers); - if (uniqueNumbers.size() != 6) { - throw new IllegalArgumentException("로또 번호는 중복될 수 없습니다."); - } - - if (numbers.stream().anyMatch(n -> n < 1 || n > 45)) { - throw new IllegalArgumentException("로또 번호는 1~45 사이여야 합니다."); - } - - return new ArrayList<>(uniqueNumbers); + return Integer.parseInt(scanner.nextLine().trim()); } } diff --git a/src/main/java/view/ResultView.java b/src/main/java/view/ResultView.java index 68d1dddf..4f428d5c 100644 --- a/src/main/java/view/ResultView.java +++ b/src/main/java/view/ResultView.java @@ -5,6 +5,30 @@ public class ResultView { + public static void printInvalidAmountMessage() { + System.out.println("올바른 금액을 입력해 주세요! (1000원 단위로 입력)"); + } + + public static void printInvalidManualTicketMessage() { + System.out.println("수동 구매 개수가 전체 구매 개수를 초과할 수 없습니다."); + } + + public static void printInvalidManualCountMessage() { + System.out.println("올바른 개수를 입력하세요! (0 이상의 숫자)"); + } + + public static void printInvalidLottoNumbersMessage() { + System.out.println("1~45 사이의 중복되지 않은 6개의 숫자를 입력하세요."); + } + + public static void printInvalidWinningNumbersMessage() { + System.out.println("1~45 사이의 중복되지 않은 6개의 당첨 번호를 입력하세요."); + } + + public static void printInvalidBonusNumberMessage() { + System.out.println("1~45 사이의 보너스 번호를 입력하세요."); + } + public static void printOrderTickets(int manualCount, int autoCount) { System.out.printf("수동으로 %d장, 자동으로 %d개를 구매했습니다.\n", manualCount, autoCount); } @@ -22,7 +46,12 @@ public static void printWinningStatistics(Map results, double p } } + String profitStatus = "손해"; + if (profitRate >= 1) { + profitStatus = "이득"; + } + System.out.printf("총 수익률은 %.2f입니다. (기준이 1이기 때문에 결과적으로 %s라는 의미임)\n", - profitRate, profitRate >= 1 ? "이득" : "손해"); + profitRate, profitStatus); } } From b40189e497c00791bd1fc82738ef3b2feb49e9a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A4=80=EC=84=9D=28YunJunSeok=29?= Date: Tue, 4 Mar 2025 12:56:14 +0900 Subject: [PATCH 9/9] =?UTF-8?q?Fix:=20WinningRank=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/config/WinningRank.java | 3 +-- src/main/java/model/LottoResultChecker.java | 20 +++++--------------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/main/java/config/WinningRank.java b/src/main/java/config/WinningRank.java index 63630b0e..e5b1a4ac 100644 --- a/src/main/java/config/WinningRank.java +++ b/src/main/java/config/WinningRank.java @@ -8,8 +8,7 @@ public enum WinningRank { MATCH_4(4, 50000, "4개 일치 (50000원)"), MATCH_5(5, 1500000, "5개 일치 (1500000원)"), MATCH_5_BONUS(5, 30000000, "5개 일치, 보너스 볼 일치(30000000원)"), - MATCH_6(6, 2000000000, "6개 일치 (2000000000원)"), - NO_MATCH(0, 0, "꽝"); + MATCH_6(6, 2000000000, "6개 일치 (2000000000원)"); private final int matchCount; private final int prize; diff --git a/src/main/java/model/LottoResultChecker.java b/src/main/java/model/LottoResultChecker.java index aed44663..c5525dab 100644 --- a/src/main/java/model/LottoResultChecker.java +++ b/src/main/java/model/LottoResultChecker.java @@ -11,9 +11,7 @@ public static Map checkWinningResults(List purchasedLott Set winningSet = new HashSet<>(winningNumbers); for (Lotto lotto : purchasedLottos) { - int matchCount = getMatchCount(lotto, winningSet); - boolean hasBonus = hasBonusMatch(lotto, bonusNumber); - totalPrize += updateResults(result, matchCount, hasBonus); + totalPrize += updateResults(result, lotto, winningSet, bonusNumber); } result.put("totalPrize", totalPrize); @@ -23,22 +21,15 @@ public static Map checkWinningResults(List purchasedLott private static Map initializeResultMap() { Map result = new LinkedHashMap<>(); for (WinningRank rank : WinningRank.values()) { - if (rank != WinningRank.NO_MATCH) { - result.put(rank.getDescription(), 0); // 🛠️ 당첨 개수 0으로 초기화 - } + result.put(rank.getDescription(), 0); } return result; } - private static int getMatchCount(Lotto lotto, Set winningSet) { - return (int) lotto.getNumbers().stream().filter(winningSet::contains).count(); - } - - private static boolean hasBonusMatch(Lotto lotto, int bonusNumber) { - return lotto.getNumbers().contains(bonusNumber); - } + private static int updateResults(Map result, Lotto lotto, Set winningSet, int bonusNumber) { + int matchCount = (int) lotto.getNumbers().stream().filter(winningSet::contains).count(); + boolean hasBonus = lotto.getNumbers().contains(bonusNumber); - private static int updateResults(Map result, int matchCount, boolean hasBonus) { Optional rank = WinningRank.findByMatchCount(matchCount, hasBonus); if (rank.isEmpty()) { return 0; @@ -46,7 +37,6 @@ private static int updateResults(Map result, int matchCount, bo WinningRank winningRank = rank.get(); String key = winningRank.getDescription(); - result.put(key, result.getOrDefault(key, 0) + 1); return winningRank.getPrize();