-
Notifications
You must be signed in to change notification settings - Fork 40
[스프링 화요일 3팀]염경호 미션 제출합니다. #20
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 all commits
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,114 @@ | ||
| package controller; | ||
|
|
||
| import domain.*; | ||
| import view.*; | ||
|
|
||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.LinkedHashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
|
|
||
|
|
||
|
|
||
|
|
||
| public class LottoController { | ||
| private static final int TICKET_PRICE = 1000;//로또 개당 가격 | ||
| private static final int PERCENTAGE = 100;//추후 성공률 계산에 이용 | ||
|
|
||
| private static PlayerLottoAmount playerLottoAmount;//금액을 받고 로또를 할 수 있는 금액인지 적합성 검사 후 발행할 로또 개수 | ||
| //정해줌 | ||
| private static List<Integer> lotto = new ArrayList<>(); | ||
| private static List<Lotto> lottoList;//로또들을 발행한 개수 만큼 리스트에 저장 | ||
| private static WinningResult winningResult;//당첨 로또 번호 6개와 와 보너스 번호 1개를 가지고 있는 객체, 추후 가지고 있는 | ||
| //로또(리스트)들과 당첨 로또 간의 비교를 한 후 Ranking enum 반환 할 예정 | ||
| public void run() { | ||
| start(); | ||
| return; | ||
| } | ||
| public void start(){ | ||
| int ticketCount = inputPlayerAmount();//발행할 로또 개수 | ||
| OutputView.printTicketCount(ticketCount);//로또 개수 출략 | ||
| lottoList = makeLottoList(ticketCount);//로또 개수 만큼의 리스트 배열 생성 | ||
| winningResult = validateBonus(); | ||
| lottoResult(lottoList, winningResult, ticketCount); | ||
|
|
||
|
|
||
| } | ||
| public int inputPlayerAmount(){ | ||
| playerLottoAmount = new PlayerLottoAmount(InputView.inputPlayerAmount()); | ||
| return playerLottoAmount.calculateLottoCount(); | ||
|
|
||
| } | ||
| public WinningResult validateBonus(){ | ||
| Lotto lotto = new Lotto(InputView.inputLottoWinningNum()); | ||
| List<Integer>winningList = lotto.getLottoNumbers(); | ||
| int ball = InputView.inputBonusNumber(); | ||
| lotto.validateBonusNumber(winningList, ball); | ||
|
|
||
|
|
||
| return new WinningResult(lotto, ball); | ||
|
|
||
| } | ||
|
|
||
|
|
||
| public List<Lotto>makeLottoList(int ticketCount){ | ||
| lottoList = new ArrayList<>(); | ||
| for(int i = 0; i < ticketCount; i++){ | ||
| lottoList.add(makeLotto());//로또 개수만큼 로또 내부 리스트 생성(6개) 후 해당 로또를 lottoList에 저장함 | ||
|
|
||
| } | ||
| return lottoList;//저장 후 결과 값 반환 | ||
| } | ||
|
|
||
| private static Lotto makeLotto(){//로또 만드는 과정은 외부에서 접근하지 못하도록(랜덤하게 made) private 접근 제한자 사용 | ||
| LottoNumbers lottoNumbers = new LottoNumbers(); | ||
| lotto = lottoNumbers.setRandomLottos();//랜덤하게 로또 만들어 리스트 형태로 반환해 lotto에 넘겨줌 | ||
| System.out.println(lotto); | ||
| return new Lotto(lotto); | ||
| } | ||
|
|
||
| public void lottoResult(List<Lotto>lottoList, WinningResult winningResult, int ticketCount){ | ||
| Map<Ranking, Integer>result = setResult();//map 초기화 작업 진행 key에는 Ranking values() 각각 넣고 value는 0으로 초기화 | ||
| Ranking r; | ||
|
|
||
| OutputView.printSuccessResult(); | ||
| for(int i = 0; i < lottoList.size(); i++){ | ||
| r = winningResult.match(lottoList.get(i));//lottoList에 들어있는 로또 하나씩을 꺼내서 당첨 로또와 유사성 비교 후 | ||
| //적절한 Ranking Enum 객체를 반환해주는 역할 수행 | ||
| result.put(r, result.get(r) + 1);//헤당 enum 객체와 그 수량을 하나 증가시켜서 map에 put해줌 | ||
| } | ||
| printResult(result);//결과를 map으로 출력 | ||
| printEarningRate(result, ticketCount);//수익률 계산하는 메서드 수행 | ||
|
|
||
|
|
||
| } | ||
|
|
||
| public void printResult(Map<Ranking, Integer> result){ | ||
| for(int i = Ranking.values().length -1; i >= 0; i--){//3~6순으로 해야되므로 인덱스 역순으로 출력하게 작성 | ||
| Ranking.values()[i].printMessage(result.get(Ranking.values()[i]));//헤당 enum객체의 정보 출력 | ||
| } | ||
| } | ||
|
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 void printEarningRate(Map<Ranking, Integer>result, int ticketCount){ | ||
| double percent = 0.0; | ||
|
|
||
| for(Ranking r : result.keySet()){ | ||
| percent += ((double)((r.getWinningAmount() * result.get(r))*PERCENTAGE) | ||
| / (TICKET_PRICE * ticketCount)); | ||
|
|
||
|
|
||
| } | ||
| OutputView.printRevenueRate(percent); | ||
|
|
||
|
|
||
| } | ||
| public Map<Ranking, Integer>setResult(){ | ||
| Map<Ranking, Integer>result = new LinkedHashMap<>(); | ||
| for(Ranking r : Ranking.values()){ | ||
| result.put(r, 0); | ||
| } | ||
| return result; | ||
|
|
||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| package domain; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class Lotto { | ||
| private static final int MIN_NUMBER = 1; | ||
| private static final int MAX_NUMBER = 45; | ||
| private final List<Integer> numbers; | ||
|
|
||
| public Lotto(List<Integer> numbers) { | ||
| validate(numbers);//로또 번호 개수가 6개로 정상적으로 들어왔는지 여부 확인 | ||
| validateRange(numbers);//1~45까지의 값이 있나 확인 | ||
| this.numbers = numbers;//검사 통과하면 numbers라는 리스트 객체에 저장 | ||
| } | ||
|
|
||
| public List<Integer> getLottoNumbers(){//로또 리스트 반환 | ||
| return numbers; | ||
| } | ||
|
|
||
| public boolean containNumber(int number){//로또 리스트에 해당 숫자가 있는지 검사할 수 있는 메서드 | ||
| return numbers.contains(number); | ||
| } | ||
|
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. 이거 굳이 필요 없어 보이는데 쓰신 이유가 있나요? 그냥 contains 써도 똑같은 거 아닌가요?? |
||
| public int countMatch(Lotto winningLotto){//winningLotto에 들어있는 로또 리스트 객체와 확인하고자 하는 로또 | ||
| //비교 후 같은 정수가 있으면 값을 증가시켜 반환 | ||
| return (int)numbers.stream().filter(w -> winningLotto.numbers.contains(w)).count(); | ||
| } | ||
|
|
||
|
|
||
| private void validate(List<Integer> numbers) { | ||
| if (numbers.size() != 6) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| } | ||
| private void validateRange(List<Integer> numbers) { | ||
| for(int i = 0; i < numbers.size(); i++){ | ||
| if(numbers.get(i) < MIN_NUMBER || numbers.get(i) > MAX_NUMBER){ | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public static void validateBonusNumber(List<Integer> numbers, int bonusNumber) { | ||
| //추후 당첨 로또의 6개의 로또 번호와 1개의 보너스 번호에서 보너스 변호와 로또 번호가 겹치는게 있는지 확인하기 위한 매서드 | ||
| if (numbers.contains(bonusNumber)) { | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package domain; | ||
|
|
||
|
|
||
|
|
||
| import org.kokodak.Randoms; | ||
|
|
||
| import java.util.Collections; | ||
| import java.util.List; | ||
|
|
||
|
|
||
| public class LottoNumbers { | ||
| private static final int CNT_LOTTO_NUMBER = 6; | ||
| private static final int MIN_LOTTO_NUMBER = 1; | ||
| private static final int MAX_LOTTO_NUMBER = 45; | ||
|
|
||
| private static List<Integer> lottoNumberList; | ||
| public static List<Integer> setRandomLottos(){ | ||
| lottoNumberList = Randoms.pickUniqueNumbersInRange(MIN_LOTTO_NUMBER, MAX_LOTTO_NUMBER, CNT_LOTTO_NUMBER); | ||
| //해당 범위내 값에서 CNT만큼 증복되지 않는 로또 번호 가져와 리스트 형태로 반환해줌 | ||
| Collections.sort(lottoNumberList);//오름차순 정렬 위함 | ||
| return lottoNumberList; | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package domain; | ||
|
|
||
| public class PlayerLottoAmount { | ||
| private static final int Lotto_Min_Amount = 1000;//로또 한개 당 가격 | ||
| private final int amount; | ||
|
|
||
| public PlayerLottoAmount(String amount){ | ||
| int amountNum = changeToInt(amount); | ||
| validateAmount(amountNum); | ||
| validateNum(amountNum); | ||
| this.amount = amountNum; | ||
| } | ||
| public int changeToInt(String amount){ | ||
| return Integer.parseInt(amount); | ||
| } | ||
| public int calculateLottoCount() {//발행할 로또 개수 반환 | ||
| return amount / Lotto_Min_Amount; | ||
| } | ||
|
|
||
| public void validateAmount(int amountNum){//1000보다 작으면 로또 못삼(예외 처리) | ||
| if(amountNum < Lotto_Min_Amount){ | ||
| throw new IllegalArgumentException(); | ||
| } | ||
|
|
||
| } | ||
|
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. 이 함수는 PlayerLottoAmount 클래스 내부에서만 쓰는 것 같은데 접근지정자를 private로 바꾸는 게 어떨까요? |
||
|
|
||
| public void validateNum(int amountNum){//1000으로 안나누어지면 오류 | ||
| if(amountNum % Lotto_Min_Amount != 0){ | ||
| throw new IllegalArgumentException(); | ||
| } | ||
| } | ||
|
|
||
|
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. 이 함수도 마찬가지로 접근지정자를 private로 바꾸는 게 어떨까요 |
||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| package domain; | ||
|
|
||
| import view.OutputView; | ||
|
|
||
| public enum Ranking { | ||
| FIRST(6, 2_000_000_000, "6개 일치 (2,000,000,000원) - "), // 1등 | ||
| SECOND(5, 30_000_000, "5개 일치, 보너스 볼 일치 (30,000,000원) - "), // 2등 | ||
| THIRD(5, 1_500_000, "5개 일치 (1,500,000원) - "), // 3등 | ||
| FOURTH(4, 50_000, "4개 일치 (50,000원) - "), // 4등 | ||
| FIFTH(3, 5_000, "3개 일치 (5,000원) - "), // 5등 | ||
| MISS(0, 0, "");//3개 미만 맞으면 꽝 | ||
|
|
||
| private int countOfMatch; | ||
| private int winningAmount; | ||
| private String message; | ||
|
|
||
| Ranking(int countOfMatch, int winningAmount, String message){ | ||
| this.countOfMatch = countOfMatch; | ||
| this.winningAmount = winningAmount; | ||
| this.message = message; | ||
| } | ||
| private static final int WINNING_MIN_COUNT = 3; | ||
| public static Ranking valuesOf(int countOfMatch, boolean bonusCheck){ | ||
| if(countOfMatch < WINNING_MIN_COUNT){ | ||
| return MISS; | ||
| } | ||
| if(SECOND.matchCount(countOfMatch) && bonusCheck){ | ||
| return SECOND; | ||
| } | ||
| for(Ranking rank : values()){ | ||
| if(rank.matchCount(countOfMatch) && rank != SECOND){ | ||
| return rank; | ||
| } | ||
| } | ||
| throw new IllegalArgumentException(); | ||
| } | ||
|
|
||
| public int getCountOfMatch(){ | ||
| return countOfMatch; | ||
| } | ||
| public int getWinningAmount(){ | ||
| return winningAmount; | ||
| } | ||
|
|
||
| public void printMessage(int countOfMatch){ | ||
| if(this != MISS){ | ||
| OutputView.printSuccessMessage(message, countOfMatch); | ||
| } | ||
| } | ||
|
|
||
| private boolean matchCount(int countOfMatch) { | ||
| return this.countOfMatch == countOfMatch; | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package domain; | ||
|
|
||
| public class WinningResult { | ||
| private final Lotto lotto; | ||
| private final int bonus; | ||
| public WinningResult(Lotto lotto, int bonus){ | ||
| this.lotto = lotto; | ||
| this.bonus = bonus; | ||
| } | ||
| public Ranking match(Lotto playerNumber){ | ||
| int countOfMatch = playerNumber.countMatch(lotto);//각 로또들과 당첨 로또 비교해 몇개의 숫자 맞는지 반환 | ||
| boolean bonusCheck = playerNumber.containNumber(bonus);//보너스 번호를 맞았는지 여부 boolean형태로 반환 | ||
| return Ranking.valuesOf(countOfMatch, bonusCheck);//해당 정보들 가지고 Ranking Enum의 객체와 매치시키게 됨 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,10 @@ | ||
| package lotto; | ||
|
|
||
| import controller.LottoController; | ||
|
|
||
| public class Application { | ||
| public static void main(String[] args) { | ||
| // TODO: 프로그램 구현 | ||
| LottoController lottoController = new LottoController(); | ||
| lottoController.run(); | ||
| } | ||
| } |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package view; | ||
|
|
||
|
|
||
|
|
||
| import org.kokodak.Console; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class InputView { | ||
| private static final String INPUT_LOTTO_AMOUNT = "구입금액을 입력해 주세요."; | ||
| private static final String INPUT_LOTTO_WINNING = "당첨 번호를 입력해 주세요."; | ||
| private static final String INPUT_BONUS_NUMBER = "보너스 번호를 입력해 주세요."; | ||
|
|
||
| public static List<Integer> winningNumberList; | ||
|
|
||
| public static String inputPlayerAmount(){ | ||
| System.out.println(INPUT_LOTTO_AMOUNT); | ||
| return Console.readLine(); | ||
| } | ||
|
|
||
| public static List<Integer> inputLottoWinningNum(){ | ||
| System.out.println(INPUT_LOTTO_WINNING); | ||
| return numberList(Console.readLine()); | ||
| } | ||
| public static int inputBonusNumber() { | ||
| System.out.println(INPUT_BONUS_NUMBER); | ||
| return Integer.parseInt(Console.readLine()); | ||
| } | ||
| public static List<Integer>numberList(String winningNumber){ | ||
| String[]result = winningNumber.split(","); | ||
| winningNumberList = new ArrayList<>(); | ||
| for(int i = 0; i < result.length; i++){ | ||
| winningNumberList.add(convertToInt(result[i])); | ||
| } | ||
| return winningNumberList; | ||
| } | ||
| public static int convertToInt(String s){ | ||
|
|
||
| return Integer.parseInt(s); | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
| } |
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.
수정하겠습니다!