diff --git a/docs/README.md b/docs/README.md index e69de29bb2d..3e082c5bb61 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,71 @@ +# ๐Ÿ“์„ค๊ณ„ ๊ตฌ์กฐ +- Application : ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰์„ ๊ด€๋ฆฌํ•œ๋‹ค. +- MainController : ๋ฐ์ดํ„ฐ ์ „๋‹ฌ ๋ฐ ์ค‘๊ณ„ ์—ญํ• ์„ ํ•œ๋‹ค. +- view + - InputView : ์ž…๋ ฅ๊ณผ ๊ด€๋ จ๋œ ์ฑ…์ž„ ๊ด€๋ฆฌํ•œ๋‹ค. + - OutputView : ์ถœ๋ ฅ๊ณผ ๊ด€๋ จ๋œ ์ฑ…์ž„ ๊ด€๋ฆฌํ•œ๋‹ค. +- message(๊ฐ ๊ฐ์ฒด๋ฅผ enum์œผ๋กœ ๊ด€๋ฆฌ) + - ErrorMessage : ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. + - ViewMessage : ์ถœ๋ ฅ ๋ฉ”์‹œ์ง€๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. +- domain + - Lotto : List๋ฅผ ๋ฉค๋ฒ„๋ณ€์ˆ˜๋กœ ๊ฐ–๋Š”๋‹ค. ์ˆซ์ž๋ฅผ ๊ด€๋ฆฌํ•  ์ผ๊ธ‰๊ฐ์ฒด + - Lottos : Lotto๊ฐ์ฒด์˜ List๋ฅผ ๊ด€๋ฆฌํ•  ์ผ๊ธ‰์ปฌ๋ ‰์…˜ + - User : winningLotto , bounusNumber, lottoBudget, ๋ฉค๋ฒ„๋ณ€์ˆ˜๋ฅผ๊ฐ–๋Š”๋‹ค. + - User์˜ ๋ฉค๋ฒ„๋ณ€์ˆ˜๋Š” ์›์‹œ๊ฐ’์œผ๋กœ ํฌ์žฅํ•œ๋‹ค +- Validator ํด๋ž˜์Šค + - ๊ณตํ†ต ๊ฒ€์ฆ๋งค์„œ๋“œ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค + + +# ๐Ÿ“ ๊ตฌํ˜„ ๊ธฐ๋Šฅ ๋ชฉ๋ก +### ๊ฒŒ์ž„ ์ดˆ๊ธฐํ™” + +- [x] ๊ตฌ์ž…ํ•  ๊ธˆ์•ก ์ž…๋ ฅ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : ๋นˆ ๋ฌธ์ž์—ด ์ž…๋ ฅ ๊ฒ€์ฆ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : ์ˆซ์ž์™ธ ๋ฌธ์ž ์ž…๋ ฅ ๊ฒ€์ฆ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : ์Œ์ˆ˜ ์ž…๋ ฅ ๊ฒ€์ฆ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : 1000๋‹จ์œ„๋กœ ์•ˆ๋–จ์–ด์ง€๋Š” ๊ฒฝ์šฐ ๊ฒ€์ฆ +- [x] ๋กœ๋˜ ๊ตฌ์ž… ๊ธฐ๋Šฅ + - pickUniqueNumbersInRange() ๋งค์„œ๋“œ ์‚ฌ์šฉ +- [x] ๋‹น์ฒจ๋ฒˆํ˜ธ ์ž…๋ ฅ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : ๋นˆ ๋ฌธ์ž์—ด ์ž…๋ ฅ ๊ฒ€์ฆ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : ,๊ฐ€ ์—†์„๋•Œ ๊ฒ€์ฆ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : 1~45 ์‚ฌ์ด๋ฅผ ๋ฒ—์–ด๋‚œ ์ˆซ์ž + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : ๋ฌธ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์„๋•Œ ๊ฒ€์ฆ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : 6์ž๋ฆฌ ๋ฏธ๋งŒ์ด๊ฑฐ๋‚˜ ์ดˆ๊ณผ์ผ๋•Œ ๊ฒ€์ฆ +- [x] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ž…๋ ฅ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : 1~45 ์‚ฌ์ด๋ฅผ ๋ฒ—์–ด๋‚œ ์ˆซ์ž + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : ๋‹น์ฒจ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต ๊ฒ€์ฆ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : ๋นˆ ๋ฌธ์ž์—ด ์ž…๋ ฅ ๊ฒ€์ฆ +

