diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922b..04b7dbb3 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,8 @@ -package lotto; +import Controller.Controller; public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + Controller lottoController = new Controller(); + lottoController.run(); } } diff --git a/src/main/java/lotto/Controller/Controller.java b/src/main/java/lotto/Controller/Controller.java new file mode 100644 index 00000000..6779a2d3 --- /dev/null +++ b/src/main/java/lotto/Controller/Controller.java @@ -0,0 +1,57 @@ +package lotto.Controller; + +import Domain.LottoResult; +import Domain.LottoTicketMachine; +import Domain.WinningLotto; +import View.InputView; +import View.OutputView; +import java.util.List; +import java.util.ArrayList; +import Domain.Lottos; + +public class Controller { + private final OutputView outputView; + private final InputView inputView; + + public Controller() { + this.outputView = new OutputView(); + this.inputView = new InputView(); + } + + private int setMoney(){ + return inputView.inputMoney(); + //유효성 검사 + } + + private List setNum(){ + //유효성 검사 + String[] arr = inputView.inputNum(); + List arr2 = new ArrayList<>(); + for(int i = 0; i < arr.length; i++){ + arr2.add(Integer.parseInt(arr[i])); + } + return arr2; + } + + private int setBonus(){ + return inputView.inputBonusNum(); + } + + + public void run(){ + int money = setMoney(); //구입 금액 입력 + LottoTicketMachine lottoTicketMachine = new LottoTicketMachine(money); + outputView.getHowMany(money); //구매 개수 출력 + Lottos lottos= lottoTicketMachine.execute(); //로또 번호 생성 + outputView.getLottoNum(lottos.getLottos()); //로또 번호 출력 + List winningNum = setNum(); //당첨 번호 입력 + int bonusNum = setBonus(); //보너스 번호 입력 + WinningLotto winningLotto = new WinningLotto(winningNum, bonusNum); + LottoResult lottoResult = lottos.rankAll(winningLotto); + outputView.getResult(lottoResult); + outputView.getYield(lottoResult, money); + + } + + +} diff --git a/src/main/java/lotto/Domain/Lotto.java b/src/main/java/lotto/Domain/Lotto.java new file mode 100644 index 00000000..31b7a77e --- /dev/null +++ b/src/main/java/lotto/Domain/Lotto.java @@ -0,0 +1,48 @@ +package lotto.Domain; + +import java.util.List; + +public class Lotto { + private final List numbers; + + public Lotto(List numbers) { + validate(numbers); + this.numbers = numbers; + } + + private void validate(List numbers) { + if(numbers.size() != 6) { + throw new IllegalArgumentException("[ERROR] 로또 번호는 6개여야 합니다."); + } + if(numbers.stream().distinct().count() != 6){ + throw new IllegalArgumentException("[ERROR] 로또 번호에 중복된 숫자가 있습니다."); + } + if (numbers.stream().anyMatch(num -> num < 1 || num > 45)) { + throw new IllegalArgumentException("[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다."); + } + } + + public Rank determineRank(WinningLotto winningLotto) { + int matchCount = 0; + boolean bonus = false; + + for(int i : this.numbers) { + if(winningLotto.getWinningNum().contains(i)){ + matchCount++; + } + } + + for(int i : this.numbers) { + if(i == winningLotto.getWinningBonusNum()){ + bonus = true; + } + } + + return Rank.valueOf(matchCount, bonus); + } + + public String toString(){ + return numbers.toString(); + } + +} diff --git a/src/main/java/lotto/Domain/LottoResult.java b/src/main/java/lotto/Domain/LottoResult.java new file mode 100644 index 00000000..e441d8d8 --- /dev/null +++ b/src/main/java/lotto/Domain/LottoResult.java @@ -0,0 +1,33 @@ +package lotto.Domain; + +import java.util.Map; +import java.util.HashMap; + +public class LottoResult { + private Map ranks; + + + public LottoResult(Map ranks) { + this.ranks = ranks; + } + + public int getYield() { + int totalMoney = 0; + for(Rank rank : ranks.keySet()) { + totalMoney += rank.getPrizeMoney() * ranks.get(rank); + } + return totalMoney; + } + + public Map getRanks() { + return ranks; + } + + public double calculateYield(int purchaseAmount) { + if (purchaseAmount == 0) { + return 0.0; + } + return (double) getYield() / purchaseAmount * 100; + } + +} diff --git a/src/main/java/lotto/Domain/LottoTicketMachine.java b/src/main/java/lotto/Domain/LottoTicketMachine.java new file mode 100644 index 00000000..d7e4da1c --- /dev/null +++ b/src/main/java/lotto/Domain/LottoTicketMachine.java @@ -0,0 +1,48 @@ +package lotto.Domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.Collections; + +public class LottoTicketMachine { + private int lottoCount; + + public LottoTicketMachine(int money) { + validate(money); + this.lottoCount = money / 1000; + } + + private void validate(int money) { + if (money % 1000 != 0) { + throw new IllegalArgumentException("[ERROR] 구입 금액은 1,000원 단위여야 합니다."); + } + if (money <= 0) { + throw new IllegalArgumentException("[ERROR] 구입 금액은 0보다 커야 합니다."); + } + } + + + public List getRandomNum(){ + List numbers = new ArrayList<>(); + for(int i = 0; i < 45; i++){ + numbers.add(i+1); + } + Collections.shuffle(numbers); //1~45까지 무작위 섞기 + List lottoNumbers = new ArrayList<>(numbers.subList(0, 6)); + Collections.sort(lottoNumbers); + return lottoNumbers; + } + + public Lottos execute(){ + List lottos = new ArrayList<>(); + + for(int i = 0; i < lottoCount; i++){ + List numbers = getRandomNum(); + Lotto lotto = new Lotto(numbers); + lottos.add(lotto); + } + + return new Lottos(lottos); + } + +} diff --git a/src/main/java/lotto/Domain/Lottos.java b/src/main/java/lotto/Domain/Lottos.java new file mode 100644 index 00000000..5c0a2daf --- /dev/null +++ b/src/main/java/lotto/Domain/Lottos.java @@ -0,0 +1,29 @@ +package lotto.Domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.HashMap; + +public class Lottos { + private List lottos = new ArrayList<>(); + + public Lottos(List lottos) { + this.lottos = lottos; + } + + public List getLottos() { + return lottos; + } + + public LottoResult rankAll(WinningLotto winningLotto) { + Map rankMap = new HashMap<>(); + for (Lotto lotto : lottos) { + Rank rank = lotto.determineRank(winningLotto); + //해당 rank에 누적 더하기 + rankMap.put(rank, rankMap.getOrDefault(rank, 0) + 1); + } + return new LottoResult(rankMap); + } + +} diff --git a/src/main/java/lotto/Domain/Rank.java b/src/main/java/lotto/Domain/Rank.java new file mode 100644 index 00000000..184c4ebf --- /dev/null +++ b/src/main/java/lotto/Domain/Rank.java @@ -0,0 +1,45 @@ +package lotto.Domain; + +public enum Rank { + FIRST(6, 2_000_000_000), + SECOND(5, 30_000_000), + THIRD(5, 1_500_000), + FOURTH(4, 50_000), + FIFTH(3, 5_000), + NONE(0, 0); + + private final int matchNum; + private final int prizeMoney; + + private Rank(int matchNum, int prizeMoney) { + this.matchNum = matchNum; + this.prizeMoney = prizeMoney; + } + + public int getMatchNum() { + return matchNum; + } + + public int getPrizeMoney() { + return prizeMoney; + } + + public static Rank valueOf(int matchNum, boolean matchBonus){ + if(matchNum == 6){ + return FIRST; + } + if(matchNum == 5 && matchBonus){ + return SECOND; + } + if(matchNum == 5){ + return THIRD; + } + if(matchNum == 4){ + return FOURTH; + } + if(matchNum == 3){ + return FIFTH; + } + return NONE; + } +} diff --git a/src/main/java/lotto/Domain/WinningLotto.java b/src/main/java/lotto/Domain/WinningLotto.java new file mode 100644 index 00000000..e160f745 --- /dev/null +++ b/src/main/java/lotto/Domain/WinningLotto.java @@ -0,0 +1,40 @@ +package lotto.Domain; + +import java.util.List; + +public class WinningLotto { + private List winningNum; + private int winningBonusNum; + + public WinningLotto(List winningNum, int winningBonusNum) { + validate(winningNum, winningBonusNum); + this.winningNum = winningNum; + this.winningBonusNum = winningBonusNum; + } + + private void validate(List winningNum, int winningBonusNum) { + if (winningNum.size() != 6) { + throw new IllegalArgumentException("[ERROR] 당첨 번호는 6개여야 합니다."); + } + if (winningNum.stream().distinct().count() != 6) { + throw new IllegalArgumentException("[ERROR] 당첨 번호에 중복된 숫자가 있습니다."); + } + if (winningNum.stream().anyMatch(num -> num < 1 || num > 45)) { + throw new IllegalArgumentException("[ERROR] 당첨 번호는 1부터 45 사이의 숫자여야 합니다."); + } + if (winningNum.contains(winningBonusNum)) { + throw new IllegalArgumentException("[ERROR] 보너스 번호는 당첨 번호와 중복될 수 없습니다."); + } + if (winningBonusNum < 1 || winningBonusNum > 45) { + throw new IllegalArgumentException("[ERROR] 보너스 번호는 1부터 45 사이의 숫자여야 합니다."); + } + } + + public List getWinningNum() { + return winningNum; + } + + public int getWinningBonusNum(){ + return winningBonusNum; + } +} diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java deleted file mode 100644 index 519793d1..00000000 --- a/src/main/java/lotto/Lotto.java +++ /dev/null @@ -1,20 +0,0 @@ -package lotto; - -import java.util.List; - -public class Lotto { - private final List numbers; - - public Lotto(List numbers) { - validate(numbers); - this.numbers = numbers; - } - - private void validate(List numbers) { - if (numbers.size() != 6) { - throw new IllegalArgumentException(); - } - } - - // TODO: 추가 기능 구현 -} diff --git a/src/main/java/lotto/View/InputView.java b/src/main/java/lotto/View/InputView.java new file mode 100644 index 00000000..ef08f9b0 --- /dev/null +++ b/src/main/java/lotto/View/InputView.java @@ -0,0 +1,25 @@ +package lotto.View; + +import java.util.Scanner; + +public class InputView { + public final Scanner sc = new Scanner(System.in); + + public int inputMoney(){ + System.out.println("구입 금액을 입력해 주세요."); + int money = Integer.parseInt(sc.nextLine()); + return money; + + } + + public String[] inputNum(){ + System.out.println("당첨 번호를 입력해 주세요."); + return sc.nextLine().split(","); + } + + public int inputBonusNum(){ + System.out.println("보너스 번호를 입력해 주세요."); + return Integer.parseInt(sc.nextLine()); + } + +} diff --git a/src/main/java/lotto/View/OutputView.java b/src/main/java/lotto/View/OutputView.java new file mode 100644 index 00000000..8b92a92a --- /dev/null +++ b/src/main/java/lotto/View/OutputView.java @@ -0,0 +1,36 @@ +package lotto.View; + +import Domain.LottoResult; +import Domain.Rank; +import Domain.Lotto; +import java.util.List; +import java.util.Map; + +public class OutputView { + + public void getHowMany(int money){ + System.out.println("\n" + money/1000 + "개를 구매했습니다."); + } + + public void getLottoNum(List lottoNum){ + for(Lotto lotto : lottoNum){ + System.out.println(lotto); + } + } + + public void getResult(LottoResult result){ + Map ranks = result.getRanks(); + + System.out.println("당첨 통계\n---"); + System.out.println("3개 일치 (5,000원) - " + ranks.getOrDefault(Rank.FIFTH, 0) + "개"); + System.out.println("4개 일치 (50,000원) - " + ranks.getOrDefault(Rank.FOURTH, 0) + "개"); + System.out.println("5개 일치 (1,500,000원) - " + ranks.getOrDefault(Rank.THIRD, 0) + "개"); + System.out.println("5개 일치, 보너스 볼 일치 (30,000,000원) - " + ranks.getOrDefault(Rank.SECOND, 0) + "개"); + System.out.println("6개 일치 (2,000,000,000원) - " + ranks.getOrDefault(Rank.FIRST, 0) + "개"); + } + + public void getYield(LottoResult result, int purchaseAmount){ + System.out.println("총 수익률은 " + String.format("%.1f", result.calculateYield(purchaseAmount)) + "입니다."); + } + +} \ No newline at end of file