-
Notifications
You must be signed in to change notification settings - Fork 5
[로또] 김민정 미션 제출합니다. #4
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: monsteralover
Are you sure you want to change the base?
Changes from all commits
a80f8cd
649320b
f643205
ed34f0e
9e9763f
515da10
8c444b4
b6fa070
0a1d52f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,32 @@ | ||
| # java-lotto | ||
|
|
||
| 로또 미션 저장소 | ||
|
|
||
| # [미션 리드미](https://github.com/talmood/private-mission-README/tree/main/%EB%AF%B8%EC%85%98%203%20-%20%EB%A1%9C%EB%98%90) | ||
|
|
||
|
|
||
| # 기능 목록 정리 | ||
|
|
||
| ## 입력 | ||
| * 값을 입력받을 수 있도록 한다. | ||
| * 구매 금액, 당첨 번호, 보너스 볼 | ||
|
|
||
| ## 출력 | ||
| * 값을 출력하도록 한다. | ||
|
|
||
| ## 로또 생성 | ||
| * 구매 금액을 받아서 몇 개의 로또를 생성할지 계산한다. | ||
| * 로또 번호를 생성한다. | ||
| * 1부터 45중 6개로 구성 | ||
|
|
||
| ## 당첨 조회 | ||
| * 당첨 여부를 조회한다. | ||
|
|
||
|
|
||
| ## 당첨 통계 | ||
| * 일치하는 번호의 수 별로 통계를 구한다. | ||
| * 3개~6개까지 일치하는 경우, 5개 + 보너스 볼 일치 | ||
| * 수익률 계산 | ||
| * 3개 일치 5000원 | ||
| * 4개 일치 5000원 | ||
| * 5개 일치 150000원 | ||
| * 5개+보너스볼 30000000원 | ||
| * 6개 일치 2000000000원 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| public class Application { | ||
| public static void main(String[] args) { | ||
| LottoProcessor lottoProcessor = new LottoProcessor(new InputView(), new ResultView()); | ||
| lottoProcessor.processGame(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| public class GameCountDecider { | ||
|
|
||
| static final Integer LOTTO_PRICE = 1000; | ||
| public Integer calculateGameForPrice(Integer price) { | ||
| return price/LOTTO_PRICE; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import java.util.Scanner; | ||
|
|
||
| public class InputView { | ||
| Scanner scanner = new Scanner(System.in); | ||
|
|
||
| public void guideToPutPurchasePrice() { | ||
| System.out.println("구매금액을 입력해주세요"); | ||
| } | ||
| public void guideToPutWinningNumbers() { | ||
| System.out.println("지난 주 당첨 번호를 입력해 주세요."); | ||
| } | ||
|
|
||
| public void guideToPutBonusNumber() { | ||
| System.out.println("보너스 볼을 입력해 주세요."); | ||
| } | ||
|
|
||
| public String acceptInput() { | ||
| return scanner.nextLine(); | ||
| } | ||
|
|
||
| public Integer validatePurchasePrice(String input) { | ||
| try { | ||
| return Integer.parseInt(input); | ||
| } catch (NumberFormatException e) { | ||
| System.out.println("숫자를 입력해주세요"); | ||
| return null; | ||
| } | ||
| } | ||
|
Comment on lines
+21
to
+28
Member
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. 요 메서드는 네이밍만 보면 구매 금액에 대해 validate를 해준다는 의미인 것 같은데 실제로는 null을 반환하고 있고 해당 메서드를 호출하는 외부에서 null에 대해서 do while 문으로 처리를 해주고 있어요~ validate를 하고자 한다면 유효성 검사 후 Exception을 발생시켜 외부에서는 해당 Exception에 대해 처리하도록 하는 건 어떨까요? 추가로 validate 역할을 수행하는 Validator 객체를 만들어 해당 객체에서 처리하도록 하는 것도 고려해보셨으면 해요😄 |
||
|
|
||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
|
|
||
| public class Lotto { | ||
|
|
||
| public void setLottoGames(List<LottoGame> lottoGames) { | ||
| LottoGames = lottoGames; | ||
| } | ||
|
|
||
| List<LottoGame> LottoGames; | ||
|
|
||
| public List<LottoGame> getLottoGames() { | ||
| return new ArrayList<>(LottoGames); | ||
| } | ||
|
|
||
| public Lotto(Integer gameCount) { | ||
| this.LottoGames = new ArrayList<>(); | ||
| for (int i = 0; i < gameCount; i++) { | ||
| LottoGame lottoGame = createLottoGame(); | ||
| this.LottoGames.add(lottoGame); | ||
| } | ||
| } | ||
|
|
||
| private LottoGame createLottoGame() { | ||
| int minimumLottoValue = 1; | ||
| int maximumLottoValue = 46; | ||
| int lottoNumberCount = 6; | ||
|
Comment on lines
+26
to
+28
Member
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 라는 도메인에서 종속된 값이기 때문에 Lotto 객체에서 상수로 가지고 있어도 무방할 값으로 보여요! |
||
| List<Integer> potentialLottoNumbers = new ArrayList<>(); | ||
| for (int i = minimumLottoValue; i <= maximumLottoValue; i++) { | ||
| potentialLottoNumbers.add(i); | ||
| } | ||
| Collections.shuffle(potentialLottoNumbers); | ||
| List<Integer> gameNumbers = new ArrayList<>(potentialLottoNumbers.subList(0, lottoNumberCount)); | ||
| Collections.sort(gameNumbers); | ||
|
|
||
| return new LottoGame(gameNumbers); | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class LottoGame { | ||
| private final List<Integer> gameNumbers; | ||
|
|
||
| public LottoGame(List<Integer> gameNumbers) { | ||
| this.gameNumbers = new ArrayList<>(gameNumbers); | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return gameNumbers.toString(); | ||
| } | ||
|
Comment on lines
+11
to
+14
Member
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. 혹시 해당 |
||
|
|
||
| public List<Integer> getGameNumbers() { | ||
| return gameNumbers; | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| import java.util.Arrays; | ||
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| public class LottoProcessor { | ||
|
Member
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. LottoProcessor 객체에서 정의해주고 있는 public 메서드가 5개로 은근 많은 역할을 수행하고 있어보여요~! |
||
|
|
||
| private final InputView inputView; | ||
|
|
||
| private final ResultView resultView; | ||
|
|
||
| public LottoProcessor(InputView inputView, ResultView resultView) { | ||
| this.inputView = inputView; | ||
| this.resultView = resultView; | ||
| } | ||
|
|
||
| public void processGame() { | ||
|
|
||
| Integer price = acceptPriceForLottoGame(); | ||
| Integer gameCount = purchaseGamesByPrice(price); | ||
|
Comment on lines
+18
to
+19
Member
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. Integer를 사용하고 있어 최종적으로 |
||
| Lotto lotto = createLottoByGameCount(gameCount); | ||
| WinningLottoNumber winningLottoNumber = acceptWinningNumbers(); | ||
| Winners winners = selectWinners(lotto, winningLottoNumber); | ||
| showWinnerStatistics(winners, price); | ||
| } | ||
|
|
||
| private void showWinnerStatistics(Winners winners, Integer price) { | ||
| resultView.printWinnerStatisticsMessage(); | ||
| ProfitCalculator profitCalculator = new ProfitCalculator(winners, price); | ||
| resultView.printWinnerStatistics(winners, profitCalculator); | ||
| } | ||
|
|
||
|
|
||
| public Lotto createLottoByGameCount(Integer gameCount) { | ||
| Lotto lotto = new Lotto(gameCount); | ||
| resultView.printLottoGameNumbers(lotto); | ||
| return lotto; | ||
| } | ||
|
|
||
| public Integer purchaseGamesByPrice(Integer price) { | ||
| GameCountDecider gameCountDecider = new GameCountDecider(); | ||
| Integer gameCount = gameCountDecider.calculateGameForPrice(price); | ||
| resultView.printPurchasedGameCount(gameCount); | ||
|
|
||
| return gameCount; | ||
| } | ||
|
|
||
| private int acceptPriceForLottoGame() { | ||
| inputView.guideToPutPurchasePrice(); | ||
| Integer price; | ||
|
|
||
| do { | ||
| String stringInput = inputView.acceptInput(); | ||
| price = inputView.validatePurchasePrice(stringInput); | ||
| } while (price == null); | ||
|
|
||
| return price; | ||
| } | ||
|
|
||
| private WinningLottoNumber acceptWinningNumbers() { | ||
| inputView.guideToPutWinningNumbers(); | ||
| String stringWinningNumbers = inputView.acceptInput(); | ||
| List<Integer> winningNumbers = Arrays.stream(stringWinningNumbers.split(",")) | ||
| .map(String::trim) | ||
|
Member
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.
|
||
| .map(Integer::parseInt).collect(Collectors.toList()); | ||
|
|
||
| inputView.guideToPutBonusNumber(); | ||
| int bonusNumber = Integer.parseInt(inputView.acceptInput()); | ||
|
|
||
| return new WinningLottoNumber(winningNumbers, bonusNumber); | ||
| } | ||
|
|
||
| public Winners selectWinners(Lotto lotto, WinningLottoNumber winningLottoNumber) { | ||
| WinnerSelector winnerSelector = new WinnerSelector(lotto, winningLottoNumber); | ||
| return winnerSelector.getWinners(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| public class ProfitCalculator { | ||
|
|
||
| final static Integer FIRST_PRIZE = 2000000000; | ||
| final static Integer SECOND_PRIZE = 30000000; | ||
| final static Integer THIRD_PRIZE = 1500000; | ||
| final static Integer FOURTH_PRIZE = 50000; | ||
| final static Integer FIFTH_PRIZE = 5000; | ||
|
Comment on lines
+3
to
+7
Member
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. 등수에 대한 내용과 상금에 대한 값을 Enum으로 정의해서 처리해볼 수도 있을 것 같아요! |
||
|
|
||
| private float profit = 0; | ||
|
|
||
| public ProfitCalculator(Winners winners, Integer investMoney) { | ||
| Integer totalWinningMoney = | ||
| winners.getFirstWinner() * FIRST_PRIZE | ||
| + winners.getSecondWinner() * SECOND_PRIZE | ||
| + winners.getThirdWinner() * THIRD_PRIZE | ||
| + winners.getFourthWinner() * FOURTH_PRIZE | ||
| + winners.getFifthWinner() * FIFTH_PRIZE; | ||
|
|
||
| this.profit = totalWinningMoney.floatValue() / investMoney.floatValue(); | ||
| } | ||
|
|
||
| public float getProfit() { | ||
| return profit; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import java.util.List; | ||
|
|
||
| public class ResultView { | ||
| public void printPurchasedGameCount(Integer gameCount) { | ||
| System.out.println(gameCount + "개를 구매했습니다."); | ||
| } | ||
|
|
||
| public void printLottoGameNumbers(Lotto lotto) { | ||
| List<LottoGame> lottoGames = lotto.getLottoGames(); | ||
| for (int i = 0; i < lottoGames .size(); i++) { | ||
| System.out.println(lottoGames.get(i)); | ||
| } | ||
| } | ||
|
|
||
| public void printWinnerStatisticsMessage() { | ||
| System.out.println("당첨 통계"); | ||
| System.out.println("---------"); | ||
| } | ||
|
|
||
| public void printWinnerStatistics(Winners winners, ProfitCalculator profitCalculator) { | ||
| float profit = profitCalculator.getProfit(); | ||
|
|
||
| System.out.println("3개 일치 (" + profitCalculator.FIFTH_PRIZE + "원)- " + winners.getFifthWinner()+"개"); | ||
| System.out.println("4개 일치 (" + profitCalculator.FOURTH_PRIZE + "원)- " + winners.getFourthWinner()+"개"); | ||
| System.out.println("5개 일치 (" + profitCalculator.THIRD_PRIZE + "원)- " + winners.getThirdWinner()+"개"); | ||
| System.out.println("5개 일치, 보너스 볼 일치 (" + profitCalculator.SECOND_PRIZE + "원)- " + winners.getSecondWinner()+"개"); | ||
| System.out.println("6개 일치 (" + profitCalculator.FIRST_PRIZE + "원)- " + winners.getFirstWinner()+"개"); | ||
|
Comment on lines
+23
to
+27
Member
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. 위 ProfitCalculator 객체에 단 리뷰에서처럼 등수에 대한 내용을 Enum으로 관리한다면 각 등수 별 일치 메세지도 담아서 처리해줄 수 있을 것 같아요~😄 |
||
| System.out.println("profit = " + profit); | ||
| System.out.println(String.format("총 수익률은 %.2f 입니다.", profit)); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| import java.util.List; | ||
|
|
||
| public class WinnerSelector { | ||
|
Member
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. 해당 객체에서도 등수를 계산하기 위해 각각의 로또 번호의 매칭된 카운트를 직접 계산해주고 있는데, 이 부분도 Enum에서 매칭 카운트 값을 등수 값과 함께 관리하고 있다면 더 용이하게 구현해볼 수 있을 것 같아요! |
||
| private final Winners winners; | ||
|
|
||
| public Winners getWinners() { | ||
| return winners; | ||
| } | ||
|
|
||
| public WinnerSelector(Lotto lotto, WinningLottoNumber winningLottoNumber) { | ||
| int firstWinner = 0; | ||
| int secondWinner = 0; | ||
| int thirdWinner = 0; | ||
| int fourthWinner = 0; | ||
| int fifthWinner = 0; | ||
|
Comment on lines
+11
to
+15
Member
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. 최대한 불변 변수를 사용해서 값을 구해보는 걸 추천드릴게요! 이는 내 코드가 그렇게 이상한가요? 도서에 4장. 불변 활용하기 장에서 자세한 내용을 다루고 있습니다! |
||
|
|
||
| List<Integer> winningNumbers = winningLottoNumber.getWinningNumbers(); | ||
| Integer bonusNumber = winningLottoNumber.getBonusNumber(); | ||
|
|
||
| for (LottoGame lottoGame : lotto.getLottoGames()) { | ||
| Integer matchCount = 0; | ||
|
|
||
| List<Integer> gameNumbers = lottoGame.getGameNumbers(); | ||
| matchCount = findWinningNumberInGameNumber(matchCount, winningNumbers, gameNumbers); | ||
|
|
||
| firstWinner = getFirstWinner(firstWinner, matchCount); | ||
| secondWinner = getSecondWinner(secondWinner, bonusNumber, matchCount, gameNumbers); | ||
| thirdWinner = getThirdWinner(thirdWinner, bonusNumber, matchCount, gameNumbers); | ||
| fourthWinner = getFourthWinner(fourthWinner, matchCount); | ||
| fifthWinner = getFifthWinner(fifthWinner, matchCount); | ||
| } | ||
| this.winners = new Winners(firstWinner, secondWinner, thirdWinner, fourthWinner, fifthWinner); | ||
| } | ||
|
|
||
| private int getFifthWinner(int fifthWinner, Integer matchCount) { | ||
| if (matchCount == 3) { | ||
| fifthWinner++; | ||
| } | ||
| return fifthWinner; | ||
| } | ||
|
|
||
| private int getFourthWinner(int fourthWinner, Integer matchCount) { | ||
| if (matchCount == 4) { | ||
| fourthWinner++; | ||
| } | ||
| return fourthWinner; | ||
| } | ||
|
|
||
| private int getThirdWinner(int thirdWinner, Integer bonusNumber, Integer matchCount, List<Integer> gameNumbers) { | ||
| if (matchCount == 5 && !isBonusNumberMatch(gameNumbers, bonusNumber)) { | ||
| thirdWinner++; | ||
| } | ||
| return thirdWinner; | ||
| } | ||
|
|
||
| private int getSecondWinner(int secondWinner, Integer bonusNumber, Integer matchCount, List<Integer> gameNumbers) { | ||
| if (matchCount == 5 && isBonusNumberMatch(gameNumbers, bonusNumber)) { | ||
| secondWinner++; | ||
| } | ||
| return secondWinner; | ||
| } | ||
|
|
||
| private int getFirstWinner(int firstWinner, Integer matchCount) { | ||
| if (matchCount == 6) { | ||
| firstWinner++; | ||
| } | ||
| return firstWinner; | ||
| } | ||
|
|
||
|
|
||
| private boolean isBonusNumberMatch(List<Integer> gameNumbers, Integer bonusNumber) { | ||
| return gameNumbers.contains(bonusNumber); | ||
| } | ||
|
|
||
| private Integer findWinningNumberInGameNumber(Integer matchCount, List<Integer> winningNumbers, List<Integer> gameNumbers) { | ||
| for (Integer number : gameNumbers) { | ||
| matchCount = increaseMatchCountIfIncludeGameNumber(matchCount, winningNumbers, number); | ||
| } | ||
| return matchCount; | ||
| } | ||
|
|
||
| private Integer increaseMatchCountIfIncludeGameNumber(Integer matchCount, List<Integer> winningNumbers, Integer number) { | ||
| if (winningNumbers.contains(number)) { | ||
| matchCount++; | ||
| } | ||
| return matchCount; | ||
| } | ||
|
|
||
| } | ||
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.
LOTTO_PRICE 상수를 같은 패키지에서 사용하지 않을거라면 private 접근제어자로 정의해주는 게 좋을 것 같은데 어떻게 생각하시나요?