-
Notifications
You must be signed in to change notification settings - Fork 4
[java-lotto] roki.kim(김경록) 과제 제출합니다. #1
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: main
Are you sure you want to change the base?
Changes from 2 commits
fd81ecc
7ed040a
bf9e5e1
a36a901
84914ca
041f272
a33f8fb
1724cd3
3dba30e
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 |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| # 기능 목록 | ||
| + 각 기능에 대한 예외사항과 핸들링도 기재 | ||
|
|
||
| - [ ] 게임 관리 - GameManager class | ||
| - [ ] 게임 시작 - start() | ||
| - [ ] 로또 게임 구현 - LottoGame class | ||
| - [ ] 6개의 숫자 생성 **(Computer)** - generateLottoNumber() | ||
| - [ ] 로또 구입 금액 입력 받기 **(Me)** - receiveUserMoneyInput() | ||
| - [ ] **예외사항** : 1000원으로 나누어 떨어지지 않는 경우 -> `IllegalArgumentException` | ||
| - [ ] 당첨 번호 입력 받기 **(Me)** - receiveUserNumberInput() | ||
| - [ ] **예외사항** : 쉼표를 기준으로 구분하지 않은 경우 -> `IllegalArgumentException` | ||
| - [ ] **예외사항** : 로또 번호의 숫자 범위 밖의 경우 (1 ~ 45) -> `IllegalArgumentException` | ||
| - [ ] **예외사항** : 숫자가 중복되는 경우 -> `IllegalArgumentException` | ||
| - [ ] 보너스 번호 입력 받기 **(Me)** - receiveUserBonusInput() | ||
| - [ ] **예외사항** : 로또 번호의 숫자 범위 밖의 경우 (1 ~ 45) -> `IllegalArgumentException` | ||
| - [ ] **예외사항** : 숫자가 중복되는 경우 -> `IllegalArgumentException` | ||
| - [ ] 발행한 로또 수량 및 번호를 오름차순으로 출력 - issuanceLotto() | ||
| - [ ] 당첨 내역 출력 - printWinningDetails() | ||
| - [ ] 수익률 계산 (소수점 둘째 자리 반올림) - calculateRateOfProfit() | ||
|
|
||
| ------- | ||
|
|
||
| * 당첨 번호와 보너스 번호를 입력하는 기능을 분리하는게 좋을까? | ||
| * 가독성을 위해 분리하는 방향으로 선택 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| package lotto; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class GameManager { | ||
| private final LottoInputView lottoInputView; | ||
| private final LottoService lottoService; | ||
| private final LottoOutputView lottoOutputView; | ||
|
|
||
| public GameManager() { | ||
| this.lottoService = new LottoService(); | ||
| this.lottoOutputView = new LottoOutputView(); | ||
| this.lottoInputView = new LottoInputView(); | ||
| } | ||
|
|
||
| /** | ||
| * 게임 시작 | ||
| */ | ||
| public void start() { | ||
| int money = lottoInputView.receiveUserMoneyInput(); | ||
| List<Lotto> lottoList = lottoService.generateLottoNumber(money / 1000); | ||
| lottoOutputView.printLotto(lottoList); | ||
|
|
||
| List<Integer> winningNumbers = lottoInputView.receiveWinningNumberInput(); | ||
| int bonusNumber = lottoInputView.receiveBonusNumberInput(winningNumbers); | ||
|
|
||
| LottoResult result = lottoService.checkWinningResult(lottoList, winningNumbers, bonusNumber); | ||
| lottoOutputView.printWinningStatistics(result); | ||
|
|
||
| double profitRate = lottoService.calculateProfitRate(money, result); | ||
| lottoOutputView.printProfitRate(profitRate); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| package lotto; | ||
|
|
||
| import camp.nextstep.edu.missionutils.Console; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| public class LottoInputView { | ||
|
|
||
| /** | ||
| * 로또 구입 금액 입력 받기 | ||
| */ | ||
| public int receiveUserMoneyInput() { | ||
| System.out.println("구입금액을 입력해 주세요."); | ||
| String input = Console.readLine(); | ||
| validateMoneyInput(input); | ||
| return Integer.parseInt(input); | ||
| } | ||
|
|
||
| private void validateMoneyInput(String input) { | ||
|
||
| try { | ||
| int money = Integer.parseInt(input); | ||
| if (money % 1000 != 0) { | ||
| throw new IllegalArgumentException("[ERROR] 구입 금액은 1,000원 단위여야 합니다."); | ||
| } | ||
| } catch (NumberFormatException e) { //숫자가 아닐 경우 | ||
| throw new IllegalArgumentException("[ERROR] 올바른 숫자를 입력하세요."); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * 당첨 번호 입력 받기 | ||
| */ | ||
| public List<Integer> receiveWinningNumberInput() { | ||
| System.out.println("당첨 번호를 입력해 주세요."); | ||
| String input = Console.readLine(); | ||
| List<Integer> numbers = parseNumbers(input); | ||
| validateNumbers(numbers); | ||
| return numbers; | ||
| } | ||
|
|
||
| private void validateNumbers(List<Integer> numbers) { | ||
| if (numbers.size() != 6) { | ||
| throw new IllegalArgumentException("[ERROR] 당첨 번호는 6개여야 합니다."); | ||
| } | ||
| if (numbers.stream().distinct().count() != 6) { | ||
| throw new IllegalArgumentException("[ERROR] 당첨 번호에 중복된 숫자가 있습니다."); | ||
| } | ||
| if (numbers.stream().anyMatch(n -> n < 1 || n > 45)) { | ||
| throw new IllegalArgumentException("[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다."); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * 입력 정수 리스트로 변환 | ||
| */ | ||
| private List<Integer> parseNumbers(String input) { | ||
| return Arrays.stream(input.split(",")) | ||
| .map(String::trim) //스페이스 제거 | ||
| .map(Integer::parseInt) //정수 변환 | ||
| .collect(Collectors.toList()); | ||
| } | ||
|
|
||
|
|
||
| public int receiveBonusNumberInput(List<Integer> winningList) { | ||
| System.out.println("보너스 번호를 입력해 주세요."); | ||
| String input = Console.readLine(); | ||
| int result = Integer.parseInt(input); | ||
| validateBonusNumber(result, winningList); | ||
| return result; | ||
| } | ||
|
|
||
| private void validateBonusNumber(int bonusNumber, List<Integer> winningList) { | ||
| if (bonusNumber < 1 || bonusNumber > 45) { | ||
| throw new IllegalArgumentException("[ERROR] 보너스 번호는 1부터 45 사이의 숫자여야 합니다."); | ||
| } | ||
| if (winningList.contains(bonusNumber)) { | ||
| throw new IllegalArgumentException("[ERROR] 당첨 번호에 중복된 숫자가 있습니다."); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package lotto; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class LottoOutputView { | ||
|
||
|
|
||
| public void printLotto(List<Lotto> lottoList) { | ||
| System.out.println(lottoList.size() + "개를 구매했습니다."); | ||
| for(Lotto lotto : lottoList) { | ||
| System.out.println(lotto); | ||
| } | ||
| System.out.println(); | ||
| } | ||
|
|
||
| public void printWinningStatistics(LottoResult result) { | ||
| System.out.println("당첨 통계"); | ||
| System.out.println("---"); | ||
| for (LottoRank lottoRank : LottoRank.values()) { | ||
| if (lottoRank != LottoRank.NONE) { | ||
| //println (X) print(X) printf(O) | ||
| System.out.printf("%s - %d개\n", lottoRank.getDescription(), result.getCountForRank(lottoRank)); | ||
|
||
| } | ||
| } | ||
| } | ||
|
|
||
| public void printProfitRate(double profitRate) { | ||
| System.out.printf("총 수익률은 %.1f%%입니다.\n", profitRate); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| package lotto; | ||
|
|
||
| public enum LottoRank { | ||
| FIRST(6, 2_000_000_000, "6개 일치 (2,000,000,000원)"), | ||
| SECOND(5, 30_000_000, "5개 일치, 보너스 볼 일치 (30,000,000원)"), | ||
| THIRD(5, 1_500_000, "5개 일치 (1,500,000원)"), | ||
| FOURTH(4, 50_000, "4개 일치 (50,000원)"), | ||
| FIFTH(3, 5_000, "3개 일치 (5,000원)"), | ||
| NONE(0, 0, ""); | ||
|
|
||
| private final int matchCount; | ||
| private final int prize; | ||
| private final String description; | ||
|
|
||
| LottoRank(int matchCount, int prize, String description) { | ||
| this.matchCount = matchCount; | ||
| this.prize = prize; | ||
| this.description = description; | ||
| } | ||
|
|
||
| public static LottoRank getRank(int matchCount, boolean bonusMatch) { | ||
| if (matchCount == 6) return FIRST; | ||
| else if (matchCount == 5 && bonusMatch) return SECOND; | ||
| else if (matchCount == 5) return THIRD; | ||
| else if (matchCount == 4) return FOURTH; | ||
| else if (matchCount == 3) return FIFTH; | ||
| return NONE; | ||
| } | ||
|
|
||
| public String getDescription() { | ||
| return description; | ||
| } | ||
|
|
||
| public long getPrize() { | ||
| return prize; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package lotto; | ||
|
|
||
| import java.util.HashMap; | ||
|
|
||
| public class LottoResult { | ||
| private final HashMap<LottoRank, Integer> rankCounts; | ||
|
|
||
| public LottoResult() { | ||
| this.rankCounts = new HashMap<LottoRank, Integer>(); | ||
| for (LottoRank lottoRank : LottoRank.values()) { | ||
| rankCounts.put(lottoRank, 0); | ||
| } | ||
| } | ||
|
|
||
| public void addResult(LottoRank rank) { | ||
| rankCounts.put(rank, rankCounts.get(rank) + 1); //현재 랭크 갯수보다 하나 업 | ||
| } | ||
|
|
||
| public int getCountForRank(LottoRank lottoRank) { | ||
| return rankCounts.get(lottoRank); | ||
| } | ||
|
|
||
| public long getTotalPrize() { | ||
| return rankCounts.entrySet().stream() | ||
| .mapToLong(entry -> entry.getKey().getPrize() * entry.getValue()) | ||
| .sum(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package lotto; | ||
|
|
||
| import camp.nextstep.edu.missionutils.Randoms; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class LottoService { | ||
|
|
||
| /** | ||
| * 6개의 숫자 생성 | ||
| */ | ||
| public List<Lotto> generateLottoNumber(int count) { | ||
| List<Lotto> result = new ArrayList<>(); | ||
| for(int i = 0; i < count; i++) { | ||
| List<Integer> numbers = Randoms.pickUniqueNumbersInRange(1, 45, 6); | ||
| result.add(new Lotto(numbers)); | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
| public LottoResult checkWinningResult(List<Lotto> lottoList, List<Integer> winningNumbers, int bonusNumber) { | ||
| LottoResult result = new LottoResult(); | ||
| for (Lotto lotto : lottoList) { | ||
| int matchCount = lotto.matchCount(winningNumbers); | ||
| boolean bonusMatch = lotto.contains(bonusNumber); | ||
| result.addResult(LottoRank.getRank(matchCount, bonusMatch)); | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
| public double calculateProfitRate(int money, LottoResult result) { | ||
| long totalPrize = result.getTotalPrize(); | ||
| return (totalPrize * 100.0) / money; | ||
| } | ||
| } |
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.
숫자를 바로 하드코딩 하는 방식은 좋지 않은걸로 알고있는데 이 점에 대해선 어떻게 생각하시나용??
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.
magic number를 사용하는 방법으로 바꿔보겠습니다!