+ +### ๊ฒŒ์ž„ ์ง„ํ–‰ +- [x] ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ์ˆ˜๋Ÿ‰ ๋ฐ ๋ฒˆํ˜ธ(์˜ค๋ฆ„์ฐจ์ˆœ) ์ถœ๋ ฅํ•œ๋‹ค. +- [x] ๋‹น์ฒจ ์ฒดํฌ ๊ธฐ๋Šฅ + +

+ +### ๊ฒŒ์ž„ ์ข…๋ฃŒ +- [x] ๋‹น์ฒจ๋‚ด์—ญ๋ฐ ์ˆ˜์ต๋ฅ  ์ถœ๋ ฅํ›„ ๊ฒŒ์ž„์ข…๋ฃŒ + +

+ +### ํ™•์ธ ๋ชฉ๋ก +- Git์˜ ์ปค๋ฐ‹ ๋‹จ์œ„๋Š” README.md์— ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก ๋‹จ์œ„๋กœ ์ถ”๊ฐ€ +- Java Enum์„ ์ ์šฉ +- ์ž…๋ ฅ๋ฌธ๊ตฌ + - ๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. + - ${๊ฐฏ์ˆ˜}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค. + - ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. + - ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. + - ๋‹น์ฒจ ํ†ต๊ณ„ + - \-\-\- + - 3๊ฐœ ์ผ์น˜ (5,000์›) - 1๊ฐœ + - 4๊ฐœ ์ผ์น˜ (50,000์›) - 0๊ฐœ + - 5๊ฐœ ์ผ์น˜ (1,500,000์›) - 0๊ฐœ + - 5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - 0๊ฐœ + - 6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - 0๊ฐœ + - ์ด ์ˆ˜์ต๋ฅ ์€ 62.5%์ž…๋‹ˆ๋‹ค. +- ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ๊ฐ’์„ ์ž…๋ ฅํ•  ๊ฒฝ์šฐ + - "[ERROR]"๋กœ ์‹œ์ž‘ํ•˜๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅ + - Exception์ด ์•„๋‹Œ IllegalArgumentException, IllegalStateException ๋“ฑ๊ณผ ๊ฐ™์€ ๋ช…ํ™•ํ•œ ์œ ํ˜•์„ ์ฒ˜๋ฆฌํ•œ๋‹ค. + - ๊ทธ ๋ถ€๋ถ„๋ถ€ํ„ฐ ์ž…๋ ฅ์„ ๋‹ค์‹œ ๋ฐ›๋Š”๋‹ค. \ No newline at end of file diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922ba44..21ec324f200 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -2,6 +2,6 @@ public class Application { public static void main(String[] args) { - // TODO: ํ”„๋กœ๊ทธ๋žจ ๊ตฌํ˜„ + MainController.run(); } } diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java deleted file mode 100644 index 519793d1f73..00000000000 --- a/src/main/java/lotto/Lotto.java +++ /dev/null @@ -1,20 +0,0 @@ -package lotto; - -import java.util.List; - -public class Lotto { - private final List numbers; - - public Lotto(List numbers) { - validate(numbers); - this.numbers = numbers; - } - - private void validate(List numbers) { - if (numbers.size() != 6) { - throw new IllegalArgumentException(); - } - } - - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ -} diff --git a/src/main/java/lotto/MainController.java b/src/main/java/lotto/MainController.java new file mode 100644 index 00000000000..27a35c8ac62 --- /dev/null +++ b/src/main/java/lotto/MainController.java @@ -0,0 +1,28 @@ +package lotto; + +import java.util.LinkedHashMap; +import java.util.Map; +import lotto.domain.Budget; +import lotto.domain.Lotto; +import lotto.domain.Lottos; +import lotto.view.InputView; +import lotto.view.OutputView; + +public class MainController { + + public static void run() { + //๊ฒŒ์ž„ ์ดˆ๊ธฐํ™” + Budget budget = InputView.inputBudget(); + Lotto winningLotto = InputView.createWinningLotto(); + int bonusNumber = InputView.createBonusNumber(winningLotto); + //๊ฒŒ์ž„์ง„ํ–‰ + Lottos purchasedLottos = Lotto.buyLottoUsingBudget(budget); + + //GameEnd + Map resultMap = Lottos.compareLottos(purchasedLottos, winningLotto, bonusNumber); + + OutputView.printResult(resultMap); + OutputView.printInvestmentRate(Budget.calculateTotalReturnRate(budget,resultMap)); + ; + } +} diff --git a/src/main/java/lotto/Validator.java b/src/main/java/lotto/Validator.java new file mode 100644 index 00000000000..ec42916cf38 --- /dev/null +++ b/src/main/java/lotto/Validator.java @@ -0,0 +1,56 @@ +package lotto; + +import lotto.domain.Lotto; +import lotto.message.ErrorMessage; + +public class Validator { + public static void validatePositiveNumber(String inputString) { + if (Integer.parseInt(inputString)<=0){ + throw new IllegalArgumentException(ErrorMessage.INPUT_NOT_POSITIVE_NUMBER.getMessage()); + } + } + + public static void validateBlank(String inputString) { + if (inputString == null || inputString.isBlank()) { + throw new IllegalArgumentException(ErrorMessage.INPUT_BLANK.getMessage()); + } + } + + public static void validateType(String inputString) { + try { + Integer.parseInt(inputString); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(ErrorMessage.INPUT_NOT_NUMBER.getMessage()); + } + } + + public static void validateDeliiter(String input) { + input.contains(","); + } + public static Integer parseAndValidateNotNumber(String input) { + try { + int number = Integer.parseInt(input); + validateNumberRange(number); + return number; + } catch (NumberFormatException e) { + throw new IllegalArgumentException(ErrorMessage.INPUT_NOT_NUMBER.getMessage()); + } + } + + public static void validateNumberRange(int number) { + if (number < 1 || number > 45) { + throw new IllegalArgumentException(ErrorMessage.INPUT_NOT_LOTTO_RANGE.getMessage()); + } + } + + public static int parseAndValidateBonusNumber(String input, Lotto winningLotto) { + validateBlank(input); + + int bonusNumber = Validator.parseAndValidateNotNumber(input); + if (winningLotto.getNumbers().contains(bonusNumber)) { + throw new IllegalArgumentException(ErrorMessage.INPUT_DUPLICATED_NUMBER_WITH_WINNINGNUMBERS.getMessage()); + } + return bonusNumber; + } + +} diff --git a/src/main/java/lotto/domain/Budget.java b/src/main/java/lotto/domain/Budget.java new file mode 100644 index 00000000000..d307b3d02bf --- /dev/null +++ b/src/main/java/lotto/domain/Budget.java @@ -0,0 +1,46 @@ +package lotto.domain; + +import java.util.HashMap; +import java.util.Map; +import lotto.message.ViewMessage; +import lotto.view.InputView; + +public class Budget { + private int amount; + + public Budget(int amount) { + validateBudget(amount); + this.amount = amount; + } + public static double calculateTotalReturnRate(Budget budget, Map resultMap) { + // ๋‹น์ฒจ๊ธˆ์•ก๊ณผ ์ƒ๊ธˆ์„ ๋งต์œผ๋กœ ์ •์˜ + Map prizeMap = new HashMap<>(); + prizeMap.put("3๊ฐœ ์ผ์น˜ (5,000์›) - ", 5000L); + prizeMap.put("4๊ฐœ ์ผ์น˜ (50,000์›) - ", 50000L); + prizeMap.put("5๊ฐœ ์ผ์น˜ (1,500,000์›) - ", 1500000L); + prizeMap.put("5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ", 30000000L); + prizeMap.put("6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ", 2000000000L); + + // ๋‹น์ฒจ ๊ธˆ์•ก ๊ณ„์‚ฐ + long totalPrize = resultMap.entrySet().stream() + .mapToLong(entry -> prizeMap.getOrDefault(entry.getKey(), 0L) * entry.getValue()) + .sum(); + + // ์ด ํˆฌ์ž ๊ธˆ์•ก ๊ณ„์‚ฐ + long totalInvestment = budget.getAmount(); + + // ์ˆ˜์ต๋ฅ  ๊ณ„์‚ฐ + return (double) totalPrize / totalInvestment * 100; + + // ๊ฒฐ๊ณผ ์ถœ๋ ฅ + } + private static void validateBudget(int amount) { + if (amount % 1000 != 0) { + throw new IllegalArgumentException("1000์› ๋‹จ์œ„๋กœ๋งŒ ๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."); + } + } + public int getAmount() { + return amount; + } + +} diff --git a/src/main/java/lotto/domain/Lotto.java b/src/main/java/lotto/domain/Lotto.java new file mode 100644 index 00000000000..e73b3f100fd --- /dev/null +++ b/src/main/java/lotto/domain/Lotto.java @@ -0,0 +1,59 @@ +package lotto.domain; + +import camp.nextstep.edu.missionutils.Randoms; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import lotto.message.ViewMessage; +import lotto.view.OutputView; + +public class Lotto { + private final List numbers; + + public Lotto(List numbers) { + validate(numbers); + validateDuplicatedNumber(numbers); + this.numbers = numbers; + } + + public static Lottos buyLottoUsingBudget(Budget budget) { + int lottoCount=budget.getAmount() / 1000; + Lottos lottos = new Lottos(new ArrayList<>()); + + for (int i = 0; i < lottoCount; i++) { + List lottoNumbers = Randoms.pickUniqueNumbersInRange(1, 45, 6); + Lotto lotto = new Lotto(lottoNumbers); + lottos.addLotto(lotto); + } + OutputView.printBuyResult(lottoCount, lottos); + return lottos; + } + + private void validate(List numbers) { + if (numbers.size() != 6) { + throw new IllegalArgumentException(); + } + } + private void validateDuplicatedNumber(List numbers) { + Set uniqueNumbers = new HashSet<>(numbers); + if (uniqueNumbers.size() != numbers.size()) { + throw new IllegalArgumentException("์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค."); + } + } + public List getNumbers() { + return numbers; + } + + public String printNumbers() { + String numberString = numbers.stream() + .sorted() + .map(String::valueOf) + .collect(Collectors.joining(", ")); + return "[" + numberString + "]"; + } + +} diff --git a/src/main/java/lotto/domain/Lottos.java b/src/main/java/lotto/domain/Lottos.java new file mode 100644 index 00000000000..1acf3e12a5f --- /dev/null +++ b/src/main/java/lotto/domain/Lottos.java @@ -0,0 +1,58 @@ +package lotto.domain; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public record Lottos(List lottoList) { + public void addLotto(Lotto lotto) { + lottoList.add(lotto); + } + public String printAllLottoNumbers() { + return lottoList.stream() + .map(Lotto::printNumbers) + .collect(Collectors.joining("\n")); + } + public static Map compareLottos(Lottos purchasedLottos, Lotto winningLotto, int bonusNumber) { + Map resultMap = new LinkedHashMap<>(); + List winningLottoNumbers = winningLotto.getNumbers(); + + for (Lotto lotto : purchasedLottos.lottoList()){ + List purchasedNumbers = lotto.getNumbers(); + long matchCount = purchasedNumbers.stream() + .filter(winningLottoNumbers::contains) + .count(); + boolean hasBonus = purchasedNumbers.contains(bonusNumber); + updateResult(resultMap, matchCount, hasBonus); + } + return resultMap; + } + + public static void updateResult(Map resultMap, long matchCount, boolean hasBonus) { + resultMap.putIfAbsent("3๊ฐœ ์ผ์น˜ (5,000์›) - ", 0L); + resultMap.putIfAbsent("4๊ฐœ ์ผ์น˜ (50,000์›) - ", 0L); + resultMap.putIfAbsent("5๊ฐœ ์ผ์น˜ (1,500,000์›) - ", 0L); + resultMap.putIfAbsent("5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ", 0L); + resultMap.putIfAbsent("6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ", 0L); + + if (matchCount == 3) { + resultMap.merge("3๊ฐœ ์ผ์น˜ (5,000์›) - ", 1L, Long::sum); + } + if (matchCount == 4) { + resultMap.merge("4๊ฐœ ์ผ์น˜ (50,000์›) - ", 1L, Long::sum); + } + if (matchCount == 5 && hasBonus) { + resultMap.merge("5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ", 1L, Long::sum); + } + if (matchCount == 5 && !hasBonus) { + resultMap.merge("5๊ฐœ ์ผ์น˜ (1,500,000์›) - ", 1L, Long::sum); + } + if (matchCount == 6) { + resultMap.merge("6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ", 1L, Long::sum); + } + } + public int getLottosSize() { + return lottoList.size(); + } +} diff --git a/src/main/java/lotto/message/ErrorMessage.java b/src/main/java/lotto/message/ErrorMessage.java new file mode 100644 index 00000000000..af5d787092d --- /dev/null +++ b/src/main/java/lotto/message/ErrorMessage.java @@ -0,0 +1,17 @@ +package lotto.message; + +public enum ErrorMessage { + PURCHASED_COUNT_PRINT("๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค."), + INPUT_NOT_NUMBER("์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๊ฐ’์„ ์ž…๋ ฅํ•˜์…จ์Šต๋‹ˆ๋‹ค."), + INPUT_NOT_LOTTO_RANGE("๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45๊นŒ์ง€์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."), + INPUT_DUPLICATED_NUMBER_WITH_WINNINGNUMBERS("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."), + INPUT_BLANK("๋นˆ ๊ฐ’์„ ์ž…๋ ฅํ•˜์…จ์Šต๋‹ˆ๋‹ค. ๊ฐ’์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."), + INPUT_NOT_POSITIVE_NUMBER("0๋˜๋Š” ์Œ์ˆ˜๋Š” ์ž…๋ ฅํ• ์ˆ˜์—†์Šต๋‹ˆ๋‹ค. ์–‘์ˆ˜๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"); + private final String message; + ErrorMessage(String message) { + this.message = message; + } + public String getMessage() { + return "[ERROR]" + message; + } +} diff --git a/src/main/java/lotto/message/ViewMessage.java b/src/main/java/lotto/message/ViewMessage.java new file mode 100644 index 00000000000..2922385e3b6 --- /dev/null +++ b/src/main/java/lotto/message/ViewMessage.java @@ -0,0 +1,16 @@ +package lotto.message; + +public enum ViewMessage { + PURCHASED_COUNT_PRINT("๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค."), + TOTAL_RETURN_RATE ("์ด ์ˆ˜์ต๋ฅ ์€ %.1f%%์ž…๋‹ˆ๋‹ค.%n"); + private final String message; + + ViewMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + +} diff --git a/src/main/java/lotto/view/InputView.java b/src/main/java/lotto/view/InputView.java new file mode 100644 index 00000000000..24360bd921b --- /dev/null +++ b/src/main/java/lotto/view/InputView.java @@ -0,0 +1,85 @@ +package lotto.view; + +import camp.nextstep.edu.missionutils.Console; +import java.util.List; +import java.util.stream.Stream; +import lotto.Validator; +import lotto.domain.Budget; +import lotto.domain.Lotto; + +public class InputView { + public static int readInteger(String message) { + while (true) { + System.out.println(message); + String inputString = Console.readLine(); + Integer reslt = attemptToParseInteger(inputString); + if (reslt != null) { + return reslt; + } + } + } + + private static Integer attemptToParseInteger(String inputString) { + try { + Validator.validateBlank(inputString); + Validator.validateType(inputString); + Validator.validatePositiveNumber(inputString); + return Integer.parseInt(inputString); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return null; + } + } + + public static Budget inputBudget() { + Budget budget = null; + while (budget == null) { + budget = attemptToInputBudget(); + } + return budget; + } + + private static Budget attemptToInputBudget() { + try { + return new Budget(InputView.readInteger("๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.")); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage() + " ๋‹ค์‹œ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); + return null; + } + } + + public static Lotto createWinningLotto() { + System.out.println("๋กœ๋˜ ๋ฒˆํ˜ธ 6์ž๋ฆฌ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"); + String input = Console.readLine(); + Validator.validateBlank(input); + Validator.validateDeliiter(input); + List winningNumbers = Stream.of(input.split(",")) + .map(String::trim) + .map(Validator::parseAndValidateNotNumber) + .sorted() + .toList(); + if (winningNumbers.size() != 6) { + throw new IllegalArgumentException("๋กœ๋˜๋ฒˆํ˜ธ๋Š” 6๊ฐœ๋ฅผ ์ž…๋‹ˆ๋‹ค. ์ž…๋ ฅ ๊ฐฏ์ˆ˜๋ฅผ ํ™•์ธํ•˜์„ธ์š”"); + } + + return new Lotto(winningNumbers); + } + public static int createBonusNumber(Lotto winningLotto) { + while (true) { + System.out.println("๋ณด๋„ˆ์Šค ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"); + String input = Console.readLine(); + int bonusNumber = parseBounusNumber(input, winningLotto); + if (bonusNumber != -1) { + return bonusNumber; + } + } + } + private static int parseBounusNumber(String input, Lotto winningLotto) { + try{ + return Validator.parseAndValidateBonusNumber(input, winningLotto); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return -1; + } + } +} diff --git a/src/main/java/lotto/view/OutputView.java b/src/main/java/lotto/view/OutputView.java new file mode 100644 index 00000000000..173b251e5ad --- /dev/null +++ b/src/main/java/lotto/view/OutputView.java @@ -0,0 +1,24 @@ +package lotto.view; + +import java.util.HashMap; +import java.util.Map; +import lotto.domain.Budget; +import lotto.domain.Lotto; +import lotto.domain.Lottos; +import lotto.message.ViewMessage; + +public class OutputView { + public static void printBuyResult(int lottoCount, Lottos lottos) { + System.out.println(lottoCount + ViewMessage.PURCHASED_COUNT_PRINT.getMessage()); + System.out.println(lottos.printAllLottoNumbers()); + } + public static void printResult(Map resultMap) { + resultMap.forEach((key, value) ->{ + System.out.println(key + value + "๊ฐœ"); + } + ); + } + public static void printInvestmentRate(double calculateTotalReturnRate) { + System.out.printf(ViewMessage.TOTAL_RETURN_RATE.getMessage(), calculateTotalReturnRate); + }; +} diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 9f5dfe7eb83..e85ce0cceca 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -1,5 +1,9 @@ package lotto; +import lotto.domain.Budget; +import lotto.domain.Lotto; +import lotto.domain.Lottos; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -18,10 +22,17 @@ void createLottoByOverSize() { @DisplayName("๋กœ๋˜ ๋ฒˆํ˜ธ์— ์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.") @Test void createLottoByDuplicatedNumber() { - // TODO: ์ด ํ…Œ์ŠคํŠธ๊ฐ€ ํ†ต๊ณผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ตฌํ˜„ ์ฝ”๋“œ ์ž‘์„ฑ assertThatThrownBy(() -> new Lotto(List.of(1, 2, 3, 4, 5, 5))) .isInstanceOf(IllegalArgumentException.class); } - - // ์•„๋ž˜์— ์ถ”๊ฐ€ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ๊ฐ€๋Šฅ + @DisplayName("์ž…๋ ฅ๊ธˆ์•ก๋งŒํผ ๋กœ๋˜ ๊ตฌ๋งค ๋กœ์ง ์„ฑ๊ณต ํ…Œ์ŠคํŠธ") + @Test + void buyLottoUsingBudgetSuccessTest() { + //given + Lottos purchasedLotto = Lotto.buyLottoUsingBudget(new Budget(3000)); + //when + int lottoCount = purchasedLotto.getLottosSize(); // Lottos์— ์žˆ๋Š” Lotto ๊ฐ์ฒด์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ด + //then + Assertions.assertThat(lottoCount).isEqualTo(3); + } } \ No newline at end of file diff --git a/src/test/java/lotto/domain/BudgetTest.java b/src/test/java/lotto/domain/BudgetTest.java new file mode 100644 index 00000000000..3116890292e --- /dev/null +++ b/src/test/java/lotto/domain/BudgetTest.java @@ -0,0 +1,25 @@ +package lotto.domain; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.HashMap; +import java.util.Map; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class BudgetTest { + + @DisplayName("์ˆ˜์ต๊ธˆ ๊ณ„์‚ฐ ํ…Œ์ŠคํŠธ") + @Test + void calculateTotalReturnRateTest() { + //given + Budget budget = new Budget(1000); // ํˆฌ์ž ๊ธˆ์•ก 1000์› + Map resultMap = new HashMap<>(); + resultMap.put("3๊ฐœ ์ผ์น˜ (5,000์›) - ", 1L); // 5๋“ฑ ๋‹น์ฒจ 1์žฅ + //when + double totalReturnRate = Budget.calculateTotalReturnRate(budget, resultMap); + //then + Assertions.assertThat(totalReturnRate).isEqualTo(500); + } +} \ No newline at end of file diff --git a/src/test/java/lotto/domain/LottosTest.java b/src/test/java/lotto/domain/LottosTest.java new file mode 100644 index 00000000000..bb05b655ea2 --- /dev/null +++ b/src/test/java/lotto/domain/LottosTest.java @@ -0,0 +1,83 @@ +package lotto.domain; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class LottosTest { + + @DisplayName("๋“ฑ์ˆ˜๊ณ„์‚ฐ๋กœ์ง ํ™•์ธํ…Œ์ŠคํŠธ") + @ParameterizedTest + @MethodSource("ValuesByRank") + void compareLottosTest(Lottos purchasedLottos, Map expectedResults) { + //given + + Lotto winningLotto = new Lotto(List.of(1, 2, 3, 4, 5, 6)); + int bonusNumber = 7; + //when + Map purchasedLottosResult = Lottos.compareLottos(purchasedLottos, winningLotto, bonusNumber); + //then + Assertions.assertThat(purchasedLottosResult) + .isEqualTo(expectedResults); + } + + static Stream ValuesByRank() { + return Stream.of( + Arguments.of(new Lottos(List.of( + new Lotto(List.of(1, 2, 3, 4, 5, 6)) // 1๋“ฑ + )), Map.of( + "3๊ฐœ ์ผ์น˜ (5,000์›) - ", 0L, + "4๊ฐœ ์ผ์น˜ (50,000์›) - ", 0L, + "5๊ฐœ ์ผ์น˜ (1,500,000์›) - ", 0L, + "5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ", 0L, + "6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ", 1L + )), + Arguments.of(new Lottos(List.of( + new Lotto(List.of(1, 2, 3, 4, 5, 7)) // 2๋“ฑ + )), Map.of( + "3๊ฐœ ์ผ์น˜ (5,000์›) - ", 0L, + "4๊ฐœ ์ผ์น˜ (50,000์›) - ", 0L, + "5๊ฐœ ์ผ์น˜ (1,500,000์›) - ", 0L, + "5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ", 1L, + "6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ", 0L + )), + Arguments.of(new Lottos(List.of( + new Lotto(List.of(1, 2, 3, 4, 5, 8)) // 3๋“ฑ + )), Map.of( + "3๊ฐœ ์ผ์น˜ (5,000์›) - ", 0L, + "4๊ฐœ ์ผ์น˜ (50,000์›) - ", 0L, + "5๊ฐœ ์ผ์น˜ (1,500,000์›) - ", 1L, + "5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ", 0L, + "6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ", 0L + )), + Arguments.of(new Lottos(List.of( + new Lotto(List.of(1, 2, 3, 4, 8, 9)) // 4๋“ฑ + )), Map.of( + "3๊ฐœ ์ผ์น˜ (5,000์›) - ", 0L, + "4๊ฐœ ์ผ์น˜ (50,000์›) - ", 1L, + "5๊ฐœ ์ผ์น˜ (1,500,000์›) - ", 0L, + "5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ", 0L, + "6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ", 0L + )), + Arguments.of(new Lottos(List.of( + new Lotto(List.of(1, 2, 3, 8, 9, 10)) // 5๋“ฑ + )), Map.of( + "3๊ฐœ ์ผ์น˜ (5,000์›) - ", 1L, + "4๊ฐœ ์ผ์น˜ (50,000์›) - ", 0L, + "5๊ฐœ ์ผ์น˜ (1,500,000์›) - ", 0L, + "5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ", 0L, + "6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ", 0L + )) + ); +} + + +} \ No newline at end of file