Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
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
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,33 @@
로또 미션 저장소

# [미션 리드미](https://github.com/talmood/private-mission-README/tree/main/%EB%AF%B8%EC%85%98%203%20-%20%EB%A1%9C%EB%98%90)

# 미션 1 - 로또
## 기능 요구 사항
- 로또 구입 금액을 입력 받는다.
- 로또 구입 금액은 숫자여야 한다.
- 로또 한 장의 가격은 1000원이다.
- 최소 구입 금액은 1000원이다.
- 로또 구입 금액은 1000원 단위여야 한다.
- 로또 구입 금액만큼 로또를 발급한다.
- 로또 한 장의 가격은 1000원이다.
- 로또 1장은 6개의 랜덤 숫자를 가진다.
- 로또 숫자는 1부터 45까지의 숫자이다.
- 로또 숫자는 중복되지 않는다.
- 로또 숫자는 오름차순으로 정렬되어 있다.
- 지난주 당첨 번호를 입력 받는다.
- 지난주 당첨 번호는 1부터 45까지의 숫자이다.
- 지난주 당첨 번호는 중복되지 않는다.
- 지난주 당첨 번호는 오름차순으로 정렬되어 있다.
- 지난 주 보너스 볼을 입력 받는다.
- 보너스 볼은 1부터 45까지의 숫자이다.
- 보너스 볼은 지난주 당첨 번호와 중복되지 않는다.
- 보너스 볼은 오름차순으로 정렬되어 있다.
- 당첨 통계를 출력한다.
- 3개 일치, 4개 일치, 5개 일치, 5개 일치 + 보너스 볼 일치, 6개 일치의 당첨 통계를 출력한다.
- 당첨 통계는 로또 당첨 금액을 기준으로 한다.
- 당첨 통계는 로또 당첨 개수를 기준으로 한다.
- 당첨 통계는 로또 당첨 금액과 로또 당첨 개수를 출력한다.
- 총 수익률을 계산한다.
- 총 수익률은 (총 당첨 금액 - 로또 구입 금액) / 로또 구입 금액으로 계산한다.
- 총 수익률은 소수점 둘째 자리까지 출력한다. (소수점 셋째 자리에서 버림 처리한다.)
10 changes: 10 additions & 0 deletions src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package lotto;

import lotto.controller.LottoMachine;

public class Application {

public static void main(String[] args) {
LottoMachine.run();
}
}
10 changes: 10 additions & 0 deletions src/main/java/lotto/constrant/LottoConstant.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package lotto.constrant;

public class LottoConstant {
private LottoConstant() {
}
public static final int LOTTO_PRICE = 1000;
public static final int LOTTO_NUMBER_SIZE = 6;
public static final int MIN_LOTTO_NUMBER = 1;
public static final int MAX_LOTTO_NUMBER = 45;
}
46 changes: 46 additions & 0 deletions src/main/java/lotto/controller/LottoGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package lotto.controller;

import lotto.domain.LottoNumber;
import lotto.domain.LottoNumbers;
import lotto.domain.PurchasedLotto;

import java.util.*;

public class LottoGenerator {

private static final int LOTTO_NUMBER_SIZE = 6;

private final List<Integer> candidateLottoNumbers;

public LottoGenerator() {
this.candidateLottoNumbers = initializeCandidateNumbers();
}

private List<Integer> initializeCandidateNumbers() {
final List<Integer> lottoNumbers = new ArrayList<>();
for (int i = 1; i <= 45; i++) {
lottoNumbers.add(i);
}
return lottoNumbers;
}

public List<PurchasedLotto> generatePurchasedLottos(final int purchaseCount) {
final List<PurchasedLotto> purchasedLottos = new ArrayList<>();
for (int i = 0; i < purchaseCount; i++) {
purchasedLottos.add(generatePurchasedLotto());
}
return purchasedLottos;
}

private PurchasedLotto generatePurchasedLotto() {
final List<Integer> shuffledNumbers = new ArrayList<>(candidateLottoNumbers);
Collections.shuffle(shuffledNumbers);

final List<LottoNumber> lottoNumbers = shuffledNumbers.stream()
.limit(LOTTO_NUMBER_SIZE)
.map(LottoNumber::from)
.toList();

return PurchasedLotto.from(LottoNumbers.from(lottoNumbers));
}
}
54 changes: 54 additions & 0 deletions src/main/java/lotto/controller/LottoMachine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package lotto.controller;

import lotto.domain.PurchasedLotto;
import lotto.domain.WinningLotto;
import lotto.domain.prize.PrizeResult;
import lotto.request.LastWeekWinningLottoRequest;
import lotto.request.LottoPurchaseRequest;
import lotto.view.InputView;
import lotto.view.ResultView;

import java.util.List;

public class LottoMachine {

private LottoMachine() {
}

public static void run() {
final int purchaseCount = inputPurchaseAmount();
printPurchaseAmount(purchaseCount);
final List<PurchasedLotto> purchasedLottos = generateLottoNumbers(purchaseCount);

final WinningLotto winningLotto = inputLastWeekWinningNumbers();

printWinningStatistics(purchasedLottos, winningLotto);
}

private static int inputPurchaseAmount() {
final LottoPurchaseRequest lottoPurchaseRequest = InputView.inputPurchaseAmount();
return lottoPurchaseRequest.calculatePurchaseCount();
}

private static List<PurchasedLotto> generateLottoNumbers(final int purchaseCount) {
final LottoGenerator lottoGenerator = new LottoGenerator();
final List<PurchasedLotto> purchasedLottos = lottoGenerator.generatePurchasedLottos(purchaseCount);
ResultView.printPurchasedLottos(purchasedLottos);
return purchasedLottos;
}

private static WinningLotto inputLastWeekWinningNumbers() {
final LastWeekWinningLottoRequest lastWeekWinningLottoRequest = InputView.inputLastWeekWinningNumbers();
return lastWeekWinningLottoRequest.generateWinningLotto();
}

private static void printPurchaseAmount(final int purchaseAmount) {
ResultView.printPurchaseAmount(purchaseAmount);
}

private static void printWinningStatistics(final List<PurchasedLotto> purchasedLottos, final WinningLotto winningLotto) {
final PrizeResult prizeResult = PrizeResult.from(purchasedLottos, winningLotto);
ResultView.printWinningStatistics(prizeResult);
}

}
43 changes: 43 additions & 0 deletions src/main/java/lotto/domain/LottoNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package lotto.domain;

