diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922..589a1a3 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,14 @@ package lotto; +import camp.nextstep.edu.missionutils.Console; + +import java.util.Scanner; + public class Application { + public static void main(String[] args) { // TODO: 프로그램 구현 + LottoController lottoController = new LottoController(); + lottoController.start(); } } diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java index 519793d..7cfa832 100644 --- a/src/main/java/lotto/Lotto.java +++ b/src/main/java/lotto/Lotto.java @@ -1,12 +1,22 @@ package lotto; +import camp.nextstep.edu.missionutils.Randoms; + +import java.util.Comparator; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class Lotto { + public List getNumbers() { + return numbers; + } + private final List numbers; public Lotto(List numbers) { - validate(numbers); + validate(numbers); //숫자 6개 인지 확인 + checkDuplicate(numbers); //중복된 숫자 있는지 확인 this.numbers = numbers; } @@ -17,4 +27,28 @@ private void validate(List numbers) { } // TODO: 추가 기능 구현 + private boolean checkBonusNumber(List numbers, int bonusNumber) { //보너스 숫자 일치 여부 확인 + if (numbers.contains(bonusNumber)) { + return true; + } + return false; + } + + private int checkWinningNumbers(List numbers, List winningNumbers){ //일치하는 숫자 개수 확인 + int cnt = 0; + for(int i = 0 ; i < numbers.size() ; i++){ + if(winningNumbers.contains(numbers.get(i))){ + cnt += 1; + } + } + return cnt; + } + + private void checkDuplicate(List numbers){ //중복 숫자 확인 + Set set = new HashSet<>(numbers); + + if(numbers.size() != set.size()){ + throw new IllegalArgumentException("[ERROR] 중복된 숫자가 존재합니다."); + } + } } diff --git a/src/main/java/lotto/LottoController.java b/src/main/java/lotto/LottoController.java new file mode 100644 index 0000000..fc655ab --- /dev/null +++ b/src/main/java/lotto/LottoController.java @@ -0,0 +1,33 @@ +package lotto; + +import java.util.List; +import java.util.Map; + +public class LottoController { + //돈 입력 -> 돈 입력, 로또 구매 가능 갯수 파악 예외처리(돈 1000이하 or 1000단위 아님) + //구매 내역 출력 -> 로또 생성기로 개수 만큼 생성 + //당첨번호 입력 -> 6개 숫자 입력 -> 예외처리(1~45 이내, 중복제거) + //보너스 번호 입력 -> 숫자 입력 -> 예외처리(1~45 이내) + //당첨 내역 출력 + //수익률 출력 + public void start(){ + try{ + int money = UserInput.getMoney(); //돈 입력 + PurchaseLotto lottoAmount = new PurchaseLotto(money); + Output.printLottoAmount(lottoAmount.getPurchaseAmount()); //구매 갯수 출력 + Lottos lottos = new Lottos(lottoAmount.generateLottos()); // + Output.printLottos(lottos); + List winningNumbers = UserInput.getWinningNumbers(); + int bonusNumber = UserInput.getBonusNumber(); + LottoWinningCheck lottoWinningCheck = new LottoWinningCheck(); + Map lottoResult = lottoWinningCheck.matchingNumbersCount(lottos, winningNumbers, bonusNumber); + Map winningInfo = WinningRank.findWinningCounts(lottoResult); + Output.printResults(winningInfo); + double earningRate = Output.calcEarning(winningInfo,money); + System.out.printf("총 수익률은 %f% 입니다", earningRate); + } catch(IllegalArgumentException e){ + System.out.println(e.getMessage()); + } + } + +} diff --git a/src/main/java/lotto/LottoWinningCheck.java b/src/main/java/lotto/LottoWinningCheck.java new file mode 100644 index 0000000..9618616 --- /dev/null +++ b/src/main/java/lotto/LottoWinningCheck.java @@ -0,0 +1,65 @@ +package lotto; + +import java.util.*; + +public class LottoWinningCheck { + private Lottos lottos; + private List winningNumbers; + private int bonusNumber; + public LottoWinningCheck() { + } + + //로또 번호와 당첨 번호 비교하는 메소드 + public int matchingLotto(Lotto lotto, List winningNumbers){ + int cnt = 0; + for(int num: lotto.getNumbers()){ + if(winningNumbers.contains(num)){ + cnt += 1; + } + } + return cnt; + } + + //로또 번호와 당첨 번호 비교하여 맞는 개수로 등수 확정 + public Map matchingNumbersCount(Lottos lottos, List winningNumbers, int bonusNumber){ + Map matchingNumbersCount = new HashMap<>(); + for(Lotto lotto1: lottos.getLottos()){ + int cnt = 0; + boolean bonusNumberMatching = false; + cnt = matchingLotto(lotto1, winningNumbers); + bonusNumberMatching = bonusNumberMatchingCheck(lotto1, bonusNumber); + matchingNumbersCount.put(cnt, bonusNumberMatching); + } + return matchingNumbersCount; + } + //보너스 번호 맞는지 여부 확인 + public boolean bonusNumberMatchingCheck(Lotto lotto, int bonusNumber){ + if(lotto.getNumbers().contains(bonusNumber)){ + return true; + } + return false; + } + + //로또 결과 map으로 표시 된 것들 몇 등이 몇 개인지 체크 후 출력 + /* 이 방식으로는 15줄 넘어가서 다른 방법 찾아야 함 + public void printResults(Map lottoResult){ + for(Map.Entry entry : lottoResult.entrySet()){ + int key = entry.getKey(); + boolean value = entry.getValue(); + if(key < 3){ + continue; + } + if (key == 3) { + } + if(key == 4){ + + } + if (key == 5) { + + } + } + } + */ + + +} diff --git a/src/main/java/lotto/Lottos.java b/src/main/java/lotto/Lottos.java new file mode 100644 index 0000000..dda44d1 --- /dev/null +++ b/src/main/java/lotto/Lottos.java @@ -0,0 +1,16 @@ +package lotto; + +import java.util.List; + +public class Lottos { //Lotto 클래스를 List로 묶은 클래스 + + private List lottos; + + public Lottos(List lottos) { + this.lottos = lottos; + } + + public List getLottos() { + return lottos; + } +} diff --git a/src/main/java/lotto/Output.java b/src/main/java/lotto/Output.java new file mode 100644 index 0000000..2b92490 --- /dev/null +++ b/src/main/java/lotto/Output.java @@ -0,0 +1,34 @@ +package lotto; + +import java.util.Map; + +public class Output { + public static void printLottoAmount(int lottoAmount){ + System.out.println(lottoAmount +"개를 구매했습니다."); + } + + public static void printLottos(Lottos lottos){ + lottos.getLottos().stream() + .forEach(lotto -> System.out.println(lotto.getNumbers().toString())); + } + public static void printResults (Map winningInfo){ + for(Map.Entry entry : winningInfo.entrySet()){ + WinningRank winningRank = entry.getKey(); + int value = entry.getValue(); + System.out.println( winningRank.ordinal()+1 + "개 일치 (" + winningRank.getWinningPrice() +"원) - " + value + "개"); + } + } + + public static double calcEarning(Map winningInfo, int money){ + int sum = 0; + for(Map.Entry entry : winningInfo.entrySet()){ + WinningRank winningRank = entry.getKey(); + int value = entry.getValue(); + if(value >= 1){ + sum += value * winningRank.getWinningPrice(); + } + } + return Math.round(sum/money); + } + +} diff --git a/src/main/java/lotto/PurchaseLotto.java b/src/main/java/lotto/PurchaseLotto.java new file mode 100644 index 0000000..6b162c6 --- /dev/null +++ b/src/main/java/lotto/PurchaseLotto.java @@ -0,0 +1,44 @@ +package lotto; + +import camp.nextstep.edu.missionutils.Console; +import camp.nextstep.edu.missionutils.Randoms; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +public class PurchaseLotto { //다른 코드 참고 + public int getPurchaseAmount() { + return purchaseAmount; + } + + private int purchaseAmount; //로또 갯수 + private final List lottos = new ArrayList<>(); //구매한 로또 번호들 + + public PurchaseLotto(int money){ + validateMoney(money); + purchaseAmount = money / 1000; + } + private void validateMoney(int money) { //액수 검증 + money = Integer.parseInt(Console.readLine()); + if (money < 1000) { + throw new IllegalArgumentException("[ERROR] 구입 금액은 1000원 이상이어야 합니다"); + } + if (money % 1000 != 0) { + throw new IllegalArgumentException("[ERROR] 구입 금액은 1000원 단위여야 합니다."); + } + } + + private Lotto generateNumbers(){ + List numbers = Randoms.pickUniqueNumbersInRange(1,45,6); //겹치지 않는 숫자 반환 + numbers.sort(Comparator.naturalOrder()); + return new Lotto(numbers); //이렇게 해야 예외처리 됨 + } + public List generateLottos(){ + for(int i = 0 ; i < purchaseAmount ; i++){ + Lotto lotto = generateNumbers(); + lottos.add(lotto); + } + return lottos; + } +} diff --git a/src/main/java/lotto/UserInput.java b/src/main/java/lotto/UserInput.java new file mode 100644 index 0000000..5bec853 --- /dev/null +++ b/src/main/java/lotto/UserInput.java @@ -0,0 +1,42 @@ +package lotto; + +import camp.nextstep.edu.missionutils.Console; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class UserInput { //메소드를 static으로 선언하여 인풋 시 선언 필요 없도록 + //구매 액수 입력 + public static int getMoney(){ + System.out.println("구매 금액을 입력해 주세요"); + try{ + return Integer.parseInt(Console.readLine()); //액수 관련 오류는 Purchase Lotto에서 처리 + } catch(NumberFormatException numberFormatException) { //입력 관련 오류 처리 + throw new IllegalArgumentException("[ERROR] 숫자가 아닌 값이 입력됐습니다."); + } + } + + //당첨 번호 입력 + + public static List getWinningNumbers() { + System.out.println("당첨 번호를 입력해 주세요"); + try { + return Arrays.stream(Console.readLine().split(",")) // , 단위로 구분 + .map(Integer::parseInt) // 각 요소 Integer로 + .collect(Collectors.toList()); // 리스트로 변환 스트림 사용법 다시 익히기 + } catch (NumberFormatException numberFormatException) { //입력 관련 오류 처리 + throw new IllegalArgumentException("[ERROR] 숫자가 아닌 값이 입력됐습니다."); + } + } + //보너스 번호 입력 + + public static int getBonusNumber() { + System.out.println("보너스 번호를 입력해 주세요"); + try { + return Integer.parseInt(Console.readLine()); + } catch(NumberFormatException numberFormatException) { //입력 관련 오류 처리 + throw new IllegalArgumentException("[ERROR] 숫자가 아닌 값이 입력됐습니다."); + } + } +} diff --git a/src/main/java/lotto/WinningRank.java b/src/main/java/lotto/WinningRank.java new file mode 100644 index 0000000..6c25038 --- /dev/null +++ b/src/main/java/lotto/WinningRank.java @@ -0,0 +1,58 @@ +package lotto; + +import java.util.Arrays; +import java.util.EnumMap; +import java.util.Map; + +public enum WinningRank{ //코드 중 15줄 안에 해결되지 않는 메소드가 있어 다른 분 코드 참고하여 열거형 생성, + LAST_PLACE(0, false, 0), + FIFTH_PLACE(3, false,5_000), + + FOURTH_PLACE(4,false,50_000), + THIRD_PLACE(5,false,1_500_500), + SECOND_PLACE(5,true,30_000_000), + FIRST_PLACE(6,false,2_000_000_000); + + private final int matchingCount; + private final boolean containsBonusNumber; + + + + private final int winningPrice; + private static final Map winningInfo = new EnumMap(WinningRank.class); + WinningRank(int matchingCount, boolean containsBonusNumber, int winningPrice) { + this.matchingCount = matchingCount; + this.containsBonusNumber = containsBonusNumber; + this.winningPrice = winningPrice; + } + + public static WinningRank findWinningRank(int matchingCount, boolean containsBonusNumber){ + return Arrays.stream(values()) + .filter(winningRank -> winningRank.matchingCount == matchingCount) + .filter(winningRank -> winningRank.containsBonusNumber == containsBonusNumber) + .findFirst() + .orElse(WinningRank.LAST_PLACE); + } + + /* public int getWinningCount(Map winningInfo, int key){ + return winningInfo.get(key); + }*/ + //enum 판별 후 갯수 파악 + public static Map findWinningCounts(Map lottoResult){ + for(Map.Entryentry : lottoResult.entrySet()) { + int key = entry.getKey(); + boolean value = entry.getValue(); + winningInfo.put(findWinningRank(key,value), 0); + } + for(Map.Entryentry : lottoResult.entrySet()){ + int key = entry.getKey(); + boolean value = entry.getValue(); + WinningRank winningRank = WinningRank.findWinningRank(key, value); + winningInfo.put(findWinningRank(key,value), winningInfo.get(findWinningRank(key,value)) + 1); + } + return winningInfo; + } + public int getWinningPrice() { + return winningPrice; + } +} \ No newline at end of file diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 0f3af0f..dbd71ee 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -18,10 +18,15 @@ void createLottoByOverSize() { @DisplayName("로또 번호에 중복된 숫자가 있으면 예외가 발생한다.") @Test void createLottoByDuplicatedNumber() { - // TODO: 이 테스트가 통과할 수 있게 구현 코드 작성 + // TODO: 이 테스트가 통과할 수 있게 구현 코드 작성)(완료) assertThatThrownBy(() -> new Lotto(List.of(1, 2, 3, 4, 5, 5))) .isInstanceOf(IllegalArgumentException.class); } - // 아래에 추가 테스트 작성 가능 + + @DisplayName("로또 번호 일치 갯수가 일치하지 않으면 예외가 발생한다") + @Test + void 로또_번호_일치_갯수_확인() { + + } }