-
Notifications
You must be signed in to change notification settings - Fork 5
[미션 2] 로또게임 구현 완료했습니다. 리뷰 요청드립니다. #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: gooroom
Are you sure you want to change the base?
Changes from all commits
36ecf4c
ec88235
1b2f32b
1cd1b8b
2d543ac
d554f8b
d3f38c2
6ff70bb
3088140
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package lottodomain; | ||
|
|
||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import java.util.Objects; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| public class Lotto { | ||
| private List<LottoNo> lottoNos; | ||
|
|
||
| public Lotto(List<Integer> lottoNos) { | ||
| Collections.sort(lottoNos); | ||
| this.lottoNos = lottoNos.stream().map(number -> new LottoNo(number)).collect(Collectors.toList()); | ||
| } | ||
|
|
||
| public List<LottoNo> getLottoNos() { | ||
| return lottoNos; | ||
| } | ||
|
|
||
| public boolean contains(LottoNo lottoNo) { | ||
| return lottoNos.contains(lottoNo); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(Object o) { | ||
| if (this == o) { | ||
| return true; | ||
| } | ||
| if (o == null || getClass() != o.getClass()) { | ||
| return false; | ||
| } | ||
| Lotto lotto = (Lotto) o; | ||
| return Objects.equals(lottoNos, lotto.lottoNos); | ||
| } | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package lottodomain; | ||
|
|
||
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| public class LottoAnalyzer { | ||
| private static final int PRICE_PER_LOTTO = 1000; | ||
| private static final int PERCENTAGE = 100; | ||
|
|
||
| private List<Lotto> lottos; | ||
| private List<WinningLotto> winningLottos; | ||
|
|
||
| public LottoAnalyzer(List<Lotto> lottos, WinningNos winningNos) { | ||
| this.lottos = lottos; | ||
| winningLottos = lottos.stream().map(lotto -> new WinningLotto(lotto, calculateRankOfLotto(lotto, winningNos))) | ||
| .collect(Collectors.toList()); | ||
| } | ||
|
|
||
| public Rank calculateRankOfLotto(Lotto lotto, WinningNos winningNos) { | ||
| int countOfMatch = winningNos.countMatchOf(lotto); | ||
| boolean matchBonus = winningNos.isBonus(lotto); | ||
| return Rank.valueOf(countOfMatch, matchBonus); | ||
| } | ||
|
|
||
| public double calculateEarningRate() { | ||
| int inputMoney = lottos.size() * PRICE_PER_LOTTO; | ||
| double earnedMoney = calculateEarnedMoney(); | ||
| return Math.round(earnedMoney / inputMoney * PERCENTAGE * 10) / 10.0; | ||
| } | ||
|
|
||
| public int calculateEarnedMoney() { | ||
| List<Integer> winningMoneys = winningLottos.stream() | ||
| .map(winningLotto -> winningLotto.getLottoPrize().getWinningMoney()) | ||
| .collect(Collectors.toList()); | ||
| return winningMoneys.stream().reduce(0, (accumulation, current) -> accumulation + current); | ||
| } | ||
|
|
||
| public int countRank(Rank findingRank) { | ||
| return (int) winningLottos.stream().map(WinningLotto::getLottoPrize) | ||
| .filter(rank -> rank.equals(findingRank)).count(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| package lottodomain; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class LottoGame { | ||
| private static final int PRICE_PER_LOTTO = 1000; | ||
|
|
||
| private List<Lotto> allLotto; | ||
| private int numberOfAllLotto; | ||
|
|
||
| public LottoGame(int inputMoney, List<List<Integer>> manualLottoNos) { | ||
| numberOfAllLotto = inputMoney / PRICE_PER_LOTTO; | ||
| allLotto = issueLottos(manualLottoNos); | ||
| } | ||
|
|
||
| public LottoAnalyzer getLottoAnalyzer(WinningNos winningNos) { | ||
| return new LottoAnalyzer(allLotto, winningNos); | ||
| } | ||
|
|
||
| public List<Lotto> getAllLotto() { | ||
| return allLotto; | ||
| } | ||
|
|
||
| private List<Lotto> issueLottos(List<List<Integer>> manualLottoNos) { | ||
| List<Lotto> lottos = issueManualLottos(manualLottoNos); | ||
| lottos.addAll(issueAutoLottos(numberOfAllLotto - lottos.size())); | ||
| return lottos; | ||
| } | ||
|
|
||
| private List<Lotto> issueManualLottos(List<List<Integer>> manualLottoNos) { | ||
| List<Lotto> ManualLottos = new ArrayList<>(); | ||
| for (int i = 0; i < manualLottoNos.size(); i++) { | ||
| ManualLottos.add(LottoGenerator.generateLottoWithNos(manualLottoNos.get(i))); | ||
| } | ||
| return ManualLottos; | ||
| } | ||
|
|
||
| private List<Lotto> issueAutoLottos(int numberOfAutoLottos) { | ||
| List<Lotto> autoLottos = new ArrayList<>(); | ||
| for (int i = 0; i < numberOfAutoLottos; i++) { | ||
| autoLottos.add(LottoGenerator.generateAutoLotto()); | ||
| } | ||
| return autoLottos; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| package lottodomain; | ||
|
|
||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
| import java.util.stream.IntStream; | ||
|
|
||
| public class LottoGenerator { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lotto 에 factory method 을 추가하여 생성해보면 어떨까요? |
||
| private static final List<Integer> LOTTO_NO_POOLS = IntStream.rangeClosed(1, 45).boxed().collect(Collectors.toList()); | ||
| ; | ||
|
|
||
| public static Lotto generateLottoWithNos(List<Integer> lottoNos) { | ||
| return new Lotto(lottoNos); | ||
| } | ||
|
|
||
| public static Lotto generateAutoLotto() { | ||
| return generateLottoWithNos(getRandomNos()); | ||
| } | ||
|
|
||
|
|
||
| private static List<Integer> getRandomNos() { | ||
| Collections.shuffle(LOTTO_NO_POOLS); | ||
| return LOTTO_NO_POOLS.subList(0, 6); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| package lottodomain; | ||
|
|
||
| public class LottoNo { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 문제 : 위와 같은 문제는 어떻게 해결할 수 있을까요? (키워드 : static, map) |
||
| private Integer value; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 불변의 값을 wrapping 한 클래스이므로 final int value; 로 선언해보면 어떨까요? |
||
|
|
||
| public LottoNo(int number) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LottoNo 를 생성할 때 range 에 대한 조건을 검증하면 좀 더 의미 있는 wrapping class 가 되지 않을까요? |
||
| value = number; | ||
| } | ||
|
|
||
| public Integer getValue() { | ||
| return value; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(Object o) { | ||
| if (this == o) { | ||
| return true; | ||
| } | ||
| if (o == null || getClass() != o.getClass()) { | ||
| return false; | ||
| } | ||
| LottoNo lottoNo = (LottoNo) o; | ||
| return value == lottoNo.value; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package lottodomain; | ||
|
|
||
| import lottoview.InputView; | ||
| import lottoview.OutputView; | ||
| import java.util.List; | ||
| import java.util.Scanner; | ||
|
|
||
| public class Main { | ||
| public static void main(String[] args) { | ||
| try { | ||
| Scanner scanner = new Scanner(System.in); | ||
| int payment = InputView.askPayment(scanner); | ||
| int numberOfManualLottos = InputView.askNumberOfManualLottos(scanner); | ||
| List<List<Integer>> manualNumbers = InputView.askManualLottoNos(scanner, numberOfManualLottos); | ||
|
|
||
| LottoGame lottoGame = new LottoGame(payment, manualNumbers); | ||
| OutputView.showAllLottos(lottoGame.getAllLotto(), numberOfManualLottos); | ||
|
|
||
| WinningNos winningNos = new WinningNos( | ||
| InputView.askWinningNos(scanner), InputView.askBonusNo(scanner) | ||
| ); | ||
| LottoAnalyzer lottoAnalyzer = lottoGame.getLottoAnalyzer(winningNos); | ||
| OutputView.showAnalysis(lottoAnalyzer); | ||
| } catch (Exception e) { | ||
| e.printStackTrace(); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package lottodomain; | ||
|
|
||
| import java.util.*; | ||
| import java.util.function.Function; | ||
| import java.util.stream.Collectors; | ||
| import java.util.stream.Stream; | ||
|
|
||
| public enum Rank { | ||
| FIRST(6, 2000000000), | ||
| SECOND(5, 30000000), | ||
| THIRD(5, 1500000), | ||
| FOURTH(4, 50000), | ||
| FIFTH(3, 5000), | ||
| MISS(0, 0); | ||
|
|
||
| private int countOfMatch; | ||
| private int winningMoney; | ||
|
|
||
| private Rank(int countOfMatch, int winningMoney) { | ||
| this.countOfMatch = countOfMatch; | ||
| this.winningMoney = winningMoney; | ||
| } | ||
|
|
||
| public int getCountOfMatch() { | ||
| return countOfMatch; | ||
| } | ||
|
|
||
| public int getWinningMoney() { | ||
| return winningMoney; | ||
| } | ||
|
|
||
| public static Rank valueOf(int countOfMatch, boolean matchBonus) { | ||
| if (countOfMatch == 5 && matchBonus) { | ||
| return SECOND; | ||
| } | ||
| Map<Integer, Rank> countOfMatchRankMapWithoutSecond = Stream.of(values()).filter(rank -> rank != SECOND) | ||
| .collect(Collectors.toMap(Rank::getCountOfMatch, Function.identity())); | ||
| Rank result = countOfMatchRankMapWithoutSecond.get(countOfMatch); | ||
| if (result == null) { | ||
| result = MISS; | ||
| } | ||
| return result; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package lottodomain; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class WinningLotto { | ||
| private List<LottoNo> lottoNos; | ||
| private Rank lottoPrize; | ||
|
|
||
| public WinningLotto(Lotto lotto, Rank lottoPrize) { | ||
| lottoNos = lotto.getLottoNos(); | ||
| this.lottoPrize = lottoPrize; | ||
| } | ||
|
|
||
| public List<LottoNo> getLottoNos() { | ||
| return lottoNos; | ||
| } | ||
|
|
||
| public Rank getLottoPrize() { | ||
| return lottoPrize; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package lottodomain; | ||
|
|
||
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| public class WinningNos { | ||
| private List<LottoNo> winningNos; | ||
| private LottoNo bonusNo; | ||
|
|
||
| public WinningNos(List<Integer> winningNos, int bonusNo) { | ||
| this.winningNos = winningNos.stream().map(number -> new LottoNo(number)) | ||
| .collect(Collectors.toList()); | ||
| this.bonusNo = new LottoNo(bonusNo); | ||
| } | ||
|
|
||
| public int countMatchOf(Lotto lotto) { | ||
| return winningNos.stream().filter(lotto::contains).collect(Collectors.toList()).size(); | ||
| } | ||
|
|
||
| public boolean isBonus(Lotto lotto) { | ||
| return lotto.contains(bonusNo); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package lottoview; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class InputValidation { | ||
| private final static int NUMBER_OF_LOTTO_NOS = 6; | ||
| private final static int PRICE_PER_LOTTO = 1000; | ||
|
|
||
| public static void validatePayment(int payment) throws ViewException { | ||
| if (payment < PRICE_PER_LOTTO) { | ||
| throw new ViewException("[ViewException] 구입금액은 1000원 이상이어야 합니다"); | ||
| } | ||
| if (payment % PRICE_PER_LOTTO != 0) { | ||
| throw new ViewException("[ViewException] 구입금액은 1000원단위로 입력해주세요"); | ||
| } | ||
| } | ||
|
|
||
| public static void validateNumberOfLottos(int numberOfLottos) throws ViewException { | ||
| if (numberOfLottos < 0) { | ||
| throw new ViewException("[ViewException] 로또의 수는 0이상이어야 합니다"); | ||
| } | ||
| } | ||
|
|
||
| public static void validateAllLottoNos(List<List<Integer>> lottoNos) throws ViewException { | ||
| for (List<Integer> lottoNo : lottoNos) { | ||
| validateLottoNos(lottoNo); | ||
| } | ||
| } | ||
|
|
||
| public static void validateLottoNos(List<Integer> lottoNos) throws ViewException { | ||
| if (lottoNos.size() != NUMBER_OF_LOTTO_NOS) { | ||
| throw new ViewException("[ViewException] 로또 번호는 6자리 입니다"); | ||
| } | ||
| for (int number : lottoNos) { | ||
| validateNoRange(number); | ||
| } | ||
| } | ||
|
|
||
| public static void validateNoRange(int number) throws ViewException { | ||
| if (number <= 0 || number > 45) { | ||
| throw new ViewException("[ViewException] 로또 번호는 1 ~ 45 범위 내의 숫자입니다"); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
변수명이 대문자로 시작하네요 ~