import java.util.Objects;

import static lotto.constrant.LottoConstant.MAX_LOTTO_NUMBER;
import static lotto.constrant.LottoConstant.MIN_LOTTO_NUMBER;

public class LottoNumber {

private final int number;

private LottoNumber(final int number) {
validate(number);
this.number = number;
}

public static LottoNumber from(final int number) {
return new LottoNumber(number);
}

private static void validate(final int number) {
if (number < MIN_LOTTO_NUMBER || number > MAX_LOTTO_NUMBER) {
throw new IllegalArgumentException("로또 번호는 1부터 45까지의 숫자만 가능합니다.");
}
}

public int getNumber() {
return number;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LottoNumber that = (LottoNumber) o;
return number == that.number;
}

@Override
public int hashCode() {
return Objects.hash(number);
}
}
48 changes: 48 additions & 0 deletions src/main/java/lotto/domain/LottoNumbers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package lotto.domain;

import java.util.List;
import java.util.Set;

import static lotto.constrant.LottoConstant.LOTTO_NUMBER_SIZE;

public class LottoNumbers {

private final List<LottoNumber> numbers;

private LottoNumbers(final List<LottoNumber> numbers) {
validateSize(numbers);
validateDuplicate(numbers);
this.numbers = numbers;
}

public static LottoNumbers from(final List<LottoNumber> numbers) {
return new LottoNumbers(numbers);
}

private void validateSize(final List<LottoNumber> numbers) {
if (numbers.size() != LOTTO_NUMBER_SIZE) {
throw new IllegalArgumentException("로또 번호는 6개여야 합니다.");
}
}

private void validateDuplicate(final List<LottoNumber> numbers) {
final Set<LottoNumber> lottoNumberSet = Set.copyOf(numbers);
if (lottoNumberSet.size() != LOTTO_NUMBER_SIZE) {
throw new IllegalArgumentException("로또 번호는 중복될 수 없습니다.");
}
}

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

public int calculateMatchCounts(final List<LottoNumber> winningNumbers) {
return (int) numbers.stream()
.filter(winningNumbers::contains)
.count();
}

public boolean containsBonusNumber(final LottoNumber bonusNumber) {
return numbers.contains(bonusNumber);
}
}
27 changes: 27 additions & 0 deletions src/main/java/lotto/domain/PurchasedLotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package lotto.domain;

import java.util.Objects;

public class PurchasedLotto {

private final LottoNumbers lottoNumbers;

private PurchasedLotto(final LottoNumbers lottoNumbers) {
validate(lottoNumbers);
this.lottoNumbers = lottoNumbers;
}

public static PurchasedLotto from(final LottoNumbers lottoNumbers) {
return new PurchasedLotto(lottoNumbers);
}

private static void validate(final LottoNumbers lottoNumbers) {
if (Objects.isNull(lottoNumbers)) {
throw new IllegalArgumentException("lotto numbers must not be null");
}
}

public LottoNumbers getLottoNumbers() {
return lottoNumbers;
}
}
32 changes: 32 additions & 0 deletions src/main/java/lotto/domain/WinningLotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package lotto.domain;

import java.util.List;

public class WinningLotto {
private final LottoNumbers lottoNumbers;
private final LottoNumber bonusNumber;

private WinningLotto(final LottoNumbers lottoNumbers, final LottoNumber bonusNumber) {
validate(lottoNumbers, bonusNumber);
this.lottoNumbers = lottoNumbers;
this.bonusNumber = bonusNumber;
}

public static WinningLotto of(final LottoNumbers lottoNumbers, final LottoNumber bonusNumber) {
return new WinningLotto(lottoNumbers, bonusNumber);
}

public static void validate(final LottoNumbers lottoNumbers, final LottoNumber bonusNumber) {
if (lottoNumbers.getNumbers().contains(bonusNumber)) {
throw new IllegalArgumentException("보너스 번호는 당첨 번호와 중복될 수 없습니다.");
}
}

public List<LottoNumber> getLottoNumbers() {
return List.copyOf(lottoNumbers.getNumbers());
}

public LottoNumber getBonusNumber() {
return bonusNumber;
}
}
40 changes: 40 additions & 0 deletions src/main/java/lotto/domain/prize/Prize.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package lotto.domain.prize;

public enum Prize {
NONE(0, false, 0),
FIFTH(3, false, 5000),
FOURTH(4, false, 50000),
THIRD(5, false, 1500000),
SECOND(5, true, 30000000),
FIRST(6, false, 2000000000);

private final int matchCount;
private final boolean matchBonus;
private final int money;

Prize(final int matchCount, final boolean matchBonus, final int money) {
this.matchCount = matchCount;
this.matchBonus = matchBonus;
this.money = money;
}

public static Prize of(final int matchCount, final boolean matchBonus) {
if (matchCount == SECOND.matchCount && matchBonus) {
return SECOND;
}
for (final Prize prize : values()) {
if (prize.matchCount == matchCount) {
return prize;
}
}
return NONE;
}

public int getMatchCount() {
return matchCount;
}

public int getMoney() {
return money;
}
}
Loading