Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package lotto;
import lotto.controller.lottoController;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
lottoController controller = new lottoController();
controller.run();
}
}
}
36 changes: 36 additions & 0 deletions src/main/java/lotto/controller/lottoController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package lotto.controller;

import lotto.model.*;
import lotto.view.LottoView;

import java.util.*;

public class lottoController {
private final LottoView view = new LottoView();

public void run() {
try {
int money = view.askMoney();
List<Lotto> tickets = generateTickets(money / 1000);
view.printTickets(tickets);

Set<Integer> winning = view.askWinningNumbers();
int bonus = view.askBonusNumber(winning);

LottoResult result = evaluate(tickets, winning, bonus);
view.printResult(result, money);
} catch (IllegalArgumentException e) {
view.printError(e.getMessage());
}
}

private List<Lotto> generateTickets(int count) {
return LottoGenerator.generateMultiple(count);
}

private LottoResult evaluate(List<Lotto> tickets, Set<Integer> win, int bonus) {
LottoResult result = new LottoResult();
tickets.forEach(ticket -> result.add(ticket, win, bonus));
return result;
}
}
45 changes: 45 additions & 0 deletions src/main/java/lotto/model/Lotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package lotto.model;

import java.util.*;

public class Lotto {
private static final int SIZE = 6;
private static final int MIN = 1;
private static final int MAX = 45;
private final List<Integer> numbers;

public Lotto(List<Integer> numbers) {
validate(numbers);
this.numbers = sorted(numbers);
}

private void validate(List<Integer> numbers) {
if (numbers.size() != SIZE)
throw new IllegalArgumentException("[ERROR] 로또 번호는 6개여야 합니다.");
if (new HashSet<>(numbers).size() != SIZE)
throw new IllegalArgumentException("[ERROR] 중복되지 않은 번호여야 합니다.");
if (!numbers.stream().allMatch(n -> n >= MIN && n <= MAX))
throw new IllegalArgumentException("[ERROR] 번호는 1~45 사이여야 합니다.");
}

private List<Integer> sorted(List<Integer> numbers) {
return numbers.stream().sorted().toList();
}

public int matchCount(Set<Integer> winning) {
return (int) numbers.stream().filter(winning::contains).count();
}

public boolean hasBonus(int bonus) {
return numbers.contains(bonus);
}

public List<Integer> getNumbers() {
return List.copyOf(numbers);
}

@Override
public String toString() {
return numbers.toString();
}
}
22 changes: 22 additions & 0 deletions src/main/java/lotto/model/LottoGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package lotto.model;

import java.util.*;

public class LottoGenerator {
public static Lotto generate() {
Set<Integer> set = new HashSet<>();
Random rand = new Random();
while (set.size() < 6) {
set.add(rand.nextInt(45) + 1);
}
return new Lotto(new ArrayList<>(set));
}

public static List<Lotto> generateMultiple(int count) {
List<Lotto> list = new ArrayList<>();
for (int i = 0; i < count; i++) {
list.add(generate());
}
return list;
}
}
34 changes: 34 additions & 0 deletions src/main/java/lotto/model/LottoResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package lotto.model;

import java.util.*;

public class LottoResult {
private final Map<PrizeTier, Integer> results = new LinkedHashMap<>();
private int totalPrize = 0;

public LottoResult() {
for (PrizeTier tier : PrizeTier.values()) {
results.put(tier, 0);
}
}

public void add(Lotto lotto, Set<Integer> winning, int bonus) {
int match = lotto.matchCount(winning);
boolean hasBonus = lotto.hasBonus(bonus);
PrizeTier tier = PrizeTier.valueOf(match, hasBonus);
if (tier == null) return;

results.put(tier, results.get(tier) + 1);
totalPrize += tier.getPrize();
}

public void printStats() {
results.forEach((tier, count) ->
System.out.printf("%s - %d개%n", tier.getLabel(), count)
);
}

public int getTotalPrize() {
return totalPrize;
}
}
36 changes: 36 additions & 0 deletions src/main/java/lotto/model/PrizeTier.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package lotto.model;

public enum PrizeTier {
FIRST(6, false, 2_000_000_000, "6개 일치 (2,000,000,000원)"),
SECOND(5, true, 30_000_000, "5개 일치, 보너스 볼 일치 (30,000,000원)"),
THIRD(5, false, 1_500_000, "5개 일치 (1,500,000원)"),
FOURTH(4, false, 50_000, "4개 일치 (50,000원)"),
FIFTH(3, false, 5_000, "3개 일치 (5,000원)");

private final int match;
private final boolean bonus;
private final int prize;
private final String label;

PrizeTier(int match, boolean bonus, int prize, String label) {
this.match = match;
this.bonus = bonus;
this.prize = prize;
this.label = label;
}

public static PrizeTier valueOf(int match, boolean hasBonus) {
for (PrizeTier tier : values()) {
if (tier.match == match && tier.bonus == hasBonus) return tier;
}
return null;
}

public String getLabel() {
return label;
}

public int getPrize() {
return prize;
}
}
55 changes: 55 additions & 0 deletions src/main/java/lotto/view/LottoView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package lotto.view;

import lotto.model.*;

import java.util.*;

public class LottoView {
private final Scanner sc = new Scanner(System.in);

public int askMoney() {
System.out.println("로또 구입 금액을 입력해 주세요.");
int money = Integer.parseInt(sc.nextLine());
if (money % 1000 != 0)
throw new IllegalArgumentException("[ERROR] 구입 금액은 1,000원 단위여야 합니다.");
return money;
}

public void printTickets(List<Lotto> tickets) {
System.out.printf("%n%d개를 구매했습니다.%n", tickets.size());
tickets.forEach(System.out::println);
}

public Set<Integer> askWinningNumbers() {
System.out.println("\n당첨 번호를 입력해 주세요.");
String[] tokens = sc.nextLine().split(",");
Set<Integer> numbers = new HashSet<>();
for (String token : tokens) {
int n = Integer.parseInt(token.trim());
if (n < 1 || n > 45) throw new IllegalArgumentException("[ERROR] 당첨 번호는 1~45 사이여야 합니다.");
if (!numbers.add(n)) throw new IllegalArgumentException("[ERROR] 중복된 번호입니다.");
}
if (numbers.size() != 6)
throw new IllegalArgumentException("[ERROR] 당첨 번호는 6개여야 합니다.");
return numbers;
}

public int askBonusNumber(Set<Integer> winning) {
System.out.println("\n보너스 번호를 입력해 주세요.");
int bonus = Integer.parseInt(sc.nextLine());
if (bonus < 1 || bonus > 45 || winning.contains(bonus))
throw new IllegalArgumentException("[ERROR] 보너스 번호는 1~45 범위이며 당첨 번호와 중복되지 않아야 합니다.");
return bonus;
}

public void printResult(LottoResult result, int money) {
System.out.println("\n당첨 통계\n---");
result.printStats();
double rate = ((double) result.getTotalPrize() / money) * 100;
System.out.printf("총 수익률은 %.1f%%입니다.%n", rate);
}

public void printError(String msg) {
System.out.println(msg);
}
}