From 061538e7c156d91407b33dbf17a9b8058de73e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9D=B4=EB=A6=84?= Date: Fri, 20 Feb 2026 02:17:14 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EA=B7=9C?= =?UTF-8?q?=EC=B9=99/=EC=97=90=EB=9F=AC=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EC=83=81=EC=88=98=20=EC=A0=95=EC=9D=98=20=EB=B0=8F=20Lotto=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/Lotto.java | 20 ------------ .../java/lotto/constants/ErrorMessage.java | 18 +++++++++++ src/main/java/lotto/constants/LottoRule.java | 11 +++++++ src/main/java/lotto/domain/Lotto.java | 31 +++++++++++++++++++ src/test/java/lotto/LottoTest.java | 1 + 5 files changed, 61 insertions(+), 20 deletions(-) delete mode 100644 src/main/java/lotto/Lotto.java create mode 100644 src/main/java/lotto/constants/ErrorMessage.java create mode 100644 src/main/java/lotto/constants/LottoRule.java create mode 100644 src/main/java/lotto/domain/Lotto.java 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/constants/ErrorMessage.java b/src/main/java/lotto/constants/ErrorMessage.java new file mode 100644 index 0000000000..8921c3f3d9 --- /dev/null +++ b/src/main/java/lotto/constants/ErrorMessage.java @@ -0,0 +1,18 @@ +package lotto.constants; + +public enum ErrorMessage { + INVALID_SIZE("로또 번호는 " + LottoRule.LOTTO_SIZE + "개여야 합니다."), + DUPLICATE_NUMBER("로또 번호는 중복될 수 없습니다."), + INVALID_RANGE("로또 번호는 " + LottoRule.MIN_NUMBER + "부터 " + LottoRule.MAX_NUMBER + " 사이여야 합니다."); + + private static final String PREFIX = "[ERROR] "; + private final String message; + + ErrorMessage(String message) { + this.message = message; + } + + public String getMessage() { + return PREFIX + message; + } +} \ No newline at end of file diff --git a/src/main/java/lotto/constants/LottoRule.java b/src/main/java/lotto/constants/LottoRule.java new file mode 100644 index 0000000000..a9af0b5a46 --- /dev/null +++ b/src/main/java/lotto/constants/LottoRule.java @@ -0,0 +1,11 @@ +package lotto.constants; + +public class LottoRule { + public static final int MIN_NUMBER = 1; + public static final int MAX_NUMBER = 45; + public static final int LOTTO_SIZE = 6; + public static final int TICKET_PRICE = 1000; + + private LottoRule() { + } +} \ No newline at end of file diff --git a/src/main/java/lotto/domain/Lotto.java b/src/main/java/lotto/domain/Lotto.java new file mode 100644 index 0000000000..22d2d19c0e --- /dev/null +++ b/src/main/java/lotto/domain/Lotto.java @@ -0,0 +1,31 @@ +package lotto.domain; + +import lotto.constants.ErrorMessage; +import lotto.constants.LottoRule; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class Lotto { + private final List numbers; + + public Lotto(List numbers) { + validateSize(numbers); + validateDuplicate(numbers); + this.numbers = numbers; + } + + private void validateSize(List numbers) { + if (numbers.size() != LottoRule.LOTTO_SIZE) { + throw new IllegalArgumentException(ErrorMessage.INVALID_SIZE.getMessage()); + } + } + + private void validateDuplicate(List numbers) { + Set uniqueNumbers = new HashSet<>(numbers); + if (uniqueNumbers.size() != numbers.size()) { + throw new IllegalArgumentException(ErrorMessage.DUPLICATE_NUMBER.getMessage()); + } + } +} diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 309f4e50ae..c74fb4b676 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; From 9d0238c0fe503ea9d19ea98113428e818b4d498a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9D=B4=EB=A6=84?= Date: Fri, 20 Feb 2026 11:19:46 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=EA=B5=AC=EC=9E=85=20=EA=B8=88?= =?UTF-8?q?=EC=95=A1=20=EA=B2=80=EC=A6=9D=20=EB=B0=8F=20=EB=A1=9C=EB=98=90?= =?UTF-8?q?=20=EC=9E=90=EB=8F=99=20=EB=B0=9C=ED=96=89=EA=B8=B0(LottoMachin?= =?UTF-8?q?e)=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/lotto/constants/ErrorMessage.java | 3 +- src/main/java/lotto/domain/LottoMachine.java | 45 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/main/java/lotto/domain/LottoMachine.java diff --git a/src/main/java/lotto/constants/ErrorMessage.java b/src/main/java/lotto/constants/ErrorMessage.java index 8921c3f3d9..dce0e61d34 100644 --- a/src/main/java/lotto/constants/ErrorMessage.java +++ b/src/main/java/lotto/constants/ErrorMessage.java @@ -3,7 +3,8 @@ public enum ErrorMessage { INVALID_SIZE("로또 번호는 " + LottoRule.LOTTO_SIZE + "개여야 합니다."), DUPLICATE_NUMBER("로또 번호는 중복될 수 없습니다."), - INVALID_RANGE("로또 번호는 " + LottoRule.MIN_NUMBER + "부터 " + LottoRule.MAX_NUMBER + " 사이여야 합니다."); + INVALID_RANGE("로또 번호는 " + LottoRule.MIN_NUMBER + "부터 " + LottoRule.MAX_NUMBER + " 사이여야 합니다."), + INVALID_MONEY("로또 구입 금액은 " + LottoRule.TICKET_PRICE + "원 단위여야 합니다."); private static final String PREFIX = "[ERROR] "; private final String message; diff --git a/src/main/java/lotto/domain/LottoMachine.java b/src/main/java/lotto/domain/LottoMachine.java new file mode 100644 index 0000000000..3d9606134b --- /dev/null +++ b/src/main/java/lotto/domain/LottoMachine.java @@ -0,0 +1,45 @@ +package lotto.domain; + +import camp.nextstep.edu.missionutils.Randoms; +import lotto.constants.ErrorMessage; +import lotto.constants.LottoRule; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class LottoMachine { + + public List buyLottos(int money) { + validateMoney(money); + int count = money / LottoRule.TICKET_PRICE; + return generateLottos(count); + } + + private void validateMoney(int money) { + if (money <= 0 || money % LottoRule.TICKET_PRICE != 0) { + throw new IllegalArgumentException(ErrorMessage.INVALID_MONEY.getMessage()); + } + } + + private List generateLottos(int count) { + List lottos = new ArrayList<>(); + for (int i = 0; i < count; i++) { + lottos.add(generateSingleLotto()); + } + return lottos; + } + + private Lotto generateSingleLotto() { + List numbers = Randoms.pickUniqueNumbersInRange( + LottoRule.MIN_NUMBER, + LottoRule.MAX_NUMBER, + LottoRule.LOTTO_SIZE + ); + + List sortedNumbers = new ArrayList<>(numbers); + Collections.sort(sortedNumbers); + + return new Lotto(sortedNumbers); + } +} \ No newline at end of file From 018f68526ed0843c3b71074b5471e0ff669ad0d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9D=B4=EB=A6=84?= Date: Fri, 20 Feb 2026 16:18:09 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=20=EB=93=B1?= =?UTF-8?q?=EA=B8=89(Rank)=20=EB=B0=8F=20=EB=8B=B9=EC=B2=A8=20=EB=A1=9C?= =?UTF-8?q?=EB=98=90(WinningLotto)=20=EB=8F=84=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/lotto/constants/ErrorMessage.java | 5 ++- src/main/java/lotto/constants/LottoRule.java | 2 +- src/main/java/lotto/domain/Lotto.java | 11 +++++ src/main/java/lotto/domain/LottoMachine.java | 2 +- src/main/java/lotto/domain/Rank.java | 45 +++++++++++++++++++ src/main/java/lotto/domain/WinningLotto.java | 31 +++++++++++++ 6 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 src/main/java/lotto/domain/Rank.java create mode 100644 src/main/java/lotto/domain/WinningLotto.java diff --git a/src/main/java/lotto/constants/ErrorMessage.java b/src/main/java/lotto/constants/ErrorMessage.java index dce0e61d34..56e012a3af 100644 --- a/src/main/java/lotto/constants/ErrorMessage.java +++ b/src/main/java/lotto/constants/ErrorMessage.java @@ -4,7 +4,8 @@ public enum ErrorMessage { INVALID_SIZE("로또 번호는 " + LottoRule.LOTTO_SIZE + "개여야 합니다."), DUPLICATE_NUMBER("로또 번호는 중복될 수 없습니다."), INVALID_RANGE("로또 번호는 " + LottoRule.MIN_NUMBER + "부터 " + LottoRule.MAX_NUMBER + " 사이여야 합니다."), - INVALID_MONEY("로또 구입 금액은 " + LottoRule.TICKET_PRICE + "원 단위여야 합니다."); + INVALID_MONEY("로또 구입 금액은 " + LottoRule.TICKET_PRICE + "원 단위여야 합니다."), + DUPLICATE_BONUS_NUMBER("보너스 번호는 당첨 번호와 중복될 수 없습니다."); private static final String PREFIX = "[ERROR] "; private final String message; @@ -16,4 +17,4 @@ public enum ErrorMessage { public String getMessage() { return PREFIX + message; } -} \ No newline at end of file +} diff --git a/src/main/java/lotto/constants/LottoRule.java b/src/main/java/lotto/constants/LottoRule.java index a9af0b5a46..efc2573d06 100644 --- a/src/main/java/lotto/constants/LottoRule.java +++ b/src/main/java/lotto/constants/LottoRule.java @@ -8,4 +8,4 @@ public class LottoRule { private LottoRule() { } -} \ No newline at end of file +} diff --git a/src/main/java/lotto/domain/Lotto.java b/src/main/java/lotto/domain/Lotto.java index 22d2d19c0e..9fd481b946 100644 --- a/src/main/java/lotto/domain/Lotto.java +++ b/src/main/java/lotto/domain/Lotto.java @@ -28,4 +28,15 @@ private void validateDuplicate(List numbers) { throw new IllegalArgumentException(ErrorMessage.DUPLICATE_NUMBER.getMessage()); } } + + public boolean contains(int number) { + return numbers.contains(number); + } + + public int countMatchingNumbers(Lotto otherLotto) { + return (int) numbers.stream() + .filter(otherLotto::contains) + .count(); + } } + diff --git a/src/main/java/lotto/domain/LottoMachine.java b/src/main/java/lotto/domain/LottoMachine.java index 3d9606134b..adaa452c5d 100644 --- a/src/main/java/lotto/domain/LottoMachine.java +++ b/src/main/java/lotto/domain/LottoMachine.java @@ -42,4 +42,4 @@ private Lotto generateSingleLotto() { return new Lotto(sortedNumbers); } -} \ No newline at end of file +} diff --git a/src/main/java/lotto/domain/Rank.java b/src/main/java/lotto/domain/Rank.java new file mode 100644 index 0000000000..61e022da42 --- /dev/null +++ b/src/main/java/lotto/domain/Rank.java @@ -0,0 +1,45 @@ +package lotto.domain; + +public enum Rank { + FIRST(6, 2_000_000_000), + SECOND(5, 30_000_000), + THIRD(5, 1_500_000), + FOURTH(4, 50_000), + FIFTH(3, 5_000), + NONE(0, 0); + + private final int matchCount; + private final int prizeMoney; + + Rank(int matchCount, int prizeMoney) { + this.matchCount = matchCount; + this.prizeMoney = prizeMoney; + } + + public static Rank valueOf(int matchCount, boolean matchBonus) { + if (matchCount == 6) { + return FIRST; + } + if (matchCount == 5 && matchBonus) { + return SECOND; + } + if (matchCount == 5 && !matchBonus) { + return THIRD; + } + if (matchCount == 4) { + return FOURTH; + } + if (matchCount == 3) { + return FIFTH; + } + return NONE; + } + + public int getMatchCount() { + return matchCount; + } + + public int getPrizeMoney() { + return prizeMoney; + } +} diff --git a/src/main/java/lotto/domain/WinningLotto.java b/src/main/java/lotto/domain/WinningLotto.java new file mode 100644 index 0000000000..5cb23857e5 --- /dev/null +++ b/src/main/java/lotto/domain/WinningLotto.java @@ -0,0 +1,31 @@ +package lotto.domain; + +import lotto.constants.ErrorMessage; +import lotto.constants.LottoRule; + +public class WinningLotto { + private final Lotto winningLotto; + private final int bonusNumber; + + public WinningLotto(Lotto winningLotto, int bonusNumber) { + validateBonusNumber(winningLotto, bonusNumber); + this.winningLotto = winningLotto; + this.bonusNumber = bonusNumber; + } + + private void validateBonusNumber(Lotto winningLotto, int bonusNumber) { + if (bonusNumber < LottoRule.MIN_NUMBER || bonusNumber > LottoRule.MAX_NUMBER) { + throw new IllegalArgumentException(ErrorMessage.INVALID_RANGE.getMessage()); + } + if (winningLotto.contains(bonusNumber)) { + throw new IllegalArgumentException(ErrorMessage.DUPLICATE_BONUS_NUMBER.getMessage()); + } + } + + public Rank match(Lotto userLotto) { + int matchCount = userLotto.countMatchingNumbers(winningLotto); + boolean matchBonus = userLotto.contains(bonusNumber); + + return Rank.valueOf(matchCount, matchBonus); + } +} From 9c1169390df274fdaa53741de9bc31011ea1275c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9D=B4=EB=A6=84?= Date: Fri, 20 Feb 2026 21:44:53 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=EB=A5=BC=20=EB=B9=84=EA=B5=90=ED=95=98?= =?UTF-8?q?=EA=B3=A0=20=EB=8B=B9=EC=B2=A8=20=ED=86=B5=EA=B3=84/=EC=88=98?= =?UTF-8?q?=EC=9D=B5=EB=A5=A0=EC=9D=84=20=EB=82=B4=EB=8A=94=20LottoResult?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/domain/LottoResult.java | 46 +++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/main/java/lotto/domain/LottoResult.java diff --git a/src/main/java/lotto/domain/LottoResult.java b/src/main/java/lotto/domain/LottoResult.java new file mode 100644 index 0000000000..f960ca35b4 --- /dev/null +++ b/src/main/java/lotto/domain/LottoResult.java @@ -0,0 +1,46 @@ +package lotto.domain; + +import java.util.Collections; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +public class LottoResult { + private final Map result; + + public LottoResult() { + this.result = new EnumMap<>(Rank.class); + for (Rank rank : Rank.values()) { + result.put(rank, 0); + } + } + + public void compareLottos(List userLottos, WinningLotto winningLotto) { + for (Lotto lotto : userLottos) { + Rank rank = winningLotto.match(lotto); + result.put(rank, result.get(rank) + 1); + } + } + + private long calculateTotalPrize() { + long totalPrize = 0; + for (Map.Entry entry : result.entrySet()) { + totalPrize += (long) entry.getKey().getPrizeMoney() * entry.getValue(); + } + return totalPrize; + } + + public double calculateYield(int purchaseAmount) { + if (purchaseAmount == 0) { + return 0.0; + } + long totalPrize = calculateTotalPrize(); + double yield = ((double) totalPrize / purchaseAmount) * 100; + + return Math.round(yield * 10.0) / 10.0; + } + + public Map getResult() { + return Collections.unmodifiableMap(result); + } +} \ No newline at end of file From 918a858f5f5f924d6085f5c802bf3069f8532ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9D=B4=EB=A6=84?= Date: Fri, 20 Feb 2026 22:20:51 +0900 Subject: [PATCH 5/8] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EA=B0=92=EC=9D=84=20=EB=B3=80=ED=99=98?= =?UTF-8?q?=ED=95=98=EA=B3=A0=20=ED=8F=AC=EB=A7=B7=EC=9D=84=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=ED=95=98=EB=8A=94=20Parser=20=EB=B0=8F=20Validator=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/lotto/constants/ErrorMessage.java | 4 ++- src/main/java/lotto/domain/LottoResult.java | 2 +- src/main/java/lotto/util/InputValidator.java | 21 ++++++++++++ src/main/java/lotto/util/Parser.java | 34 +++++++++++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 src/main/java/lotto/util/InputValidator.java create mode 100644 src/main/java/lotto/util/Parser.java diff --git a/src/main/java/lotto/constants/ErrorMessage.java b/src/main/java/lotto/constants/ErrorMessage.java index 56e012a3af..dc19833459 100644 --- a/src/main/java/lotto/constants/ErrorMessage.java +++ b/src/main/java/lotto/constants/ErrorMessage.java @@ -5,7 +5,9 @@ public enum ErrorMessage { DUPLICATE_NUMBER("로또 번호는 중복될 수 없습니다."), INVALID_RANGE("로또 번호는 " + LottoRule.MIN_NUMBER + "부터 " + LottoRule.MAX_NUMBER + " 사이여야 합니다."), INVALID_MONEY("로또 구입 금액은 " + LottoRule.TICKET_PRICE + "원 단위여야 합니다."), - DUPLICATE_BONUS_NUMBER("보너스 번호는 당첨 번호와 중복될 수 없습니다."); + DUPLICATE_BONUS_NUMBER("보너스 번호는 당첨 번호와 중복될 수 없습니다."), + EMPTY_INPUT("입력값이 비어있습니다."), + NOT_NUMERIC("숫자만 입력해 주세요."); private static final String PREFIX = "[ERROR] "; private final String message; diff --git a/src/main/java/lotto/domain/LottoResult.java b/src/main/java/lotto/domain/LottoResult.java index f960ca35b4..56503b7e9a 100644 --- a/src/main/java/lotto/domain/LottoResult.java +++ b/src/main/java/lotto/domain/LottoResult.java @@ -43,4 +43,4 @@ public double calculateYield(int purchaseAmount) { public Map getResult() { return Collections.unmodifiableMap(result); } -} \ No newline at end of file +} diff --git a/src/main/java/lotto/util/InputValidator.java b/src/main/java/lotto/util/InputValidator.java new file mode 100644 index 0000000000..02139e4f74 --- /dev/null +++ b/src/main/java/lotto/util/InputValidator.java @@ -0,0 +1,21 @@ +package lotto.util; + +import lotto.constants.ErrorMessage; + +public class InputValidator { + + private InputValidator() { + } + + public static void validateEmpty(String input) { + if (input == null || input.trim().isEmpty()) { + throw new IllegalArgumentException(ErrorMessage.EMPTY_INPUT.getMessage()); + } + } + + public static void validateNumeric(String input) { + if (!input.matches("^[0-9]+$")) { + throw new IllegalArgumentException(ErrorMessage.NOT_NUMERIC.getMessage()); + } + } +} diff --git a/src/main/java/lotto/util/Parser.java b/src/main/java/lotto/util/Parser.java new file mode 100644 index 0000000000..aac41fc178 --- /dev/null +++ b/src/main/java/lotto/util/Parser.java @@ -0,0 +1,34 @@ +package lotto.util; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class Parser { + private static final String DELIMITER = ","; + + private Parser() { + } + + public static int parsePurchaseAmount(String input) { + return parseToInt(input); + } + + public static List parseWinningNumbers(String input) { + InputValidator.validateEmpty(input); + return Arrays.stream(input.split(DELIMITER)) + .map(String::trim) + .map(Parser::parseToInt) // 내부 비공개 메서드 재사용 + .collect(Collectors.toList()); + } + + public static int parseBonusNumber(String input) { + return parseToInt(input); + } + + private static int parseToInt(String input) { + InputValidator.validateEmpty(input); + InputValidator.validateNumeric(input); + return Integer.parseInt(input); + } +} From a478f1e07da39c0410dd900c99da4a3b72a5fcfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9D=B4=EB=A6=84?= Date: Fri, 20 Feb 2026 22:46:29 +0900 Subject: [PATCH 6/8] =?UTF-8?q?feat:=20UI=20=EC=95=88=EB=82=B4=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=83=81=EC=88=98=ED=99=94=20=EB=B0=8F=20?= =?UTF-8?q?InputView,=20OutputView=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/lotto/constants/InputMessage.java | 17 +++++++ .../java/lotto/constants/OutputMessage.java | 19 ++++++++ src/main/java/lotto/domain/Lotto.java | 5 +- src/main/java/lotto/view/InputView.java | 27 +++++++++++ src/main/java/lotto/view/OutputView.java | 48 +++++++++++++++++++ 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 src/main/java/lotto/constants/InputMessage.java create mode 100644 src/main/java/lotto/constants/OutputMessage.java create mode 100644 src/main/java/lotto/view/InputView.java create mode 100644 src/main/java/lotto/view/OutputView.java diff --git a/src/main/java/lotto/constants/InputMessage.java b/src/main/java/lotto/constants/InputMessage.java new file mode 100644 index 0000000000..9ee2b47800 --- /dev/null +++ b/src/main/java/lotto/constants/InputMessage.java @@ -0,0 +1,17 @@ +package lotto.constants; + +public enum InputMessage { + REQUEST_PURCHASE_AMOUNT("구입금액을 입력해 주세요."), + REQUEST_WINNING_NUMBERS("\n당첨 번호를 입력해 주세요."), + REQUEST_BONUS_NUMBER("\n보너스 번호를 입력해 주세요."); + + private final String message; + + InputMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/lotto/constants/OutputMessage.java b/src/main/java/lotto/constants/OutputMessage.java new file mode 100644 index 0000000000..5d11923b7e --- /dev/null +++ b/src/main/java/lotto/constants/OutputMessage.java @@ -0,0 +1,19 @@ +package lotto.constants; + +public enum OutputMessage { + PURCHASE_COUNT_MESSAGE("\n%d개를 구매했습니다.\n"), + WINNING_STATISTICS_HEADER("\n당첨 통계\n---"), + YIELD_MESSAGE("총 수익률은 %.1f%%입니다.\n"), + NORMAL_RANK_FORMAT("%d개 일치 (%,d원) - %d개\n"), + SECOND_RANK_FORMAT("%d개 일치, 보너스 볼 일치 (%,d원) - %d개\n"); + + private final String message; + + OutputMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/lotto/domain/Lotto.java b/src/main/java/lotto/domain/Lotto.java index 9fd481b946..f58cabe97c 100644 --- a/src/main/java/lotto/domain/Lotto.java +++ b/src/main/java/lotto/domain/Lotto.java @@ -16,6 +16,10 @@ public Lotto(List numbers) { this.numbers = numbers; } + public List getNumbers() { + return numbers; + } + private void validateSize(List numbers) { if (numbers.size() != LottoRule.LOTTO_SIZE) { throw new IllegalArgumentException(ErrorMessage.INVALID_SIZE.getMessage()); @@ -39,4 +43,3 @@ public int countMatchingNumbers(Lotto otherLotto) { .count(); } } - diff --git a/src/main/java/lotto/view/InputView.java b/src/main/java/lotto/view/InputView.java new file mode 100644 index 0000000000..39efb67696 --- /dev/null +++ b/src/main/java/lotto/view/InputView.java @@ -0,0 +1,27 @@ +package lotto.view; + +import camp.nextstep.edu.missionutils.Console; +import lotto.constants.InputMessage; +import lotto.util.Parser; +import java.util.List; + +public class InputView { + + public int readPurchaseAmount() { + System.out.println(InputMessage.REQUEST_PURCHASE_AMOUNT.getMessage()); + String input = Console.readLine(); + return Parser.parsePurchaseAmount(input); + } + + public List readWinningNumbers() { + System.out.println(InputMessage.REQUEST_WINNING_NUMBERS.getMessage()); + String input = Console.readLine(); + return Parser.parseWinningNumbers(input); + } + + public int readBonusNumber() { + System.out.println(InputMessage.REQUEST_BONUS_NUMBER.getMessage()); + String input = Console.readLine(); + return Parser.parseBonusNumber(input); + } +} diff --git a/src/main/java/lotto/view/OutputView.java b/src/main/java/lotto/view/OutputView.java new file mode 100644 index 0000000000..99ad8eeea2 --- /dev/null +++ b/src/main/java/lotto/view/OutputView.java @@ -0,0 +1,48 @@ +package lotto.view; + +import lotto.constants.OutputMessage; +import lotto.domain.Lotto; +import lotto.domain.LottoResult; +import lotto.domain.Rank; + +import java.util.List; +import java.util.Map; + +public class OutputView { + + public void printPurchasedLottos(List lottos) { + System.out.printf(OutputMessage.PURCHASE_COUNT_MESSAGE.getMessage(), lottos.size()); + for (Lotto lotto : lottos) { + System.out.println(lotto.getNumbers()); + } + } + + public void printWinningStatistics(LottoResult lottoResult) { + System.out.println(OutputMessage.WINNING_STATISTICS_HEADER.getMessage()); + Map result = lottoResult.getResult(); + + printRankCondition(Rank.FIFTH, result.getOrDefault(Rank.FIFTH, 0)); + printRankCondition(Rank.FOURTH, result.getOrDefault(Rank.FOURTH, 0)); + printRankCondition(Rank.THIRD, result.getOrDefault(Rank.THIRD, 0)); + printRankCondition(Rank.SECOND, result.getOrDefault(Rank.SECOND, 0)); + printRankCondition(Rank.FIRST, result.getOrDefault(Rank.FIRST, 0)); + } + + private void printRankCondition(Rank rank, int count) { + if (rank == Rank.SECOND) { + System.out.printf(OutputMessage.SECOND_RANK_FORMAT.getMessage(), + rank.getMatchCount(), rank.getPrizeMoney(), count); + return; + } + System.out.printf(OutputMessage.NORMAL_RANK_FORMAT.getMessage(), + rank.getMatchCount(), rank.getPrizeMoney(), count); + } + + public void printTotalYield(double yield) { + System.out.printf(OutputMessage.YIELD_MESSAGE.getMessage(), yield); + } + + public void printErrorMessage(Exception e) { + System.out.println("[ERROR] " + e.getMessage()); + } +} From c89a46bf99a41c47b6ddaf8a59cd81ec4d19bf6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9D=B4=EB=A6=84?= Date: Fri, 20 Feb 2026 22:55:13 +0900 Subject: [PATCH 7/8] =?UTF-8?q?feat:=20AppConfig=EB=A5=BC=20=ED=86=B5?= =?UTF-8?q?=ED=95=9C=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A3=BC=EC=9E=85(DI?= =?UTF-8?q?)=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20Application=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/Application.java | 9 +++- src/main/java/lotto/config/AppConfig.java | 25 ++++++++++ .../lotto/controller/LottoController.java | 46 +++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/main/java/lotto/config/AppConfig.java create mode 100644 src/main/java/lotto/controller/LottoController.java diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922ba4..778bab9ccf 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,14 @@ package lotto; +import lotto.config.AppConfig; +import lotto.controller.LottoController; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + + AppConfig appConfig = new AppConfig(); + LottoController controller = appConfig.lottoController(); + + controller.run(); } } diff --git a/src/main/java/lotto/config/AppConfig.java b/src/main/java/lotto/config/AppConfig.java new file mode 100644 index 0000000000..b1e68c8cf3 --- /dev/null +++ b/src/main/java/lotto/config/AppConfig.java @@ -0,0 +1,25 @@ +package lotto.config; + +import lotto.controller.LottoController; +import lotto.domain.LottoMachine; +import lotto.view.InputView; +import lotto.view.OutputView; + +public class AppConfig { + + public LottoController lottoController() { + return new LottoController(inputView(), outputView(), lottoMachine()); + } + + private InputView inputView() { + return new InputView(); + } + + private OutputView outputView() { + return new OutputView(); + } + + private LottoMachine lottoMachine() { + return new LottoMachine(); + } +} diff --git a/src/main/java/lotto/controller/LottoController.java b/src/main/java/lotto/controller/LottoController.java new file mode 100644 index 0000000000..42c313506a --- /dev/null +++ b/src/main/java/lotto/controller/LottoController.java @@ -0,0 +1,46 @@ +package lotto.controller; + +import lotto.domain.Lotto; +import lotto.domain.LottoMachine; +import lotto.domain.LottoResult; +import lotto.domain.WinningLotto; +import lotto.view.InputView; +import lotto.view.OutputView; + +import java.util.List; + +public class LottoController { + private final InputView inputView; + private final OutputView outputView; + private final LottoMachine lottoMachine; // 의존성 주입받을 도메인 + + public LottoController(InputView inputView, OutputView outputView, LottoMachine lottoMachine) { + this.inputView = inputView; + this.outputView = outputView; + this.lottoMachine = lottoMachine; + } + + public void run() { + try { + int purchaseAmount = inputView.readPurchaseAmount(); + List purchasedLottos = lottoMachine.buyLottos(purchaseAmount); + outputView.printPurchasedLottos(purchasedLottos); + + List winningNumbers = inputView.readWinningNumbers(); + Lotto winningLottoNumbers = new Lotto(winningNumbers); + + int bonusNumber = inputView.readBonusNumber(); + WinningLotto winningLotto = new WinningLotto(winningLottoNumbers, bonusNumber); + + LottoResult lottoResult = new LottoResult(); + lottoResult.compareLottos(purchasedLottos, winningLotto); + + outputView.printWinningStatistics(lottoResult); + double yield = lottoResult.calculateYield(purchaseAmount); + outputView.printTotalYield(yield); + + } catch (IllegalArgumentException e) { + outputView.printErrorMessage(e); + } + } +} From 8612c9b9a2ef64a625ab675a7f789dae50c936d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9D=B4=EB=A6=84?= Date: Fri, 20 Feb 2026 23:13:43 +0900 Subject: [PATCH 8/8] =?UTF-8?q?refactor:=20=EC=97=90=EB=9F=AC=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=A4=91=EB=B3=B5=20=EC=B6=9C=EB=A0=A5=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/lotto/view/OutputView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/lotto/view/OutputView.java b/src/main/java/lotto/view/OutputView.java index 99ad8eeea2..daa9bf6ab7 100644 --- a/src/main/java/lotto/view/OutputView.java +++ b/src/main/java/lotto/view/OutputView.java @@ -43,6 +43,6 @@ public void printTotalYield(double yield) { } public void printErrorMessage(Exception e) { - System.out.println("[ERROR] " + e.getMessage()); + System.out.println(e.getMessage()); } }