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: 6 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- 로또 1개 클래스
- 로또 n개 묶음 클래스
- 로또 발행기? (입력받은 가격만큼 생성, 가격 안 맞으면 오류)
- 당첨번호 입력 (6자리인지, 중복 없는지, 1~45의 숫자인지)
- 당첨내역 확인 (몇 개가 일치하는지.. 어떻게하지)
- 수익률
4 changes: 4 additions & 0 deletions src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package lotto;

import lotto.controller.LottoController;

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

import org.kokodak.Console;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class InputView {

private static final String INVALID_VALUE = "[ERROR] 올바른 값을 입력하세요.";

public static int getPurchaseAmount() {
System.out.println("구입금액을 입력해 주세요.");
try {
return Integer.parseInt(Console.readLine());
} catch (NumberFormatException numberFormatException) {
throw new IllegalArgumentException(INVALID_VALUE);
}
}

// 찾아볼필요 ㅇ
public static List<Integer> getWinningNums() {
System.out.println("당첨 번호를 입력해 주세요.");
try {
return Arrays.stream(Console.readLine().split(","))
.map(Integer::parseInt)
.collect(Collectors.toList());
} catch (NumberFormatException numberFormatException) {
throw new IllegalArgumentException(INVALID_VALUE);
}

}

public static int getBonusNum() {
System.out.println("보너스 번호를 입력해 주세요.");
try {
return Integer.parseInt(Console.readLine());
} catch (NumberFormatException numberFormatException) {
throw new IllegalArgumentException(INVALID_VALUE);
}
}
}
59 changes: 59 additions & 0 deletions src/main/java/lotto/View/OutputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package lotto.View;

import lotto.domain.Lottos;
import lotto.service.WinningRank;

import java.text.DecimalFormat;
import java.util.Map;

public class OutputView {

private static final String WINNING_DETAILS_MESSAGE = "%d개 일치 (%s원) - %d개\n";
private static final String WINNING_DETAILS_MESSAGE_WITH_BONUS_MASSAGE = "%d개 일치, 보너스 볼 일치 (%s원) - %d개\n";

public static void printHowManyLottoUserPurchased(int lottoQuantity) {
System.out.println(lottoQuantity + "개를 구매했습니다.");
}

public static void printLottos(Lottos lottos) {
lottos.getLottos()
.forEach(lotto -> System.out.println(lotto.getNumbers().toString()));
}

public static void printWinningDetails(Map<WinningRank, Integer> winningDetails) {
System.out.println("당첨 통계");
System.out.println("---");
winningDetails.entrySet().stream()
.filter(entry->entry.getKey()!=WinningRank.LAST_PLACE)
.forEach(entry->{
if (entry.getKey() == WinningRank.SECOND_PLACE){
printWinningDetailsWithBonus(entry);
}
printWinningDetails(entry);
});
}

public static void printProfitRate(double profitRate) {
System.out.printf("총 수익률은 %.1f%%입니다.\n", profitRate);
}


private static void printWinningDetails(Map.Entry<WinningRank, Integer> entry) {
System.out.printf(WINNING_DETAILS_MESSAGE,
entry.getKey().getMatchCount(),
getFormattingPrice(entry.getKey().getPrize()),
entry.getValue());
}

private static void printWinningDetailsWithBonus(Map.Entry<WinningRank, Integer> entry) {
System.out.printf(WINNING_DETAILS_MESSAGE_WITH_BONUS_MASSAGE,
entry.getKey().getMatchCount(),
getFormattingPrice(entry.getKey().getPrize()),
entry.getValue());
}

private static String getFormattingPrice(int prize) {
DecimalFormat df = new DecimalFormat("###,###");
return df.format(prize);
}
}
33 changes: 33 additions & 0 deletions src/main/java/lotto/controller/LottoController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package lotto.controller;

import lotto.View.InputView;
import lotto.View.OutputView;
import lotto.domain.*;
import lotto.service.LottoGenerator;
import lotto.service.WinningDetails;
import lotto.service.WinningRank;

import java.util.Map;

