diff --git a/src/main/java/lotto/LottoMain.java b/src/main/java/lotto/LottoMain.java index 3ed6d871ad..03f0a81567 100644 --- a/src/main/java/lotto/LottoMain.java +++ b/src/main/java/lotto/LottoMain.java @@ -4,13 +4,23 @@ import lotto.view.InputView; import lotto.view.ResultView; +import java.util.List; + public class LottoMain { public static void main(String[] args) { Money money = new Money(InputView.getInputMoney()); - LottoGroup lottoGroup = new LottoGroup(money); + int inputManualLottoCount = InputView.getInputManualLottoCount(); + + LottoCount lottoCount = new LottoCount(money, inputManualLottoCount); + + LottoPurChase lottoPurChase = new LottoPurChase(money, lottoCount); + + List manualLottos = InputView.getInputManualLottos(inputManualLottoCount); + + LottoGroup lottoGroup = new LottoGroup(new LottosBundleGenerator(lottoPurChase, manualLottos)); - ResultView.showBuyLottos(lottoGroup); + ResultView.showBuyLottos(lottoGroup, lottoPurChase); Lotto winLotto = new Lotto(InputView.getInputWinNumber()); diff --git a/src/main/java/lotto/domain/AutoLottoGenerator.java b/src/main/java/lotto/domain/AutoLottoGenerator.java new file mode 100644 index 0000000000..cafd7dbb2c --- /dev/null +++ b/src/main/java/lotto/domain/AutoLottoGenerator.java @@ -0,0 +1,27 @@ +package lotto.domain; + +import java.util.ArrayList; +import java.util.List; + +public class AutoLottoGenerator implements LottoGenerator { + private final Money money; + + public AutoLottoGenerator(int money) { + this(new Money(money)); + } + + public AutoLottoGenerator(Money money) { + this.money = money; + } + + @Override + public List generate() { + List lottoArray = new ArrayList<>(); + + for (int i = 0; i < money.getBuyableCount(); i++) { + lottoArray.add(new Lotto(LottoMachine.createLottoNumbers())); + } + + return lottoArray; + } +} diff --git a/src/main/java/lotto/domain/Lotto.java b/src/main/java/lotto/domain/Lotto.java index 104acb6dbc..a382aca165 100644 --- a/src/main/java/lotto/domain/Lotto.java +++ b/src/main/java/lotto/domain/Lotto.java @@ -1,11 +1,10 @@ package lotto.domain; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; +import java.util.*; +import java.util.stream.Collectors; public class Lotto { - private final List numbers; + private final Set numbers; public Lotto(int... numbers) { this(intToList(numbers)); @@ -15,20 +14,42 @@ public Lotto(String... numbers) { this(stringToList(numbers)); } - public Lotto(List numbers) { + public Lotto(String numbers) { + this(stringToList(parse(numbers))); + } + + private static String[] parse(String s) { + String[] strs = s.split(","); + + for (int i = 0; i < strs.length; i++) { + strs[i] = strs[i].trim(); + } + + return strs; + } + + public Lotto(Set numbers) { + System.out.println(numbers); + validation(numbers); this.numbers = numbers; } - private static List stringToList(String... numbers) { + private void validation(Set numbers) { + if (numbers.size() != 6) { + throw new IllegalArgumentException("로또 번호는 6개여야 합니다."); + } + } + + private static Set stringToList(String... numbers) { return Arrays.stream(numbers) .map(LottoNumber::valueOf) - .toList(); + .collect(Collectors.toSet()); } - private static List intToList(int... numbers) { + private static Set intToList(int... numbers) { return Arrays.stream(numbers) .mapToObj(LottoNumber::valueOf) - .toList(); + .collect(Collectors.toSet()); } public int countMatchedNumbers(Lotto winningLotto) { diff --git a/src/main/java/lotto/domain/LottoCount.java b/src/main/java/lotto/domain/LottoCount.java new file mode 100644 index 0000000000..030d012fcc --- /dev/null +++ b/src/main/java/lotto/domain/LottoCount.java @@ -0,0 +1,23 @@ +package lotto.domain; + +public class LottoCount { + private final int manualCount; + private final int autoCount; + + public LottoCount(Money money, int manualCount) { + this(money.getBuyableCount() - manualCount, manualCount); + } + + public LottoCount(int autoCount, int manualCount) { + this.autoCount = autoCount; + this.manualCount = manualCount; + } + + public int getManualCount() { + return this.manualCount; + } + + public int getAutoCount() { + return this.autoCount; + } +} diff --git a/src/main/java/lotto/domain/LottoGenerator.java b/src/main/java/lotto/domain/LottoGenerator.java new file mode 100644 index 0000000000..34a8e2fb07 --- /dev/null +++ b/src/main/java/lotto/domain/LottoGenerator.java @@ -0,0 +1,7 @@ +package lotto.domain; + +import java.util.List; + +public interface LottoGenerator { + List generate(); +} diff --git a/src/main/java/lotto/domain/LottoGroup.java b/src/main/java/lotto/domain/LottoGroup.java index 12791db65f..90432269db 100644 --- a/src/main/java/lotto/domain/LottoGroup.java +++ b/src/main/java/lotto/domain/LottoGroup.java @@ -6,24 +6,13 @@ public class LottoGroup { private final List lottos; - public LottoGroup(Money money) { - this(buyLotto(money)); + public LottoGroup(LottoGenerator lottoGenerator) { + this(lottoGenerator.generate()); } public LottoGroup(List lottos) { this.lottos = lottos; } - private static List buyLotto(Money money) { - int cnt = money.getBuyableCount(); - - List lottoArray = new ArrayList<>(); - - for(int i = 0; i < cnt; i++) { - lottoArray.add(new Lotto(LottoMachine.createLottoNumbers())); - } - - return lottoArray; - } public List getLottoNumbers() { return lottos; diff --git a/src/main/java/lotto/domain/LottoMachine.java b/src/main/java/lotto/domain/LottoMachine.java index b54ef30e3f..47e331acec 100644 --- a/src/main/java/lotto/domain/LottoMachine.java +++ b/src/main/java/lotto/domain/LottoMachine.java @@ -11,7 +11,7 @@ public class LottoMachine { public static int[] createLottoNumbers() { List nums = new ArrayList<>(); - for(int i = MIN_NUMBER; i <= MAX_NUMBER; i++){ + for (int i = MIN_NUMBER; i <= MAX_NUMBER; i++) { nums.add(i); } @@ -22,7 +22,7 @@ public static int[] createLottoNumbers() { private static int[] selectLottoNumbers(List lottoNumbers) { int[] nums = new int[COUNT]; - for(int i = 0; i < COUNT; i++){ + for (int i = 0; i < COUNT; i++) { nums[i] = lottoNumbers.get(i); } return nums; diff --git a/src/main/java/lotto/domain/LottoNumber.java b/src/main/java/lotto/domain/LottoNumber.java index a6fbe061e4..917d3af33e 100644 --- a/src/main/java/lotto/domain/LottoNumber.java +++ b/src/main/java/lotto/domain/LottoNumber.java @@ -9,8 +9,8 @@ public class LottoNumber { private static final int MAX = 45; private static final Map CACHE_NUM = new HashMap<>(); - static{ - for (int i = MIN; i <= MAX; i++){ + static { + for (int i = MIN; i <= MAX; i++) { CACHE_NUM.put(i, new LottoNumber(i)); } } @@ -22,12 +22,12 @@ public LottoNumber(int number) { this.number = number; } - public static LottoNumber valueOf(String number){ + public static LottoNumber valueOf(String number) { validation(Integer.parseInt(number)); - return CACHE_NUM.get(Integer.parseInt(number)); + return valueOf(Integer.parseInt(number)); } - public static LottoNumber valueOf(int number){ + public static LottoNumber valueOf(int number) { validation(number); return CACHE_NUM.get(number); } diff --git a/src/main/java/lotto/domain/LottoPurChase.java b/src/main/java/lotto/domain/LottoPurChase.java new file mode 100644 index 0000000000..32c649bb56 --- /dev/null +++ b/src/main/java/lotto/domain/LottoPurChase.java @@ -0,0 +1,31 @@ +package lotto.domain; + +public class LottoPurChase { + private final Money money; + private final LottoCount lottoCount; + + + public LottoPurChase(int money, int autoCount, int manualCount) { + this(new Money(money), new LottoCount(autoCount, manualCount)); + } + + public LottoPurChase(Money money, LottoCount lottoCount) { + this.money = money; + this.lottoCount = lottoCount; + } + public Money deductManualLottoCost() { + return this.money.deductManualLottoCost(lottoCount.getManualCount()); + } + + public Money getMoney() { + return this.money; + } + + public int getAutoCount() { + return this.lottoCount.getAutoCount(); + } + + public int getManualCount() { + return this.lottoCount.getManualCount(); + } +} diff --git a/src/main/java/lotto/domain/LottoResult.java b/src/main/java/lotto/domain/LottoResult.java index 827f80fa20..522de57a06 100644 --- a/src/main/java/lotto/domain/LottoResult.java +++ b/src/main/java/lotto/domain/LottoResult.java @@ -9,7 +9,8 @@ public class LottoResult { public LottoResult() { this(initResult()); } - public LottoResult(Map result) { + + public LottoResult(Map result) { this.result = result; } @@ -36,7 +37,7 @@ private static Map initResult() { } public void rank(LottoRank rank) { - if(rank.isAddAble()) { + if (rank.isAddAble()) { result.put(rank, result.get(rank) + 1); } } diff --git a/src/main/java/lotto/domain/LottoWinningNumbers.java b/src/main/java/lotto/domain/LottoWinningNumbers.java index e83d31ad69..f5e52d2194 100644 --- a/src/main/java/lotto/domain/LottoWinningNumbers.java +++ b/src/main/java/lotto/domain/LottoWinningNumbers.java @@ -4,6 +4,10 @@ public class LottoWinningNumbers { private final Lotto winningLotto; private final LottoNumber bonusNumber; + public LottoWinningNumbers(Lotto winningLotto, int bonusNumber) { + this(winningLotto, new LottoNumber(bonusNumber)); + } + public LottoWinningNumbers(Lotto winningLotto, LottoNumber bonusNumber) { this.winningLotto = winningLotto; this.bonusNumber = bonusNumber; diff --git a/src/main/java/lotto/domain/LottosBundleGenerator.java b/src/main/java/lotto/domain/LottosBundleGenerator.java new file mode 100644 index 0000000000..fc8ee1bf80 --- /dev/null +++ b/src/main/java/lotto/domain/LottosBundleGenerator.java @@ -0,0 +1,26 @@ +package lotto.domain; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class LottosBundleGenerator implements LottoGenerator{ + private final LottoPurChase lottoPurChase; + private final List manualLottoText; + + public LottosBundleGenerator(LottoPurChase lottoPurChase, List manualLottoText) { + this.lottoPurChase = lottoPurChase; + this.manualLottoText = manualLottoText; + } + + @Override + public List generate() { + // ManualLottosGenerator 활용해 수동 로또 생성 + List manualLottos = new ManualLottosGenerator(manualLottoText).generate(); + + // AutoLottosGenerator 활용해 자동 로또 생성(수동 로또 수 만큼 Money 차감) + List autoLottos = new AutoLottoGenerator(lottoPurChase.deductManualLottoCost()).generate(); + + return Stream.concat(manualLottos.stream(), autoLottos.stream()).collect(Collectors.toList()); + } +} diff --git a/src/main/java/lotto/domain/ManualLottosGenerator.java b/src/main/java/lotto/domain/ManualLottosGenerator.java new file mode 100644 index 0000000000..086946823d --- /dev/null +++ b/src/main/java/lotto/domain/ManualLottosGenerator.java @@ -0,0 +1,19 @@ +package lotto.domain; + +import java.util.List; +import java.util.stream.Collectors; + +public class ManualLottosGenerator implements LottoGenerator { + private final List manualLottos; + + public ManualLottosGenerator(List manualLottos) { + this.manualLottos = manualLottos; + } + + @Override + public List generate() { + return manualLottos.stream() + .map(Lotto::new) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/lotto/domain/Money.java b/src/main/java/lotto/domain/Money.java index f16a0fbc84..003e965534 100644 --- a/src/main/java/lotto/domain/Money.java +++ b/src/main/java/lotto/domain/Money.java @@ -29,6 +29,10 @@ public double getYield(Money total) { return total.value() / (double) this.money; } + public Money deductManualLottoCost(int manualCount) { + return new Money(this.money - (manualCount * PRICE)); + } + @Override public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; diff --git a/src/main/java/lotto/view/InputView.java b/src/main/java/lotto/view/InputView.java index 6f4ed7f831..81733798a8 100644 --- a/src/main/java/lotto/view/InputView.java +++ b/src/main/java/lotto/view/InputView.java @@ -2,6 +2,8 @@ import lotto.domain.Lotto; +import java.util.ArrayList; +import java.util.List; import java.util.Scanner; public class InputView { @@ -12,6 +14,22 @@ public static int getInputMoney() { return Integer.parseInt(scanner.nextLine()); } + public static int getInputManualLottoCount() { + System.out.println("수동으로 구매할 로또 수를 입력해 주세요."); + return Integer.parseInt(scanner.nextLine()); + } + + public static List getInputManualLottos(int manualLottoCount) { + System.out.println("수동으로 구매할 번호를 입력해 주세요."); + + List manualLottos = new ArrayList<>(); + for (int i = 0; i < manualLottoCount; i++) { + manualLottos.add(scanner.nextLine()); + } + + return manualLottos; + } + public static String[] getInputWinNumber() { System.out.println("지난 주 당첨 번호를 입력해 주세요."); diff --git a/src/main/java/lotto/view/ResultView.java b/src/main/java/lotto/view/ResultView.java index 40914c8109..80bbc60212 100644 --- a/src/main/java/lotto/view/ResultView.java +++ b/src/main/java/lotto/view/ResultView.java @@ -4,8 +4,8 @@ public class ResultView { - public static void showBuyLottos(LottoGroup lottoGroup) { - System.out.printf("%d개를 구매했습니다.%n", lottoGroup.getLottoNumbers().size()); + public static void showBuyLottos(LottoGroup lottoGroup, LottoPurChase lottoPurchase) { + System.out.printf("수동으로 %d장, 자동으로 %d개를 구매했습니다.%n", lottoPurchase.getManualCount(), lottoPurchase.getAutoCount()); for (Lotto lotto : lottoGroup.getLottoNumbers()) { System.out.println(lotto); diff --git a/src/test/java/lotto/domain/LottoCountTest.java b/src/test/java/lotto/domain/LottoCountTest.java new file mode 100644 index 0000000000..85eec900c7 --- /dev/null +++ b/src/test/java/lotto/domain/LottoCountTest.java @@ -0,0 +1,14 @@ +package lotto.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +public class LottoCountTest { + + @Test + void 수동_자동_카운트해서_생성() { + LottoCount lottoCount = new LottoCount(11, 3); + + Assertions.assertThat(lottoCount.getAutoCount()).isEqualTo(11); + } +} diff --git a/src/test/java/lotto/domain/LottoGeneratorTest.java b/src/test/java/lotto/domain/LottoGeneratorTest.java new file mode 100644 index 0000000000..b0d8b73c3b --- /dev/null +++ b/src/test/java/lotto/domain/LottoGeneratorTest.java @@ -0,0 +1,28 @@ +package lotto.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +public class LottoGeneratorTest { + + @Test + @DisplayName("돈을 입력하여 자동으로 몇장 살 수 있는지") + void AutoGenerator() { + LottoGenerator autoLottoGenerator = new AutoLottoGenerator(14000); + + Assertions.assertThat(autoLottoGenerator.generate()).hasSize(14); + } + + @Test + @DisplayName("돈을 입력하여 자동과 수동으로 몇장 살 수 있는지") + void mixGenerator() { + LottoGenerator mixedLottoGenerator = new LottosBundleGenerator( + new LottoPurChase(3000, 2, 1), List.of("1, 2, 3, 4, 5, 6") + ); + + Assertions.assertThat(mixedLottoGenerator.generate()).hasSize(3); + } +} diff --git a/src/test/java/lotto/domain/LottoGroupTest.java b/src/test/java/lotto/domain/LottoGroupTest.java index fe36d35a41..4b56ddd2ec 100644 --- a/src/test/java/lotto/domain/LottoGroupTest.java +++ b/src/test/java/lotto/domain/LottoGroupTest.java @@ -7,7 +7,7 @@ public class LottoGroupTest { @Test void 로또_몇장_구매할_수_있는지() { - LottoGroup lottoGroup = new LottoGroup(new Money(14000)); + LottoGroup lottoGroup = new LottoGroup(new AutoLottoGenerator(new Money(14000))); assertThat(lottoGroup.getLottoNumbers()).hasSize(14); } diff --git a/src/test/java/lotto/domain/LottoPurchaseTest.java b/src/test/java/lotto/domain/LottoPurchaseTest.java new file mode 100644 index 0000000000..a29ed700a0 --- /dev/null +++ b/src/test/java/lotto/domain/LottoPurchaseTest.java @@ -0,0 +1,13 @@ +package lotto.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +public class LottoPurchaseTest { + @Test + void create() { + LottoPurChase lottoPurChase = new LottoPurChase(14000, 11, 3); + + Assertions.assertThat(lottoPurChase.getMoney()).isEqualTo(new Money(14000)); + } +} diff --git a/src/test/java/lotto/domain/LottoResultTest.java b/src/test/java/lotto/domain/LottoResultTest.java index 05aa76c0e2..ddeb062aaa 100644 --- a/src/test/java/lotto/domain/LottoResultTest.java +++ b/src/test/java/lotto/domain/LottoResultTest.java @@ -18,7 +18,7 @@ public class LottoResultTest { ) ); - LottoWinningNumbers lottoWinningNumbers = new LottoWinningNumbers(winLotto, LottoNumber.valueOf(10)); + LottoWinningNumbers lottoWinningNumbers = new LottoWinningNumbers(winLotto, 10); LottoResult lottoResult = lottoGroup.match(lottoWinningNumbers); Assertions.assertThat(lottoResult.calTotal()).isEqualTo(new Money(10000)); @@ -35,7 +35,7 @@ public class LottoResultTest { ) ); - LottoWinningNumbers lottoWinningNumbers = new LottoWinningNumbers(winLotto, LottoNumber.valueOf(10)); + LottoWinningNumbers lottoWinningNumbers = new LottoWinningNumbers(winLotto, 10); LottoResult lottoResult = lottoGroup.match(lottoWinningNumbers); diff --git a/src/test/java/lotto/domain/LottoTest.java b/src/test/java/lotto/domain/LottoTest.java index a7337dd99e..ecc9430e3c 100644 --- a/src/test/java/lotto/domain/LottoTest.java +++ b/src/test/java/lotto/domain/LottoTest.java @@ -3,31 +3,39 @@ import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; public class LottoTest { @Test void 로또_개수_구하기() { - Lotto lotto = new Lotto(1,2,3,4,5,6); + Lotto lotto = new Lotto(1, 2, 3, 4, 5, 6); assertThat(lotto.countMatchedNumbers( - new Lotto(1,2,3,11,22,33) + new Lotto(1, 2, 3, 11, 22, 33) )).isEqualTo(3); } @Test void 포함된_숫자인지() { - Lotto lotto = new Lotto(1,2,3,4,5,6); + Lotto lotto = new Lotto(1, 2, 3, 4, 5, 6); assertThat(lotto.contains(LottoNumber.valueOf(1))).isTrue(); } @Test void 로또_스트링으로_받기() { - Lotto lotto = new Lotto("1","2","3","4","5","6"); + Lotto lotto = new Lotto("1,2,3,4,5,6"); assertThat(lotto.countMatchedNumbers( - new Lotto(1,2,3,11,22,33) + new Lotto(1, 2, 3, 11, 22, 33) )).isEqualTo(3); } + + @Test + void 로또_번호는_6개_이여야_함() { + assertThatThrownBy(()-> new Lotto("1,2,3,4,5")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("로또 번호는 6개여야 합니다."); + } }