-
Notifications
You must be signed in to change notification settings - Fork 327
[1단계 - 로또(자동)] 레넌(조형래) 미션 제출합니다. #375
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
Merged
Merged
Changes from all commits
Commits
Show all changes
63 commits
Select commit
Hold shift + click to select a range
ec830c9
docs : 구현할 기능 목록 정리
brorae c6112ee
feat : 로또 등수 계산하는 기능 추가
brorae 7f22b10
docs : 구현할 기능 목록 수정
brorae cb9ae63
refactor : 메서드 분리 및 메소드 순서 정리
brorae ed649e3
feat : 구입금액, 당첨 번호 입력 받는 기능 추가
brorae a2da1bf
test : 입력값 테스트 추가
brorae 232e7d3
feat : 로또 번호 자동 생성 기능 추가
brorae e203093
feat : 로또 자동생성하여 출력하는 기능 추가
brorae 00bd0f4
refactor : 매직넘버 제거 및 상수화
brorae 8322669
refactor : controller에 따라 코드 수정
brorae 4def0e0
feat : 등수 계산 기능 추가
brorae df43ef5
docs : 기능 예외 사항 추가
brorae 3dddf58
refactor : enum Rank 구조 수정
brorae 6eb9277
feat : 입력 받을 때 예외 사항 추가
brorae 205a81b
feat : 등수 카운트 계산 후 저장하는 기능 추가
brorae a61d7be
feat : 통계(등수, 수익률) 계산 및 출력 기능 추가
brorae d89398c
refactor : 불필요 메소드 제거 및 메소드 이름, 접근제어자 수정
brorae 92aef92
refactor : 메소드 구조 수정
brorae ec4515f
refactor : 에러 메시지 출력하도록 코드 수정
brorae 45486ba
test : 정상적인 input test 추가
brorae 34f38e5
test : 로또 당첨 테스트 케이스 추가
brorae 0653db0
refactor : 구입 금액 입력 예외 사항 추가
brorae ad82fec
test : Lottos 테스트 코드 추가
brorae c6c2e3e
refactor : 코드 스타일에 따라 포멧 변경
brorae 7d3b0ca
refactor : Lottos를 생성자를 통해 생성하도록 수정
brorae e10159f
refactor : InputController에서 객체를 반환하도록 수정
brorae a5d3294
refactor : 객체 내에서 검증 하도록 수정
brorae 89f3122
refactor : lotto 생성 테스트 케이스 수정 및 추가
brorae 9b7a782
refactor : Money model 추가
brorae 25aa9f2
refactor : BonusNumber model 추가
brorae 45c944f
refactor : 중복 사용 메소드 분리
brorae 2f9dd8e
refactor : interface 추가하여 테스트하기 쉽도록 수정
brorae 6d0dc70
refactor : InputController 제거하여 코드 수정
brorae 07cbcbc
refactor : 코드 인덴트에 맞도록 수정
brorae 6ead5f3
refactor : LottoNumber 모델 추가
brorae 4ff3379
refactor : LottoNumbers 모델 추가하여 Validator 제거
brorae d0e8c63
refactor : Util 인터페이스 수정
brorae cfa0583
refactor : 로또 생성기 model로 이동
brorae 0638557
refactor : 메소드 이름 수정 등 전체적인 리팩토링
brorae 565795e
refactor : getter 지양하도록 코드 수정
brorae 6f7f5e1
refactor : 단위 테스트 수정 및 getter 제거
brorae 4ba72d8
refactor : 불필요 import 제거 및 테스트 기능 메소드화
brorae 0fc1d2b
refactor : 불필요 import 제거
brorae 29812b8
refactor : 예외처리 throws 추가
brorae 4124be2
refactor : 메소드 구조 수정
brorae 2efb822
refactor : final 키워드 추가 및 변수 이름 수정
brorae 42b9825
refactor : LottoMachine 모델 추가
brorae eb76eed
refactor : 불필요한 공백 제거
brorae 83fbf49
refactor : LottoControllerTest 테스트 추가
brorae 5668e1b
refactor : 코드 간결하게 수정
brorae d94e388
refactor : 메소드, 변수 이름 수정 및 중복 제거
brorae 08d88d1
refactor : 예외처리 종류 수정
brorae 47341e2
refactor : 메소드 간단하게 수정
brorae 95d9f78
refactor : LottoMachine에서 자동 로또 만들도록 수정
brorae 7db0597
refactor : 자동 로또 처리 LottoController로 이동
brorae cf442a8
refactor : 불필요한 import,공백 제거
brorae 515956f
refactor : 수익률 계산 오류 수정
brorae 429e57c
refactor : 예외 메시지 수정
brorae 9fb8215
refactor : 불필요 의존 제거
brorae 5cd87bb
refactor : 자동 로또 생성 테스트 방식 수정
brorae fc3c309
refactor : 테스트 메시지 추가
brorae 5d52845
refactor : unmodifiable Collection 수정 및 중복 상수 제거
brorae 2707b67
refactor : throws 키워드 제거
brorae File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package lotto; | ||
|
|
||
| import lotto.controller.LottoController; | ||
| import lotto.model.generator.AutoLottoGenerator; | ||
|
|
||
| public class Application { | ||
| public static void main(String[] args) { | ||
| LottoController lottoController = new LottoController(new AutoLottoGenerator()); | ||
|
|
||
| try { | ||
| lottoController.run(); | ||
| } catch (RuntimeException e) { | ||
| System.out.println(e.getMessage()); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| package lotto.controller; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.regex.Pattern; | ||
| import java.util.stream.Collectors; | ||
| import lotto.model.LottoMachine; | ||
| import lotto.model.Money; | ||
| import lotto.model.WinningLotto; | ||
| import lotto.model.generator.LottoGenerator; | ||
| import lotto.model.number.LottoNumber; | ||
| import lotto.model.number.LottoNumbers; | ||
| import lotto.view.InputView; | ||
| import lotto.view.ResultView; | ||
|
|
||
| public class LottoController { | ||
|
|
||
| private static final String NOT_NUMBER_ERROR_MESSAGE = "[ERROR] 문자가 입력되었습니다."; | ||
| private static final String NUMBER_REGEX = "\\d+"; | ||
|
|
||
| private LottoGenerator lottoGenerator; | ||
|
|
||
| public LottoController(LottoGenerator lottoGenerator) { | ||
| this.lottoGenerator = lottoGenerator; | ||
| } | ||
|
|
||
| public void run() { | ||
| LottoMachine lottoMachine = new LottoMachine(lottoGenerator, validateMoney(InputView.inputMoney())); | ||
| ResultView.printBuyingLottosResult(lottoMachine.getLottos()); | ||
| WinningLotto winningLotto = makeWinningLotto(InputView.inputWinningNumbers(), | ||
| InputView.inputBonusNumber()); | ||
| lottoMachine.calculateResult(winningLotto); | ||
| ResultView.printTotalRankResult(lottoMachine); | ||
| } | ||
|
|
||
| private Money validateMoney(String money) { | ||
| if (!Pattern.matches(NUMBER_REGEX, money)) { | ||
| throw new IllegalArgumentException(Money.MONEY_ERROR_MESSAGE); | ||
| } | ||
| return new Money(Integer.parseInt(money)); | ||
| } | ||
|
|
||
| private WinningLotto makeWinningLotto(String winningNumbers, String bonusNumber) { | ||
| LottoNumbers lottoNumbers = splitWinningNumbers(winningNumbers); | ||
| LottoNumber lottoBonusNumber = new LottoNumber(toIntBonusNumber(bonusNumber)); | ||
| return new WinningLotto(lottoNumbers, lottoBonusNumber); | ||
| } | ||
|
|
||
| private LottoNumbers splitWinningNumbers(String winningNumbers) { | ||
| String[] splitNumbers = validateLottoNumbers(winningNumbers); | ||
| return new LottoNumbers(Arrays.stream(splitNumbers) | ||
| .map(String::trim) | ||
| .mapToInt(Integer::parseInt) | ||
| .boxed() | ||
| .map(LottoNumber::new) | ||
| .collect(Collectors.toList())); | ||
| } | ||
|
|
||
| private String[] validateLottoNumbers(String numbers) { | ||
| String[] splitNumbers = numbers.split(","); | ||
| for (String number : splitNumbers) { | ||
| validateNumber(number); | ||
| } | ||
| return trimLottoNumbers(splitNumbers); | ||
| } | ||
|
|
||
| private int validateNumber(String number) { | ||
| try { | ||
| String trimNumber = number.trim(); | ||
| return Integer.parseInt(trimNumber); | ||
| } catch (NumberFormatException e) { | ||
| throw new IllegalArgumentException(NOT_NUMBER_ERROR_MESSAGE); | ||
| } | ||
| } | ||
|
|
||
| private String[] trimLottoNumbers(String[] numbers) { | ||
| for (int i = 0; i < numbers.length; i++) { | ||
| numbers[i] = numbers[i].trim(); | ||
| } | ||
| return numbers; | ||
| } | ||
|
|
||
| private int toIntBonusNumber(String bonusNumber) { | ||
| return validateNumber(bonusNumber); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| package lotto.model; | ||
|
|
||
| import lotto.model.number.LottoNumber; | ||
| import lotto.model.number.LottoNumbers; | ||
|
|
||
| public class Lotto { | ||
|
|
||
| private final LottoNumbers lottoNumbers; | ||
| private Rank rank; | ||
|
|
||
| public Lotto(final LottoNumbers lottoNumbers) { | ||
| this.lottoNumbers = lottoNumbers; | ||
| this.rank = null; | ||
| } | ||
|
|
||
| public Rank calculateRank(final LottoNumbers winningNumbers, final LottoNumber bonusNumber) { | ||
| if (this.rank == null) { | ||
| int matchingCount = countMatchingNumber(winningNumbers); | ||
| boolean win = isWinBonusNumber(matchingCount, bonusNumber); | ||
| return this.rank = Rank.getRank(matchingCount, win); | ||
| } | ||
| return this.rank; | ||
| } | ||
|
|
||
| private boolean isWinBonusNumber(final int matchingCount, final LottoNumber bonusNumber) { | ||
| if (matchingCount == Rank.SECOND.getCount()) { | ||
| return lottoNumbers.containNumber(bonusNumber); | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| private int countMatchingNumber(LottoNumbers winningNumbers) { | ||
| return lottoNumbers.countMatchingNumber(winningNumbers); | ||
| } | ||
|
|
||
| public LottoNumbers getLottoNumbers() { | ||
| return lottoNumbers; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| package lotto.model; | ||
|
|
||
| import java.util.Map; | ||
| import lotto.model.generator.LottoGenerator; | ||
| import lotto.model.number.LottoNumber; | ||
| import lotto.model.number.LottoNumbers; | ||
|
|
||
| public class LottoMachine { | ||
|
|
||
| private final Money money; | ||
| private final Lottos lottos; | ||
|
|
||
| private Map<Rank, Integer> rankCount; | ||
|
|
||
| public LottoMachine(final LottoGenerator lottoGenerator, final Money money) { | ||
| this.money = money; | ||
| this.lottos = lottoGenerator.generateLottos(money.lottoCount(), LottoNumber.LOTTO_NUMBER_MINIMUM_RANGE, | ||
| LottoNumber.LOTTO_NUMBER_MAXIMUM_RANGE, LottoNumbers.LOTTO_LENGTH); | ||
| } | ||
|
|
||
| public void calculateResult(final WinningLotto winningLotto) { | ||
| this.rankCount = winningLotto.checkRank(lottos); | ||
| } | ||
|
|
||
| public Lottos getLottos() { | ||
| return lottos; | ||
| } | ||
|
|
||
| public double getRevenue() { | ||
| int sum = 0; | ||
| for (Rank rank : Rank.values()) { | ||
| sum += rank.getPrice() * getEachRankCount(rank); | ||
| } | ||
| return ((double) sum / money.getMoney()); | ||
| } | ||
|
|
||
| public Integer getEachRankCount(final Rank rank) { | ||
| return rankCount.get(rank); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| package lotto.model; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.Collections; | ||
| import java.util.LinkedHashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import lotto.model.number.LottoNumber; | ||
| import lotto.model.number.LottoNumbers; | ||
|
|
||
| public class Lottos { | ||
|
|
||
| private final List<Lotto> lottos; | ||
|
|
||
| public Lottos(final List<Lotto> lottos) { | ||
| this.lottos = lottos; | ||
| } | ||
|
|
||
| public Map<Rank, Integer> calculateRanks(final LottoNumbers winningNumbers, final LottoNumber bonusNumber) { | ||
| Map<Rank, Integer> rankCount = initMap(); | ||
| lottos.forEach(lotto -> { | ||
| Rank rank = lotto.calculateRank(winningNumbers, bonusNumber); | ||
| rankCount.put(rank, rankCount.get(rank) + 1); | ||
| }); | ||
| return rankCount; | ||
brorae marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| private Map<Rank, Integer> initMap() { | ||
| Map<Rank, Integer> map = new LinkedHashMap<>(); | ||
| Arrays.stream(Rank.values()).forEach(rank -> map.put(rank, 0)); | ||
| return map; | ||
| } | ||
|
|
||
| public List<Lotto> getLottos() { | ||
| return Collections.unmodifiableList(lottos); | ||
| } | ||
|
|
||
| public int size() { | ||
| return lottos.size(); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package lotto.model; | ||
|
|
||
| public class Money { | ||
|
|
||
| private static final int PRICE_PER_LOTTO = 1000; | ||
brorae marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| public static final String MONEY_ERROR_MESSAGE = "[ERROR] 유효한 구매 금액이 아닙니다."; | ||
|
|
||
| private final int money; | ||
|
|
||
| public Money(final int money) { | ||
| validateMoney(money); | ||
| this.money = money; | ||
| } | ||
|
|
||
| private void validateMoney(final int money) { | ||
| if (money < 0) { | ||
| throw new IllegalArgumentException(MONEY_ERROR_MESSAGE); | ||
| } | ||
| } | ||
|
|
||
| public int getMoney() { | ||
| return money; | ||
| } | ||
|
|
||
| public int lottoCount() { | ||
| return money / PRICE_PER_LOTTO; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package lotto.model; | ||
|
|
||
| import java.util.Arrays; | ||
|
|
||
| public enum Rank { | ||
| LOSER(0, false, 0), | ||
| FIFTH(3, false, 5_000), | ||
| FOURTH(4, false, 50_000), | ||
| THIRD(5, false, 1_500_000), | ||
| SECOND(5, true, 30_000_000), | ||
| FIRST(6, false, 2_000_000_000); | ||
|
|
||
| private final int count; | ||
| private final boolean winBonusNumber; | ||
| private final int price; | ||
|
|
||
| Rank(final int count, final boolean winBonusNumber, final int price) { | ||
| this.count = count; | ||
| this.winBonusNumber = winBonusNumber; | ||
| this.price = price; | ||
| } | ||
|
|
||
| public int getCount() { | ||
| return count; | ||
| } | ||
|
|
||
| public boolean isWinBonusNumber() { | ||
| return winBonusNumber; | ||
| } | ||
|
|
||
| public int getPrice() { | ||
| return price; | ||
| } | ||
|
|
||
| public static Rank getRank(final int count, final boolean winBonusNumber) { | ||
| return Arrays.stream(Rank.values()) | ||
| .filter(rank -> rank.count == count) | ||
| .filter(rank -> rank.winBonusNumber == winBonusNumber) | ||
| .findFirst() | ||
| .orElse(LOSER); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package lotto.model; | ||
|
|
||
| import java.util.Map; | ||
| import lotto.model.number.LottoNumber; | ||
| import lotto.model.number.LottoNumbers; | ||
|
|
||
| public class WinningLotto { | ||
|
|
||
| private static final String DUPLICATED_NUMBER_ERROR_MESSAGE = "[ERROR] 보너스 번호가 중복되었습니다."; | ||
|
|
||
| private final LottoNumbers winningNumbers; | ||
| private final LottoNumber bonusNumber; | ||
|
|
||
| public WinningLotto(final LottoNumbers winningNumbers, final LottoNumber bonusNumber) { | ||
| this.winningNumbers = winningNumbers; | ||
| checkDuplicateNumber(bonusNumber); | ||
| this.bonusNumber = bonusNumber; | ||
| } | ||
|
|
||
| private void checkDuplicateNumber(LottoNumber bonusNumber) { | ||
| if (winningNumbers.containNumber(bonusNumber)) { | ||
| throw new IllegalArgumentException(DUPLICATED_NUMBER_ERROR_MESSAGE); | ||
| } | ||
| } | ||
|
|
||
| public Map<Rank, Integer> checkRank(Lottos lottos) { | ||
| return lottos.calculateRanks(winningNumbers, bonusNumber); | ||
| } | ||
| } |
45 changes: 45 additions & 0 deletions
45
src/main/java/lotto/model/generator/AutoLottoGenerator.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| package lotto.model.generator; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
| import java.util.stream.IntStream; | ||
| import lotto.model.Lotto; | ||
| import lotto.model.Lottos; | ||
| import lotto.model.number.LottoNumber; | ||
| import lotto.model.number.LottoNumbers; | ||
|
|
||
| public class AutoLottoGenerator implements LottoGenerator { | ||
|
|
||
| private static final int LOTTO_START_INDEX = 0; | ||
|
|
||
| @Override | ||
| public Lottos generateLottos(int lottoCount, int minimumNumber, int maximumNumber, int lottoLength) { | ||
| List<Lotto> lottos = new ArrayList<>(); | ||
| for (int i = 0; i < lottoCount; i++) { | ||
| LottoNumbers lottoNumbers = makeLottoNumbers(minimumNumber, maximumNumber, lottoLength); | ||
| lottos.add(makeLotto(lottoNumbers)); | ||
| } | ||
| return new Lottos(lottos); | ||
| } | ||
|
|
||
| private LottoNumbers makeLottoNumbers(int minimumNumber, int maximumNumber, int lottoLength) { | ||
| List<Integer> numberCollection = makeNumberCollection(minimumNumber, maximumNumber); | ||
| Collections.shuffle(numberCollection); | ||
| return new LottoNumbers(numberCollection.subList(LOTTO_START_INDEX, lottoLength).stream() | ||
| .sorted() | ||
| .map(LottoNumber::new) | ||
| .collect(Collectors.toList())); | ||
| } | ||
|
|
||
| private List<Integer> makeNumberCollection(int minimumNumber, int maximumNumber) { | ||
| return IntStream.rangeClosed(minimumNumber, maximumNumber) | ||
| .boxed() | ||
| .collect(Collectors.toList()); | ||
| } | ||
|
|
||
| private Lotto makeLotto(LottoNumbers lottoNumbers) { | ||
| return new Lotto(lottoNumbers); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.