public class LottoController {

public void lottoStart() {
try {
int money = InputView.getPurchaseAmount(); //금액 입력
LottoGenerator lottoGenerator = new LottoGenerator(money);
Lottos lottos = new Lottos(lottoGenerator.generateLottos()); //개수만큼 로또 생성

OutputView.printHowManyLottoUserPurchased(lottoGenerator.getLottoQuantity());
OutputView.printLottos(lottos); //구매 개수랑 출력

LottoWinningNumber lottoWinningNumber = new LottoWinningNumber(InputView.getWinningNums(), InputView.getBonusNum());
Map<WinningRank, Integer> winningDetails = WinningDetails.getWinningDetails(lottos, lottoWinningNumber);

OutputView.printWinningDetails(winningDetails);
long profit = WinningDetails.getProfit(winningDetails);
OutputView.printProfitRate(WinningDetails.getProfitRate(profit, money)); //당첨결과, 수익률
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package lotto;
package lotto.domain;

import java.util.List;

Expand All @@ -17,4 +17,8 @@ private void validate(List<Integer> numbers) {
}

// TODO: 추가 기능 구현

public List<Integer> getNumbers() {
return numbers;
}
}
54 changes: 54 additions & 0 deletions src/main/java/lotto/domain/LottoWinningNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package lotto.domain;

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

public class LottoWinningNumber {

private final List<Integer> winningNums;
private final int bonusNum;


public LottoWinningNumber(List<Integer> winningNums, int bonusNum) {
// 에러 체크
validateDuplicateNum(winningNums, bonusNum);
isBetween1and45(winningNums, bonusNum);

this.winningNums = winningNums;
this.bonusNum = bonusNum;
}

public List<Integer> getWinningNums() {
return winningNums;
}

public int getBonusNum() {
return bonusNum;
}

// 중복 번호 체크
private void validateDuplicateNum(List<Integer> winningNum, int bonusNum) {
Set<Integer> duplicateCheck = new HashSet<>(winningNum);
if (winningNum.size() != duplicateCheck.size()) {
throw new IllegalArgumentException("[ERROR] 당첨 번호는 서로 다른 6개의 숫자여야 합니다.");
}
if (winningNum.contains(bonusNum)) {
throw new IllegalArgumentException("[ERROR] 당첨 번호와 보너스 번호가 중복됩니다.");
}
}

// 1~45 사이의 번호
private void isBetween1and45(List<Integer> winningNums, int bonusNum) {
for (int num : winningNums) {
if (num < 1 || num > 45) {
throw new IllegalArgumentException("[ERROR] 당첨 번호는 1부터 45 사이의 숫자여야 합니다.");
}
}
if (bonusNum < 1 || bonusNum > 45) {
throw new IllegalArgumentException("[ERROR] 보너스 번호는 1부터 45 사이의 숫자여야 합니다.");
}
}


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

import lotto.domain.Lotto;

import java.util.List;

public class Lottos {

private List<Lotto> lottos;

public Lottos(List<Lotto> lottos) {
this.lottos = lottos;
}

public List<Lotto> getLottos() {
return lottos;
}
}
54 changes: 54 additions & 0 deletions src/main/java/lotto/service/LottoGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package lotto.service;


import lotto.domain.Lotto;
import org.kokodak.Randoms;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;



public class LottoGenerator {

private static final int LOTTO_PRICE = 1000; //로또 1개 1000원

private final List<Lotto> lottos = new ArrayList<>();
private final int lottoQuantity; //로또 개수(양)

public LottoGenerator(int money) {
validateMoney(money);
lottoQuantity = money/LOTTO_PRICE;
}

// 금액만큼 로또 생성
public List<Lotto> generateLottos() {
for (int i = 0; i < lottoQuantity; i++) {
lottos.add(generateLotto());
}
return lottos;
}

// 구입 로또 개수
public int getLottoQuantity() {
return lottoQuantity;
}



// 금액확인
private void validateMoney(int money) {
if (money <= 0 || money % LOTTO_PRICE != 0){
throw new IllegalArgumentException("[ERROR] 로또 구입 단위는 1,000원 단위입니다.");
}
}

// 로또 1개 생성
private Lotto generateLotto() {
List<Integer> numbers = new ArrayList<>(Randoms.pickUniqueNumbersInRange(1, 45, 6));
numbers.sort(Comparator.naturalOrder()); //오름차순
return new Lotto(numbers);
}

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

import lotto.domain.Lotto;
import lotto.domain.LottoWinningNumber;
import lotto.domain.Lottos;

import java.util.Arrays;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;

public class WinningDetails {

public static Map<WinningRank, Integer> getWinningDetails(Lottos lottos, LottoWinningNumber lottoWinningNumber) {
Map<WinningRank, Integer> winningDetails = generateWinningDetails();
for (Lotto lotto : lottos.getLottos()) {
int matchCount = compareWithWinningNums(lotto, lottoWinningNumber);
boolean containsBonusNum = compareWithBonusNum(lotto, lottoWinningNumber, matchCount);
WinningRank winningRank = WinningRank.findWinningRank(matchCount, containsBonusNum);
winningDetails.replace(winningRank, winningDetails.get(winningRank) + 1);
}
return winningDetails;
}

// 찾아볼필요가..
public static long getProfit(Map<WinningRank, Integer> winningDetails) {
return winningDetails.entrySet()
.stream()
.mapToLong(entry -> (long) entry.getKey().getPrize() * entry.getValue())
.sum();
}

// 수익률 구하는 방법이 뭐지
public static double getProfitRate(long profit, int money) {
double profitRate = 100 + (double) (profit - money) / money * 100;
return Math.round(profitRate * 10) * 10.0;
}




private static Map<WinningRank, Integer> generateWinningDetails() {
Map<WinningRank, Integer> winningDetails = new EnumMap<>(WinningRank.class);
Arrays.stream(WinningRank.values())
.forEach(winningRank -> winningDetails.put(winningRank, 0));
return winningDetails;
}


// 로또 1개와 당첨번호 비교, 일치하는 개수 찾기(스트림 필터)
private static int compareWithWinningNums(Lotto lotto, LottoWinningNumber lottoWinningNumber) {
List<Integer> nums = lotto.getNumbers();
List<Integer> winningNums = lottoWinningNumber.getWinningNums();
return (int) nums.stream()
.filter(winningNums::contains)
.count();
}

// 5개 일치 시에만 보너스 번호 필요
private static boolean compareWithBonusNum(Lotto lotto, LottoWinningNumber lottoWinningNumber, int matchCount) {
if (matchCount != 5) {
return false;
}
List<Integer> nums = lotto.getNumbers();
int bonusNum = lottoWinningNumber.getBonusNum();
return nums.contains(bonusNum); //있으면 true 없으면 false return
}

}
Loading