From fe1717326bd2bb13b104e3dcd86b805a05e77a6f Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 11:15:00 +0900 Subject: [PATCH 01/15] feat: copy code from yoonhocho branch --- docs/README.md | 40 ++++++ src/main/java/lotto/lotto/Lotto.java | 79 ++++++++++++ src/main/java/lotto/lotto/LottoBundle.java | 119 ++++++++++++++++++ src/main/java/lotto/lotto/LottoService.java | 79 ++++++++++++ src/main/java/lotto/lotto/Prize.java | 51 ++++++++ .../java/lotto/purchase/PurchaseService.java | 30 +++++ src/main/java/lotto/view/UserInput.java | 25 ++++ src/main/java/lotto/view/UserOutput.java | 27 ++++ 8 files changed, 450 insertions(+) create mode 100644 src/main/java/lotto/lotto/Lotto.java create mode 100644 src/main/java/lotto/lotto/LottoBundle.java create mode 100644 src/main/java/lotto/lotto/LottoService.java create mode 100644 src/main/java/lotto/lotto/Prize.java create mode 100644 src/main/java/lotto/purchase/PurchaseService.java create mode 100644 src/main/java/lotto/view/UserInput.java create mode 100644 src/main/java/lotto/view/UserOutput.java diff --git a/docs/README.md b/docs/README.md index e69de29bb2..72a7d3c3fd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,40 @@ +## 기능 리스트 + +- [ ] 가격 -> 개수 반환 +- [ ] 로또 발행 +- [ ] 총 일치 수, 금액, 수익률 계산 +- [ ] 정답로또 입력받기 + - validation + - 보너스점수 +- [ ] ㅇ + + +PurchaseService +- (금액) -> 개수 // thr + +Enum Prize +- 출력문구 matches bonus reward + +LottoService + + +LottoBundle +- 로또 수 +- LottoStatus list +- +- Lotto 정답로또 +- 보너스번호 +- + +LottoStatus +- Lotto +- 일치 수 +- 보너스 여부 +- (정답로또, 보너스) -> 일치 수 , 보너스 여부 +- + +Lotto +- 랜덤로또 발행 +- 정답로또 생성 +- + diff --git a/src/main/java/lotto/lotto/Lotto.java b/src/main/java/lotto/lotto/Lotto.java new file mode 100644 index 0000000000..b5cae56641 --- /dev/null +++ b/src/main/java/lotto/lotto/Lotto.java @@ -0,0 +1,79 @@ +package lotto.lotto; + + +import lotto.lotto.lottoCreator.LottoCreator; +import lotto.lotto.lottoCreator.RandomLottoCreator; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; + +public class Lotto { + private final static int LOTTO_NUM_LENGTH = 6; + private final static int LOTTO_MIN_NUM = 1; + private final static int LOTTO_MAX_NUM = 45; + private final List numbers; + + public Lotto(List numbers) { + validate(numbers); + + try { + numbers.sort(Comparator.naturalOrder()); + } catch (UnsupportedOperationException ignored) { + } + + this.numbers = numbers; + } + + public static Lotto from(LottoCreator lottoCreator) { + return lottoCreator.getLotto( + LOTTO_MIN_NUM, + LOTTO_MAX_NUM, + LOTTO_NUM_LENGTH + ); + } + + private void validate(List numbers) { + if (numbers.size() != LOTTO_NUM_LENGTH) + throw new IllegalArgumentException("[ERROR] 숫자의 개수가 올바르지 않습니다."); + if (numbers.size() != (new HashSet<>(numbers)).size()) + throw new IllegalArgumentException("[ERROR] 숫자에 중복이 없어야 합니다."); + } + + public Prize comparePrize(Lotto winningLotto, int bonus) { + List list = new ArrayList<>(); + list.addAll(numbers); + list.addAll(winningLotto.numbers); + int matches = list.size() - (new HashSet<>(list)).size(); + boolean isBonus = numbers.contains(bonus); + + Prize prize = Prize.NONE; + for (Prize p : Prize.values()) { + if ( + p.isPrized() && + p.getMatchNum() <= matches && + p.getGrade() <= prize.getGrade() + ) { + if (p.isBonus() && !isBonus) // 보너스 true인 경우 isBonus 확인한다. + continue; + prize = p; + } + } + return prize; + } + + public boolean contains(int num) { + return numbers.contains(num); + } + + @Override + public String toString() { + return numbers.toString(); + } + + public List getNumbers() { + return numbers; + } +} diff --git a/src/main/java/lotto/lotto/LottoBundle.java b/src/main/java/lotto/lotto/LottoBundle.java new file mode 100644 index 0000000000..377f3586b6 --- /dev/null +++ b/src/main/java/lotto/lotto/LottoBundle.java @@ -0,0 +1,119 @@ +package lotto.lotto; + +import lotto.lotto.lottoCreator.LottoCreator; +import lotto.lotto.model.LottoOutputModel; +import lotto.lotto.model.StatusOutputModel; +import lotto.purchase.PurchaseService; +import lotto.view.UserOutput; + +import java.util.ArrayList; +import java.util.List; + +public class LottoBundle { + private List lottos = new ArrayList<>(); + private Lotto winningLotto; + private int bonus; + + + /** + * lottoNum의 수만큼 새로운 로또 생성하기 + */ + // todo : deprecated + public void createLottos(int lottoNum) { + for (int i = 0; i < lottoNum; i++) { +// Lotto lotto = Lotto.newRandomLotto(); +// lottos.add(lotto); + } + } + + /** + * lottoNum의 수만큼 새로운 로또 생성하기 + */ + public void createLottos(List lottoCreators) { + for (LottoCreator creator : lottoCreators) { + Lotto lotto = Lotto.from(creator); + lottos.add(lotto); + } + } + + /** + * 당첨번호 저장하기 + */ + // todo : deprecated + public void setWinningLotto(List winningNumList) { + Lotto lotto = new Lotto(winningNumList); + this.winningLotto = lotto; + } + + /** + * 당첨번호 저장하기 + */ + public void setWinningLotto(LottoCreator creator) { + Lotto lotto = Lotto.from(creator); + this.winningLotto = lotto; + } + + /** + * 보너스번호 저장하기 + */ + public void setBonus(int bonus) { + if (winningLotto.contains(bonus)) { + throw new IllegalArgumentException("[ERROR] 보너스 번호와 당첨 번호에 중복이 있습니다."); + } + this.bonus = bonus; + } + + /** + * 로또 출력하기 + */ + public LottoOutputModel getLottosInfo() { + List> lottoNumbers = new ArrayList<>(); + for (Lotto lotto : lottos) + lottoNumbers.add(lotto.getNumbers()); + return new LottoOutputModel(lottos.size(), lottoNumbers); + } + + /** + * 당첨 통계 출력하기 + */ + public StatusOutputModel getResultStatus() { + int[] prizeStat = getPrizeStat(); + int totalreward = getTotalReward(prizeStat); + double rewardPercent = PurchaseService.getRewardPercent(lottos.size(), totalreward); + + StringBuilder sb = new StringBuilder(); + for (Prize prize : Prize.values()) { + if (!prize.isPrized()) continue; + sb.append(prize.getToString()); + sb.append( + String.format(" (%,d원) - %d개", + prize.getReward(), + prizeStat[prize.ordinal()] + )); + sb.append("\n"); + } + sb.append(String.format("총 수익률은 %.1f%%입니다.", rewardPercent)); + + return new StatusOutputModel(sb.toString()); + } + + public int[] getPrizeStat() { + int[] prizeStat = new int[Prize.values().length]; + for (Lotto lotto : lottos) { + Prize prize = lotto.comparePrize(winningLotto, bonus); + if (prize.isPrized()) + prizeStat[prize.ordinal()]++; + } + return prizeStat; + } + + public int getTotalReward(int[] prizeStat) { + int totalReward = 0; + for (Prize prize : Prize.values()) { + if (prizeStat[prize.ordinal()] != 0) + totalReward += prize.getReward() * prizeStat[prize.ordinal()]; + } + return totalReward; + } + +} diff --git a/src/main/java/lotto/lotto/LottoService.java b/src/main/java/lotto/lotto/LottoService.java new file mode 100644 index 0000000000..d5d0ce93dd --- /dev/null +++ b/src/main/java/lotto/lotto/LottoService.java @@ -0,0 +1,79 @@ +package lotto.lotto; + +import lotto.lotto.lottoCreator.ManualLottoCreator; +import lotto.lotto.lottoCreator.RandomLottoCreator; +import lotto.purchase.PurchaseService; +import lotto.view.UserInput; +import lotto.view.UserOutput; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class LottoService { + + public void run() { + LottoBundle bundle = new LottoBundle(); + + // 구입금액 입력받기 + int cost = getNum(UserInput.getCostInput()); + int lottoNum = PurchaseService.getLottoNum(cost); + bundle.createLottos( + Stream.generate(RandomLottoCreator::from) + .limit(lottoNum) + .collect(Collectors.toList()) + ); + + // 로또 출력하기 + UserOutput.printLottos(bundle.getLottosInfo()); + + // 당첨번호 입력받기 + List winningList = getNumList(UserInput.getLottoInput()); + bundle.setWinningLotto(ManualLottoCreator.from(winningList)); + + // 보너스번호 입력받기 + int bonus = getNum(UserInput.getBonusInput()); + bundle.setBonus(bonus); + + // 당첨 통계 출력하기 + UserOutput.printResult(bundle.getResultStatus()); + } + + + public int getNum(String input) { + int num; + try { + num = Integer.parseInt(input); + } catch (NumberFormatException ne) { + throw new IllegalArgumentException("[ERROR] 정수를 입력해주세요."); + } + return num; + } + + public List getNumList(String input) { + List strList = new ArrayList<>( + Arrays.asList( + input.split(",") + ) + ); + + // "," 개수를 이용해서 배열의 길이가 올바르게 입력되었는지 확인한다. + int commas = input.length() - input.replace(String.valueOf(","), "").length(); + if (commas + 1 != strList.size()) + throw new IllegalArgumentException("[ERROR] 정수와 ,로 이루어진 배열을 입력해주세요."); + + List numList = strList.stream() + .map(s -> { + try { + return Integer.parseInt(s); + } catch (NumberFormatException ne) { + throw new IllegalArgumentException("[ERROR] 정수와 ,로 이루어진 배열을 입력해주세요."); + } + }).collect(Collectors.toList()); + + return numList; + } + +} diff --git a/src/main/java/lotto/lotto/Prize.java b/src/main/java/lotto/lotto/Prize.java new file mode 100644 index 0000000000..762425e7ee --- /dev/null +++ b/src/main/java/lotto/lotto/Prize.java @@ -0,0 +1,51 @@ +package lotto.lotto; + +public enum Prize { + FIFTH(true, 5, 3, false, 5000, "3개 일치"), + FOURTH(true, 4, 4, false, 50000, "4개 일치"), + THIRD(true, 3, 5, false, 1500000, "5개 일치"), + SECOND(true, 2, 5, true, 30000000, "5개 일치, 보너스 볼 일치"), + FIRST(true, 1, 6, false, 2000000000, "6개 일치"), + NONE(false, 99999, 0, false, 0, ""); + + private final boolean prized; + private final int grade; + private final int matchNum; + private final boolean bonus; + private final int reward; + private final String toString; + + Prize(boolean prized, int grade, int matchNum, boolean bonus, int reward, String toString) { + this.prized = prized; + this.grade = grade; + this.matchNum = matchNum; + this.bonus = bonus; + this.reward = reward; + this.toString = toString; + } + + public boolean isPrized() { + return prized; + } + + public int getGrade() { + return grade; + } + + public int getMatchNum() { + return matchNum; + } + + public boolean isBonus() { + return bonus; + } + + public int getReward() { + return reward; + } + + public String getToString() { + return toString; + } + +} diff --git a/src/main/java/lotto/purchase/PurchaseService.java b/src/main/java/lotto/purchase/PurchaseService.java new file mode 100644 index 0000000000..8aaf074500 --- /dev/null +++ b/src/main/java/lotto/purchase/PurchaseService.java @@ -0,0 +1,30 @@ +package lotto.purchase; + +public class PurchaseService { + + private final static int PRICE_PER_LOTTO = 1000; + + private PurchaseService() { + } + + /** + * 텍스트 입력을 lotto 수로 변환 + */ + public static int getLottoNum(int cost) { + if (cost <=0 ) + throw new IllegalArgumentException("[ERROR] 1 이상의 양수를 입력해주세요"); + if (cost % PRICE_PER_LOTTO != 0) + throw new IllegalArgumentException("[ERROR] 가격의 배수에 해당하는 가격을 입력해주세요"); + + return cost / PRICE_PER_LOTTO; + } + + /** + * 총 로또 수익률을 퍼센트 단위로 반환 + */ + public static double getRewardPercent(int num, int reward){ + return (double) reward / (num * PRICE_PER_LOTTO) * 100; + } + + +} diff --git a/src/main/java/lotto/view/UserInput.java b/src/main/java/lotto/view/UserInput.java new file mode 100644 index 0000000000..51f46f99a4 --- /dev/null +++ b/src/main/java/lotto/view/UserInput.java @@ -0,0 +1,25 @@ +package lotto.view; + +import camp.nextstep.edu.missionutils.Console; + +public class UserInput { + + private UserInput() { + } + + public static String getCostInput() { + System.out.println("구입금액을 입력해 주세요."); + return Console.readLine().trim(); + } + + public static String getLottoInput(){ + System.out.println("당첨 번호를 입력해 주세요."); + return Console.readLine().trim(); + } + + public static String getBonusInput(){ + System.out.println("보너스 번호를 입력해 주세요."); + return Console.readLine().trim(); + } + +} diff --git a/src/main/java/lotto/view/UserOutput.java b/src/main/java/lotto/view/UserOutput.java new file mode 100644 index 0000000000..78631d9a48 --- /dev/null +++ b/src/main/java/lotto/view/UserOutput.java @@ -0,0 +1,27 @@ +package lotto.view; + +import lotto.lotto.model.LottoOutputModel; +import lotto.lotto.model.StatusOutputModel; + +import java.util.List; + +public class UserOutput { + + private UserOutput() { + } + + public static void printLottos(LottoOutputModel model) { + StringBuilder sb = new StringBuilder(); + sb.append(model.getLottoCount()) + .append("개를 구매했습니다.\n"); + for (List list : model.getLottoNumbers()) + sb.append(list).append("\n"); + System.out.println(sb); + } + + public static void printResult(StatusOutputModel model) { + System.out.println("당첨 통계\n" + + "---"); + System.out.println(model.getResultStr()); + } +} From 66761c9d921d688142c5a7884db4d0816def5478 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 11:15:21 +0900 Subject: [PATCH 02/15] feat: add lotto creators --- .../lotto/lottoCreator/LottoCreator.java | 8 ++++++ .../lottoCreator/ManualLottoCreator.java | 23 +++++++++++++++++ .../lottoCreator/RandomLottoCreator.java | 25 +++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 src/main/java/lotto/lotto/lottoCreator/LottoCreator.java create mode 100644 src/main/java/lotto/lotto/lottoCreator/ManualLottoCreator.java create mode 100644 src/main/java/lotto/lotto/lottoCreator/RandomLottoCreator.java diff --git a/src/main/java/lotto/lotto/lottoCreator/LottoCreator.java b/src/main/java/lotto/lotto/lottoCreator/LottoCreator.java new file mode 100644 index 0000000000..7c8b03062b --- /dev/null +++ b/src/main/java/lotto/lotto/lottoCreator/LottoCreator.java @@ -0,0 +1,8 @@ +package lotto.lotto.lottoCreator; + +import camp.nextstep.edu.missionutils.Randoms; +import lotto.lotto.Lotto; + +public interface LottoCreator { + public Lotto getLotto(int min, int max, int num); +} diff --git a/src/main/java/lotto/lotto/lottoCreator/ManualLottoCreator.java b/src/main/java/lotto/lotto/lottoCreator/ManualLottoCreator.java new file mode 100644 index 0000000000..79c4bd9b4e --- /dev/null +++ b/src/main/java/lotto/lotto/lottoCreator/ManualLottoCreator.java @@ -0,0 +1,23 @@ +package lotto.lotto.lottoCreator; + +import camp.nextstep.edu.missionutils.Randoms; +import lotto.lotto.Lotto; + +import java.util.List; + +public class ManualLottoCreator implements LottoCreator { + private List numbers; + + private ManualLottoCreator(List numbers) { + this.numbers = numbers; + } + + public static ManualLottoCreator from(List numbers) { + return new ManualLottoCreator(numbers); + } + + @Override + public Lotto getLotto(int min, int max, int num) { + return new Lotto(numbers); + } +} diff --git a/src/main/java/lotto/lotto/lottoCreator/RandomLottoCreator.java b/src/main/java/lotto/lotto/lottoCreator/RandomLottoCreator.java new file mode 100644 index 0000000000..10db4ea7ae --- /dev/null +++ b/src/main/java/lotto/lotto/lottoCreator/RandomLottoCreator.java @@ -0,0 +1,25 @@ +package lotto.lotto.lottoCreator; + +import camp.nextstep.edu.missionutils.Randoms; +import lotto.lotto.Lotto; + +import java.util.Comparator; +import java.util.List; + +public class RandomLottoCreator implements LottoCreator{ + private static final LottoCreator instance = new RandomLottoCreator(); + + private RandomLottoCreator() { + } + + public static LottoCreator from() { + return instance; + } + + @Override + public Lotto getLotto(int min, int max, int num){ + List numbers = Randoms.pickUniqueNumbersInRange(min,max,num); + numbers.sort(Comparator.naturalOrder()); + return new Lotto(numbers); + } +} From 85ecc2d75ce05af6aef71a584150b81c971eb3a2 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 11:15:34 +0900 Subject: [PATCH 03/15] feat: add output models --- .../lotto/lotto/model/LottoOutputModel.java | 21 +++++++++++++++++++ .../lotto/lotto/model/StatusOutputModel.java | 13 ++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/main/java/lotto/lotto/model/LottoOutputModel.java create mode 100644 src/main/java/lotto/lotto/model/StatusOutputModel.java diff --git a/src/main/java/lotto/lotto/model/LottoOutputModel.java b/src/main/java/lotto/lotto/model/LottoOutputModel.java new file mode 100644 index 0000000000..863ef2a394 --- /dev/null +++ b/src/main/java/lotto/lotto/model/LottoOutputModel.java @@ -0,0 +1,21 @@ +package lotto.lotto.model; + +import java.util.List; + +public class LottoOutputModel { + private final int lottoCount; + private final List> lottoNumbers; + + public LottoOutputModel(int lottoCount, List> lottoNumbers) { + this.lottoCount = lottoCount; + this.lottoNumbers = lottoNumbers; + } + + public int getLottoCount() { + return lottoCount; + } + + public List> getLottoNumbers() { + return lottoNumbers; + } +} diff --git a/src/main/java/lotto/lotto/model/StatusOutputModel.java b/src/main/java/lotto/lotto/model/StatusOutputModel.java new file mode 100644 index 0000000000..5a75d0124b --- /dev/null +++ b/src/main/java/lotto/lotto/model/StatusOutputModel.java @@ -0,0 +1,13 @@ +package lotto.lotto.model; + +public class StatusOutputModel { + private String resultStr; + + public StatusOutputModel(String resultStr) { + this.resultStr = resultStr; + } + + public String getResultStr() { + return resultStr; + } +} From a4f291370eb0df620a07e7f0bc73a843d57b54bf Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 11:15:45 +0900 Subject: [PATCH 04/15] feat: add main --- src/main/java/lotto/Application.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922ba4..bcf5546bb0 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,10 @@ package lotto; +import lotto.lotto.LottoService; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + LottoService lottoService = new LottoService(); + lottoService.run(); } } From 54b297ed25968bfe11380770588a109f817d1181 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 11:37:54 +0900 Subject: [PATCH 05/15] feat: add purchasing manual lotto --- src/main/java/lotto/lotto/LottoService.java | 23 ++++++++++++++------- src/main/java/lotto/view/UserInput.java | 17 +++++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/main/java/lotto/lotto/LottoService.java b/src/main/java/lotto/lotto/LottoService.java index d5d0ce93dd..ab7f6f8c9c 100644 --- a/src/main/java/lotto/lotto/LottoService.java +++ b/src/main/java/lotto/lotto/LottoService.java @@ -1,5 +1,6 @@ package lotto.lotto; +import lotto.lotto.lottoCreator.LottoCreator; import lotto.lotto.lottoCreator.ManualLottoCreator; import lotto.lotto.lottoCreator.RandomLottoCreator; import lotto.purchase.PurchaseService; @@ -18,13 +19,21 @@ public void run() { LottoBundle bundle = new LottoBundle(); // 구입금액 입력받기 - int cost = getNum(UserInput.getCostInput()); - int lottoNum = PurchaseService.getLottoNum(cost); - bundle.createLottos( - Stream.generate(RandomLottoCreator::from) - .limit(lottoNum) - .collect(Collectors.toList()) - ); + int lottoNum = PurchaseService.getLottoNum(getNum(UserInput.getCostInput())); + int manualNum = getNum(UserInput.getManualNumInput()); + + if (lottoNum < manualNum) + throw new IllegalArgumentException("[ERROR] 구입 가능한 로또 수를 초과하였습니다."); + List creators = Stream.generate(RandomLottoCreator::from) + .limit(lottoNum - manualNum) + .collect(Collectors.toList()); + if (manualNum != 0) { + List strList = UserInput.getManualLottoInput(manualNum); + for (String input : strList) + creators.add(ManualLottoCreator.from(getNumList(input))); + } + + bundle.createLottos(creators); // 로또 출력하기 UserOutput.printLottos(bundle.getLottosInfo()); diff --git a/src/main/java/lotto/view/UserInput.java b/src/main/java/lotto/view/UserInput.java index 51f46f99a4..965cf9c2a3 100644 --- a/src/main/java/lotto/view/UserInput.java +++ b/src/main/java/lotto/view/UserInput.java @@ -2,6 +2,9 @@ import camp.nextstep.edu.missionutils.Console; +import java.util.ArrayList; +import java.util.List; + public class UserInput { private UserInput() { @@ -12,6 +15,20 @@ public static String getCostInput() { return Console.readLine().trim(); } + public static String getManualNumInput() { + System.out.println("수동으로 구매할 로또 수를 입력해 주세요."); + return Console.readLine().trim(); + } + + public static List getManualLottoInput(int manualNum) { + System.out.println("수동으로 구매할 번호를 입력해 주세요."); + List list = new ArrayList<>(); + for (int i = 0; i < manualNum; i++) { + list.add(Console.readLine().trim()); + } + return list; + } + public static String getLottoInput(){ System.out.println("당첨 번호를 입력해 주세요."); return Console.readLine().trim(); From 2d8b6a15ccdb96f0af88756ea6f8d6591beaaa46 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 16:02:10 +0900 Subject: [PATCH 06/15] feat: use EnumMap for prize, status --- src/main/java/lotto/lotto/LottoBundle.java | 27 +++++++++++----------- src/main/java/lotto/lotto/Prize.java | 11 +++++++++ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/main/java/lotto/lotto/LottoBundle.java b/src/main/java/lotto/lotto/LottoBundle.java index 377f3586b6..3c3d9e868e 100644 --- a/src/main/java/lotto/lotto/LottoBundle.java +++ b/src/main/java/lotto/lotto/LottoBundle.java @@ -1,13 +1,12 @@ package lotto.lotto; import lotto.lotto.lottoCreator.LottoCreator; -import lotto.lotto.model.LottoOutputModel; import lotto.lotto.model.StatusOutputModel; import lotto.purchase.PurchaseService; -import lotto.view.UserOutput; import java.util.ArrayList; import java.util.List; +import java.util.Map; public class LottoBundle { private List lottos = new ArrayList<>(); @@ -66,19 +65,19 @@ public void setBonus(int bonus) { /** * 로또 출력하기 */ - public LottoOutputModel getLottosInfo() { + public List> getLottosNumList() { List> lottoNumbers = new ArrayList<>(); for (Lotto lotto : lottos) lottoNumbers.add(lotto.getNumbers()); - return new LottoOutputModel(lottos.size(), lottoNumbers); + return lottoNumbers; } /** * 당첨 통계 출력하기 */ public StatusOutputModel getResultStatus() { - int[] prizeStat = getPrizeStat(); - int totalreward = getTotalReward(prizeStat); + Map prizeMap = getPrizeStat(); + int totalreward = getTotalReward(prizeMap); double rewardPercent = PurchaseService.getRewardPercent(lottos.size(), totalreward); StringBuilder sb = new StringBuilder(); @@ -88,7 +87,7 @@ public StatusOutputModel getResultStatus() { sb.append( String.format(" (%,d원) - %d개", prize.getReward(), - prizeStat[prize.ordinal()] + prizeMap.get(prize) )); sb.append("\n"); } @@ -97,21 +96,21 @@ public StatusOutputModel getResultStatus() { return new StatusOutputModel(sb.toString()); } - public int[] getPrizeStat() { - int[] prizeStat = new int[Prize.values().length]; + public Map getPrizeStat() { + Map prizeMap = Prize.getInitializedMap(); for (Lotto lotto : lottos) { Prize prize = lotto.comparePrize(winningLotto, bonus); if (prize.isPrized()) - prizeStat[prize.ordinal()]++; + prizeMap.put(prize, prizeMap.get(prize) + 1); } - return prizeStat; + return prizeMap; } - public int getTotalReward(int[] prizeStat) { + public int getTotalReward(Map prizeMap) { int totalReward = 0; for (Prize prize : Prize.values()) { - if (prizeStat[prize.ordinal()] != 0) - totalReward += prize.getReward() * prizeStat[prize.ordinal()]; + if (prizeMap.get(prize) != 0) + totalReward += prize.getReward() * prizeMap.get(prize); } return totalReward; } diff --git a/src/main/java/lotto/lotto/Prize.java b/src/main/java/lotto/lotto/Prize.java index 762425e7ee..3a0366408c 100644 --- a/src/main/java/lotto/lotto/Prize.java +++ b/src/main/java/lotto/lotto/Prize.java @@ -1,5 +1,8 @@ package lotto.lotto; +import java.util.EnumMap; +import java.util.Map; + public enum Prize { FIFTH(true, 5, 3, false, 5000, "3개 일치"), FOURTH(true, 4, 4, false, 50000, "4개 일치"), @@ -24,6 +27,14 @@ public enum Prize { this.toString = toString; } + public static Map getInitializedMap() { + Map prizeMap = new EnumMap(Prize.class); + for( Prize key : Prize.values() ){ + prizeMap.put(key, 0); + } + return prizeMap; + } + public boolean isPrized() { return prized; } From c8a39025d0a27479c689e5c2a51c2132bf1915f8 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 16:02:35 +0900 Subject: [PATCH 07/15] feat: add creation manual&auto lotto --- src/main/java/lotto/lotto/LottoService.java | 24 ++++++++++++++------- src/main/java/lotto/view/UserInput.java | 8 +++---- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/main/java/lotto/lotto/LottoService.java b/src/main/java/lotto/lotto/LottoService.java index ab7f6f8c9c..ebc0801395 100644 --- a/src/main/java/lotto/lotto/LottoService.java +++ b/src/main/java/lotto/lotto/LottoService.java @@ -3,6 +3,7 @@ import lotto.lotto.lottoCreator.LottoCreator; import lotto.lotto.lottoCreator.ManualLottoCreator; import lotto.lotto.lottoCreator.RandomLottoCreator; +import lotto.lotto.model.LottoOutputModel; import lotto.purchase.PurchaseService; import lotto.view.UserInput; import lotto.view.UserOutput; @@ -21,12 +22,14 @@ public void run() { // 구입금액 입력받기 int lottoNum = PurchaseService.getLottoNum(getNum(UserInput.getCostInput())); int manualNum = getNum(UserInput.getManualNumInput()); - if (lottoNum < manualNum) throw new IllegalArgumentException("[ERROR] 구입 가능한 로또 수를 초과하였습니다."); + + // 자동 로또 List creators = Stream.generate(RandomLottoCreator::from) - .limit(lottoNum - manualNum) - .collect(Collectors.toList()); + .limit(lottoNum - manualNum) + .collect(Collectors.toList()); + // 수동 로또 if (manualNum != 0) { List strList = UserInput.getManualLottoInput(manualNum); for (String input : strList) @@ -36,15 +39,20 @@ public void run() { bundle.createLottos(creators); // 로또 출력하기 - UserOutput.printLottos(bundle.getLottosInfo()); + UserOutput.printLottos( + new LottoOutputModel( + lottoNum - manualNum, + manualNum, + bundle.getLottosNumList() + )); // 당첨번호 입력받기 - List winningList = getNumList(UserInput.getLottoInput()); - bundle.setWinningLotto(ManualLottoCreator.from(winningList)); + bundle.setWinningLotto( + ManualLottoCreator.from(getNumList(UserInput.getLottoInput()) + )); // 보너스번호 입력받기 - int bonus = getNum(UserInput.getBonusInput()); - bundle.setBonus(bonus); + bundle.setBonus(getNum(UserInput.getBonusInput())); // 당첨 통계 출력하기 UserOutput.printResult(bundle.getResultStatus()); diff --git a/src/main/java/lotto/view/UserInput.java b/src/main/java/lotto/view/UserInput.java index 965cf9c2a3..2073ca0716 100644 --- a/src/main/java/lotto/view/UserInput.java +++ b/src/main/java/lotto/view/UserInput.java @@ -16,12 +16,12 @@ public static String getCostInput() { } public static String getManualNumInput() { - System.out.println("수동으로 구매할 로또 수를 입력해 주세요."); + System.out.println("\n수동으로 구매할 로또 수를 입력해 주세요."); return Console.readLine().trim(); } public static List getManualLottoInput(int manualNum) { - System.out.println("수동으로 구매할 번호를 입력해 주세요."); + System.out.println("\n수동으로 구매할 번호를 입력해 주세요."); List list = new ArrayList<>(); for (int i = 0; i < manualNum; i++) { list.add(Console.readLine().trim()); @@ -29,12 +29,12 @@ public static List getManualLottoInput(int manualNum) { return list; } - public static String getLottoInput(){ + public static String getLottoInput() { System.out.println("당첨 번호를 입력해 주세요."); return Console.readLine().trim(); } - public static String getBonusInput(){ + public static String getBonusInput() { System.out.println("보너스 번호를 입력해 주세요."); return Console.readLine().trim(); } From 9852c03952bb3efdeacb3566db68fdf2ddcbc383 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 16:02:57 +0900 Subject: [PATCH 08/15] feat: edit printLottos --- src/main/java/lotto/view/UserOutput.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/lotto/view/UserOutput.java b/src/main/java/lotto/view/UserOutput.java index 78631d9a48..90fd3e7bde 100644 --- a/src/main/java/lotto/view/UserOutput.java +++ b/src/main/java/lotto/view/UserOutput.java @@ -12,7 +12,10 @@ private UserOutput() { public static void printLottos(LottoOutputModel model) { StringBuilder sb = new StringBuilder(); - sb.append(model.getLottoCount()) + sb.append("\n수동으로 "); + sb.append(model.getManualCount()) + .append("개, 자동으로 "); + sb.append(model.getAutoCount()) .append("개를 구매했습니다.\n"); for (List list : model.getLottoNumbers()) sb.append(list).append("\n"); @@ -20,7 +23,7 @@ public static void printLottos(LottoOutputModel model) { } public static void printResult(StatusOutputModel model) { - System.out.println("당첨 통계\n" + + System.out.println("\n당첨 통계\n" + "---"); System.out.println(model.getResultStr()); } From b909ad20ac8fbd517efa8188ce83349996130f86 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 16:04:52 +0900 Subject: [PATCH 09/15] feat: edit printLottos --- .../java/lotto/lotto/model/LottoOutputModel.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/lotto/lotto/model/LottoOutputModel.java b/src/main/java/lotto/lotto/model/LottoOutputModel.java index 863ef2a394..52794e3ee6 100644 --- a/src/main/java/lotto/lotto/model/LottoOutputModel.java +++ b/src/main/java/lotto/lotto/model/LottoOutputModel.java @@ -3,16 +3,22 @@ import java.util.List; public class LottoOutputModel { - private final int lottoCount; + private final int autoCount; + private final int manualCount; private final List> lottoNumbers; - public LottoOutputModel(int lottoCount, List> lottoNumbers) { - this.lottoCount = lottoCount; + public LottoOutputModel(int lottoCount, int manualCount, List> lottoNumbers) { + this.autoCount = lottoCount; + this.manualCount = manualCount; this.lottoNumbers = lottoNumbers; } - public int getLottoCount() { - return lottoCount; + public int getAutoCount() { + return autoCount; + } + + public int getManualCount() { + return manualCount; } public List> getLottoNumbers() { From dffd69c4e4848f238fbf2fca201e363beecd04f1 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 16:05:38 +0900 Subject: [PATCH 10/15] feat: delete deprecated methods --- src/main/java/lotto/lotto/LottoBundle.java | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/main/java/lotto/lotto/LottoBundle.java b/src/main/java/lotto/lotto/LottoBundle.java index 3c3d9e868e..f72a2eb9fa 100644 --- a/src/main/java/lotto/lotto/LottoBundle.java +++ b/src/main/java/lotto/lotto/LottoBundle.java @@ -13,18 +13,6 @@ public class LottoBundle { private Lotto winningLotto; private int bonus; - - /** - * lottoNum의 수만큼 새로운 로또 생성하기 - */ - // todo : deprecated - public void createLottos(int lottoNum) { - for (int i = 0; i < lottoNum; i++) { -// Lotto lotto = Lotto.newRandomLotto(); -// lottos.add(lotto); - } - } - /** * lottoNum의 수만큼 새로운 로또 생성하기 */ @@ -35,15 +23,6 @@ public void createLottos(List lottoCreators) { } } - /** - * 당첨번호 저장하기 - */ - // todo : deprecated - public void setWinningLotto(List winningNumList) { - Lotto lotto = new Lotto(winningNumList); - this.winningLotto = lotto; - } - /** * 당첨번호 저장하기 */ From 72f238dcdfbf181c364baa40a997d0117e975d9c Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 16:30:17 +0900 Subject: [PATCH 11/15] chore: edit appearences --- src/main/java/lotto/lotto/LottoBundle.java | 2 +- src/main/java/lotto/lotto/LottoService.java | 7 ++----- src/main/java/lotto/lotto/model/LottoOutputModel.java | 4 ++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/lotto/lotto/LottoBundle.java b/src/main/java/lotto/lotto/LottoBundle.java index f72a2eb9fa..ca3ede9ac7 100644 --- a/src/main/java/lotto/lotto/LottoBundle.java +++ b/src/main/java/lotto/lotto/LottoBundle.java @@ -14,7 +14,7 @@ public class LottoBundle { private int bonus; /** - * lottoNum의 수만큼 새로운 로또 생성하기 + * lottoCreators만큼 새로운 로또 생성하기 */ public void createLottos(List lottoCreators) { for (LottoCreator creator : lottoCreators) { diff --git a/src/main/java/lotto/lotto/LottoService.java b/src/main/java/lotto/lotto/LottoService.java index ebc0801395..813cee57c8 100644 --- a/src/main/java/lotto/lotto/LottoService.java +++ b/src/main/java/lotto/lotto/LottoService.java @@ -41,15 +41,12 @@ public void run() { // 로또 출력하기 UserOutput.printLottos( new LottoOutputModel( - lottoNum - manualNum, - manualNum, - bundle.getLottosNumList() + lottoNum - manualNum, manualNum, bundle.getLottosNumList() )); // 당첨번호 입력받기 bundle.setWinningLotto( - ManualLottoCreator.from(getNumList(UserInput.getLottoInput()) - )); + ManualLottoCreator.from(getNumList(UserInput.getLottoInput()))); // 보너스번호 입력받기 bundle.setBonus(getNum(UserInput.getBonusInput())); diff --git a/src/main/java/lotto/lotto/model/LottoOutputModel.java b/src/main/java/lotto/lotto/model/LottoOutputModel.java index 52794e3ee6..def54bb764 100644 --- a/src/main/java/lotto/lotto/model/LottoOutputModel.java +++ b/src/main/java/lotto/lotto/model/LottoOutputModel.java @@ -7,8 +7,8 @@ public class LottoOutputModel { private final int manualCount; private final List> lottoNumbers; - public LottoOutputModel(int lottoCount, int manualCount, List> lottoNumbers) { - this.autoCount = lottoCount; + public LottoOutputModel(int autoCount, int manualCount, List> lottoNumbers) { + this.autoCount = autoCount; this.manualCount = manualCount; this.lottoNumbers = lottoNumbers; } From e4ee5d6c47273e74a81d6039c29979babbbe869e Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 16:38:31 +0900 Subject: [PATCH 12/15] feat: edit lotto validations --- src/main/java/lotto/lotto/Lotto.java | 14 ------------- .../lottoCreator/ManualLottoCreator.java | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/main/java/lotto/lotto/Lotto.java b/src/main/java/lotto/lotto/Lotto.java index b5cae56641..8dede81df1 100644 --- a/src/main/java/lotto/lotto/Lotto.java +++ b/src/main/java/lotto/lotto/Lotto.java @@ -17,13 +17,6 @@ public class Lotto { private final List numbers; public Lotto(List numbers) { - validate(numbers); - - try { - numbers.sort(Comparator.naturalOrder()); - } catch (UnsupportedOperationException ignored) { - } - this.numbers = numbers; } @@ -35,13 +28,6 @@ public static Lotto from(LottoCreator lottoCreator) { ); } - private void validate(List numbers) { - if (numbers.size() != LOTTO_NUM_LENGTH) - throw new IllegalArgumentException("[ERROR] 숫자의 개수가 올바르지 않습니다."); - if (numbers.size() != (new HashSet<>(numbers)).size()) - throw new IllegalArgumentException("[ERROR] 숫자에 중복이 없어야 합니다."); - } - public Prize comparePrize(Lotto winningLotto, int bonus) { List list = new ArrayList<>(); list.addAll(numbers); diff --git a/src/main/java/lotto/lotto/lottoCreator/ManualLottoCreator.java b/src/main/java/lotto/lotto/lottoCreator/ManualLottoCreator.java index 79c4bd9b4e..3627cf4127 100644 --- a/src/main/java/lotto/lotto/lottoCreator/ManualLottoCreator.java +++ b/src/main/java/lotto/lotto/lottoCreator/ManualLottoCreator.java @@ -3,6 +3,7 @@ import camp.nextstep.edu.missionutils.Randoms; import lotto.lotto.Lotto; +import java.util.HashSet; import java.util.List; public class ManualLottoCreator implements LottoCreator { @@ -18,6 +19,25 @@ public static ManualLottoCreator from(List numbers) { @Override public Lotto getLotto(int min, int max, int num) { + validateLength(num); + validateDuplication(); + validateNumRange(min,max); return new Lotto(numbers); } + + private void validateLength(int length) { + if (numbers.size() != length) + throw new IllegalArgumentException("[ERROR] 숫자의 개수가 올바르지 않습니다."); + } + + private void validateDuplication() { + if (numbers.size() != (new HashSet<>(numbers)).size()) + throw new IllegalArgumentException("[ERROR] 숫자에 중복이 없어야 합니다."); + } + + private void validateNumRange(int min, int max) { + for (int n : numbers) + if (n < min || n > max) + throw new IllegalArgumentException("[ERROR] 올바른 범위 내의 숫자를 입력해주세요."); + } } From 6710f7a5db994271696ebbbb872ab9a1757cd15e Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 16:42:40 +0900 Subject: [PATCH 13/15] feat: edit purchase validations --- src/main/java/lotto/purchase/PurchaseService.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/lotto/purchase/PurchaseService.java b/src/main/java/lotto/purchase/PurchaseService.java index 8aaf074500..3f01ee8d4d 100644 --- a/src/main/java/lotto/purchase/PurchaseService.java +++ b/src/main/java/lotto/purchase/PurchaseService.java @@ -11,11 +11,8 @@ private PurchaseService() { * 텍스트 입력을 lotto 수로 변환 */ public static int getLottoNum(int cost) { - if (cost <=0 ) - throw new IllegalArgumentException("[ERROR] 1 이상의 양수를 입력해주세요"); - if (cost % PRICE_PER_LOTTO != 0) - throw new IllegalArgumentException("[ERROR] 가격의 배수에 해당하는 가격을 입력해주세요"); - + validatePositiveNum(cost); + validateDivisible(cost); return cost / PRICE_PER_LOTTO; } @@ -26,5 +23,13 @@ public static double getRewardPercent(int num, int reward){ return (double) reward / (num * PRICE_PER_LOTTO) * 100; } + private static void validatePositiveNum(int num) { + if (num <=0 ) + throw new IllegalArgumentException("[ERROR] 1 이상의 양수를 입력해주세요"); + } + private static void validateDivisible(int num) { + if (num % PRICE_PER_LOTTO != 0) + throw new IllegalArgumentException("[ERROR] 가격의 배수에 해당하는 가격을 입력해주세요"); + } } From 55db99a3fbf697ff66d9250c49c1575a9191071a Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 17:42:41 +0900 Subject: [PATCH 14/15] feat: edit winning lotto creation process, use builder pattern --- src/main/java/lotto/lotto/LottoBundle.java | 80 ++++++++++++++------- src/main/java/lotto/lotto/LottoService.java | 15 ++-- 2 files changed, 62 insertions(+), 33 deletions(-) diff --git a/src/main/java/lotto/lotto/LottoBundle.java b/src/main/java/lotto/lotto/LottoBundle.java index ca3ede9ac7..1bfea27bd5 100644 --- a/src/main/java/lotto/lotto/LottoBundle.java +++ b/src/main/java/lotto/lotto/LottoBundle.java @@ -9,36 +9,64 @@ import java.util.Map; public class LottoBundle { - private List lottos = new ArrayList<>(); - private Lotto winningLotto; - private int bonus; + private final List lottos; + private final Lotto winningLotto; + private final int bonus; - /** - * lottoCreators만큼 새로운 로또 생성하기 - */ - public void createLottos(List lottoCreators) { - for (LottoCreator creator : lottoCreators) { + private LottoBundle(Builder builder) { + this.lottos = builder.lottos; + this.winningLotto = builder.winningLotto; + this.bonus = builder.bonus; + } + + public static class Builder { + private List lottos = new ArrayList<>(); + private Lotto winningLotto; + private Integer bonus; + + public Builder() {} + + /** + * lottoCreators만큼 새로운 로또 생성하기 + */ + public Builder createLottos(List lottoCreators) { + for (LottoCreator creator : lottoCreators) { + Lotto lotto = Lotto.from(creator); + lottos.add(lotto); + } + return this; + } + + /** + * 당첨번호 저장하기 + */ + public Builder winningLotto(LottoCreator creator) { Lotto lotto = Lotto.from(creator); - lottos.add(lotto); + this.winningLotto = lotto; + if (bonus != null) + validateBonusNumber(winningLotto.getNumbers(), bonus); + return this; } - } - /** - * 당첨번호 저장하기 - */ - public void setWinningLotto(LottoCreator creator) { - Lotto lotto = Lotto.from(creator); - this.winningLotto = lotto; - } + /** + * 보너스번호 저장하기 + */ + public Builder bonus(int bonus) { + //todo : bonus 객체화하 + this.bonus = bonus; + if (winningLotto != null) + validateBonusNumber(winningLotto.getNumbers(), bonus); + return this; + } - /** - * 보너스번호 저장하기 - */ - public void setBonus(int bonus) { - if (winningLotto.contains(bonus)) { - throw new IllegalArgumentException("[ERROR] 보너스 번호와 당첨 번호에 중복이 있습니다."); + private void validateBonusNumber(List numbers, int num){ + if (numbers.contains(num)) + throw new IllegalArgumentException("[ERROR] 보너스 번호와 당첨 번호에 중복이 있습니다."); + } + + public LottoBundle build() { + return new LottoBundle(this); } - this.bonus = bonus; } /** @@ -75,7 +103,7 @@ public StatusOutputModel getResultStatus() { return new StatusOutputModel(sb.toString()); } - public Map getPrizeStat() { + private Map getPrizeStat() { Map prizeMap = Prize.getInitializedMap(); for (Lotto lotto : lottos) { Prize prize = lotto.comparePrize(winningLotto, bonus); @@ -85,7 +113,7 @@ public Map getPrizeStat() { return prizeMap; } - public int getTotalReward(Map prizeMap) { + private int getTotalReward(Map prizeMap) { int totalReward = 0; for (Prize prize : Prize.values()) { if (prizeMap.get(prize) != 0) diff --git a/src/main/java/lotto/lotto/LottoService.java b/src/main/java/lotto/lotto/LottoService.java index 813cee57c8..e873d80e04 100644 --- a/src/main/java/lotto/lotto/LottoService.java +++ b/src/main/java/lotto/lotto/LottoService.java @@ -17,9 +17,10 @@ public class LottoService { public void run() { - LottoBundle bundle = new LottoBundle(); + LottoBundle.Builder lottoBundleBuilder = new LottoBundle.Builder(); // 구입금액 입력받기 + // todo : 구입금액 객체 관리 int lottoNum = PurchaseService.getLottoNum(getNum(UserInput.getCostInput())); int manualNum = getNum(UserInput.getManualNumInput()); if (lottoNum < manualNum) @@ -36,7 +37,8 @@ public void run() { creators.add(ManualLottoCreator.from(getNumList(input))); } - bundle.createLottos(creators); + lottoBundleBuilder.createLottos(creators); + LottoBundle bundle = lottoBundleBuilder.build(); // 로또 출력하기 UserOutput.printLottos( @@ -45,11 +47,12 @@ public void run() { )); // 당첨번호 입력받기 - bundle.setWinningLotto( + lottoBundleBuilder.winningLotto( ManualLottoCreator.from(getNumList(UserInput.getLottoInput()))); // 보너스번호 입력받기 - bundle.setBonus(getNum(UserInput.getBonusInput())); + lottoBundleBuilder.bonus(getNum(UserInput.getBonusInput())); + bundle = lottoBundleBuilder.build(); // 당첨 통계 출력하기 UserOutput.printResult(bundle.getResultStatus()); @@ -57,13 +60,11 @@ public void run() { public int getNum(String input) { - int num; try { - num = Integer.parseInt(input); + return Integer.parseInt(input); } catch (NumberFormatException ne) { throw new IllegalArgumentException("[ERROR] 정수를 입력해주세요."); } - return num; } public List getNumList(String input) { From 1e073f75dd69f0e67fe3a9eac6515052ec8b9db8 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 3 Apr 2023 17:58:35 +0900 Subject: [PATCH 15/15] feat: add Bonus object --- src/main/java/lotto/lotto/Bonus.java | 18 ++++++++++++++++++ src/main/java/lotto/lotto/Lotto.java | 17 +++++++++++++++++ src/main/java/lotto/lotto/LottoBundle.java | 18 +++++++++--------- 3 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 src/main/java/lotto/lotto/Bonus.java diff --git a/src/main/java/lotto/lotto/Bonus.java b/src/main/java/lotto/lotto/Bonus.java new file mode 100644 index 0000000000..f3cf40dac0 --- /dev/null +++ b/src/main/java/lotto/lotto/Bonus.java @@ -0,0 +1,18 @@ +package lotto.lotto; + +public class Bonus { + private final int bonusNumber; + + private Bonus(int bonusNumber) { + this.bonusNumber = bonusNumber; + } + + public static Bonus from(int num, Lotto lotto) { + lotto.validateBonusNumber(num); + return new Bonus(num); + } + + public int getBonusNumber() { + return bonusNumber; + } +} diff --git a/src/main/java/lotto/lotto/Lotto.java b/src/main/java/lotto/lotto/Lotto.java index 8dede81df1..1ed7ca7c35 100644 --- a/src/main/java/lotto/lotto/Lotto.java +++ b/src/main/java/lotto/lotto/Lotto.java @@ -50,6 +50,11 @@ public Prize comparePrize(Lotto winningLotto, int bonus) { return prize; } + public void validateBonusNumber(int bonus) { + validateBonusDuplicateWithLotto(bonus); + validateBonusRange(bonus); + } + public boolean contains(int num) { return numbers.contains(num); } @@ -62,4 +67,16 @@ public String toString() { public List getNumbers() { return numbers; } + + + private void validateBonusDuplicateWithLotto(int bonus) { + if (numbers.contains(bonus)) + throw new IllegalArgumentException("[ERROR] 보너스 번호와 당첨 번호에 중복이 있습니다."); + + } + + private void validateBonusRange(int bonus) { + if (bonus < LOTTO_MIN_NUM || bonus > LOTTO_MAX_NUM) + throw new IllegalArgumentException("[ERROR] 보너스 번호와 당첨 번호에 중복이 있습니다."); + } } diff --git a/src/main/java/lotto/lotto/LottoBundle.java b/src/main/java/lotto/lotto/LottoBundle.java index 1bfea27bd5..fb2607e207 100644 --- a/src/main/java/lotto/lotto/LottoBundle.java +++ b/src/main/java/lotto/lotto/LottoBundle.java @@ -11,7 +11,7 @@ public class LottoBundle { private final List lottos; private final Lotto winningLotto; - private final int bonus; + private final Bonus bonus; private LottoBundle(Builder builder) { this.lottos = builder.lottos; @@ -22,7 +22,8 @@ private LottoBundle(Builder builder) { public static class Builder { private List lottos = new ArrayList<>(); private Lotto winningLotto; - private Integer bonus; + private Integer bonusNumber; + private Bonus bonus; public Builder() {} @@ -43,19 +44,18 @@ public Builder createLottos(List lottoCreators) { public Builder winningLotto(LottoCreator creator) { Lotto lotto = Lotto.from(creator); this.winningLotto = lotto; - if (bonus != null) - validateBonusNumber(winningLotto.getNumbers(), bonus); + if (bonusNumber != null) + bonus = Bonus.from(bonusNumber, winningLotto); return this; } /** * 보너스번호 저장하기 */ - public Builder bonus(int bonus) { - //todo : bonus 객체화하 - this.bonus = bonus; + public Builder bonus(int bonusNumber) { + this.bonusNumber = bonusNumber; if (winningLotto != null) - validateBonusNumber(winningLotto.getNumbers(), bonus); + this.bonus = Bonus.from(bonusNumber, winningLotto); return this; } @@ -106,7 +106,7 @@ public StatusOutputModel getResultStatus() { private Map getPrizeStat() { Map prizeMap = Prize.getInitializedMap(); for (Lotto lotto : lottos) { - Prize prize = lotto.comparePrize(winningLotto, bonus); + Prize prize = lotto.comparePrize(winningLotto, bonus.getBonusNumber()); if (prize.isPrized()) prizeMap.put(prize, prizeMap.get(prize) + 1); }