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
4 changes: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ repositories {
}

dependencies {
implementation 'com.github.woowacourse-projects:mission-utils:1.0.0'
implementation 'com.github.kokodak:mission-utils:1.0.0'
implementation 'org.junit.jupiter:junit-jupiter:5.7.2'
testImplementation 'org.assertj:assertj-core:3.20.2'
}

java {
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
4 changes: 3 additions & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
41 changes: 28 additions & 13 deletions gradlew

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 9 additions & 6 deletions gradlew.bat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 55 additions & 1 deletion src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,61 @@
package lotto;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.kokodak.Console;

// controller
public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
try{
// 구입금액 입력 받기
System.out.println("구입금액을 입력해 주세요.");
String purchaseAmountString = Console.readLine();
int purchaseAmount = LottoUtils.verifyPurchaseAmountString(purchaseAmountString);

// 구입한 로또 구매
List<Lotto> lottoSet = LottoService.purchaseLotto(purchaseAmount);

// 당첨번호 받기
System.out.println("당첨번호를 입력해 주세요.");
String winningNumbersString = Console.readLine();
List<Integer> winningNumbers = Arrays.stream(winningNumbersString.split(","))
.map(Integer::parseInt)
.collect(Collectors.toList());
LottoUtils.verifyLottoNumbers(winningNumbers);

// 보너스 번호 입력 받기
System.out.println("보너스 번호를 입력해 주세요.");
int bonusWinningNumber = Integer.parseInt(Console.readLine());
LottoUtils.verifyLottoNumber(bonusWinningNumber);

// 당첨 계산
int[] winningResult = LottoService.calculateWiningResult(lottoSet, winningNumbers, bonusWinningNumber);

// 로또 정보 출력
System.out.printf("%d개를 구매했습니다.\n", lottoSet.size());
for (Lotto lotto : lottoSet) {
lotto.printLotto();
}

// 당첨 통계 출력
System.out.println("당첨 통계");
System.out.println("---");
System.out.println("3개 일치 (5,000원) - " + winningResult[0] + "개");
System.out.println("4개 일치 (50,000원) - " + winningResult[1] + "개");
System.out.println("5개 일치 (1,500,000원) - " + winningResult[2] + "개");
System.out.println("5개 일치, 보너스 볼 일치 (30,000,000원) - " + winningResult[3] + "개");
System.out.println("6개 일치 (2,000,000,000원) - " + winningResult[4] + "개");

// 수익률 계산
int totalPrize = LottoService.getTotalPrize(winningResult);
double profitability = (double) totalPrize / purchaseAmount * 100;
System.out.printf("총 수익률은 %.1f%%입니다.\n", profitability);

}catch (Exception e){
System.out.println(e.getMessage());
}

}
}
19 changes: 13 additions & 6 deletions src/main/java/lotto/Lotto.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
package lotto;

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

public class Lotto {
private final List<Integer> numbers;

// lotto 검증 -> 생성
public Lotto(List<Integer> numbers) {
validate(numbers);
LottoUtils.verifyLottoNumbers(numbers);
this.numbers = numbers;
}

private void validate(List<Integer> numbers) {
if (numbers.size() != 6) {
throw new IllegalArgumentException();
}
// 로또번호 getter
public List<Integer> getNumbers(){
return this.numbers;
}

// TODO: 추가 기능 구현
// 로또번호 출력
public void printLotto(){
System.out.println(
this.numbers.stream()
.sorted()
.collect(Collectors.toList()));
}
}
76 changes: 76 additions & 0 deletions src/main/java/lotto/LottoService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package lotto;

import java.util.ArrayList;
import java.util.List;
import org.kokodak.Randoms;

// service
public class LottoService {
private static final int LOTTO_PRICE = 1000;

// 랜덤 번호 생성 -> Lotto 객체 생성
public static Lotto createRandomLotto() {
List<Integer> numbers = Randoms.pickUniqueNumbersInRange(1, 45, 6);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메서드 인자로 들어가는 1, 45, 6 도 상수처리하면 좋을 것 같습니다.

return new Lotto(numbers);
}

// 개수만큼 로또 생성
public static List<Lotto> purchaseLotto(int purchaseAmount) {
List<Lotto> lottoList = new ArrayList<>();
int lottoCount = purchaseAmount / LOTTO_PRICE;

for (int i = 0; i < lottoCount; i++) {
Lotto lotto = createRandomLotto();
LottoUtils.verifyLottoNumbers(lotto.getNumbers());
lottoList.add(lotto);
}
return lottoList;
}

// 당첨결과 계산 -> 반환
public static int[] calculateWiningResult(List<Lotto> lottoSet, List<Integer> winningNumbers, int bonusWinningNumber) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int[] 를 결과값으로 반환 하는 것 보다는 일급 컬렉션이나, DTO를 사용해서 넘겨주는 방식으로 코드를 작성해주시면 더욱 좋을 것 같습니다.

int[] winingResult = new int[5]; // 3개 일치, 4개 일치, 5개 일치, 5개+보너스, 6개 일치

int matchCount = 0;
int bonusCount = 0;

// 당첨 결과 계산

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위의 로직에 대한 설명을 넣기 보단, 메서드로 추출하여 메서드에 이름을 구체화하여 역할 분리와 가독성을 높이는 것이 좋아보입니다.

for (Lotto lotto : lottoSet) {
for (int lottoNum : lotto.getNumbers()) {
if (winningNumbers.contains(lottoNum)) {
matchCount++;
}
if (lottoNum == bonusWinningNumber) {
bonusCount = 1;
}
}

// 당첨결과 업데이트
if (matchCount == 3) {
winingResult[0]++;
} else if (matchCount == 4) {
winingResult[1]++;
} else if (matchCount == 5 && bonusCount == 0) {
winingResult[2]++;
} else if (matchCount == 5 && bonusCount == 1) {
winingResult[3]++;
} else if (matchCount == 6) {
winingResult[4]++;
}
matchCount = 0;
bonusCount = 0;
}

return winingResult;
}
Comment on lines +49 to +65

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if문 보다는 switch case로 작성하시는게 좋을 것 같습니다.
switch문이 성능면에서 좋고, 가독성도 좋을 것 같습니다.


// 전체 당첨금 계산
public static int getTotalPrize(int[] winingResult) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

당첨금은 상수로 선언하여 사용해주시면 확장성, 수정에 있어서 용이할 것 같습니다

return winingResult[0] * 5000 + // 3개 일치
winingResult[1] * 50000 + // 4개 일치
winingResult[2] * 1500000 + // 5개 일치
winingResult[3] * 30000000 + // 5개+보너스
winingResult[4] * 2000000000; // 6개 일치
}

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

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

// verify service
public class LottoUtils {

// 로또 개별 번호 검증
public static void verifyLottoNumber(int lottoNum) {
if (!(1 <= lottoNum && lottoNum <= 45)) {
throw new IllegalArgumentException("[ERROR] 로또번호는 1부터 45사이의 숫자여야합니다.");
}
}

// 로또 숫자 리스트 검증
public static void verifyLottoNumbers(List<Integer> numbers) {
// 개수 검증
if (numbers.size() != 6) {
throw new IllegalArgumentException("[ERROR] 로또번호는 6개여야 합니다.");
}

// 중복 숫자 검증
Set<Integer> setNumbers = new HashSet<>(numbers);
if( setNumbers.size() != numbers.size()){
throw new IllegalArgumentException("[ERROR] 로또번호는 중복될 수 없습니다.");
}
for (int lottoNum : numbers) {
verifyLottoNumber(lottoNum);
}
}

// 구매금액 String 검증 후 int로 반환
public static int verifyPurchaseAmountString(String purchaseAmountString) {
try {
int purchaseAmount = Integer.parseInt(purchaseAmountString);

if (purchaseAmount % 1000 != 0 || purchaseAmount < 0) {
throw new IllegalArgumentException("[ERROR] 구입금액은 1000원 단위여야 합니다.");
}

return purchaseAmount;

} catch (NumberFormatException e) {
throw new IllegalArgumentException("[ERROR] 구입금액은 숫자여야 합니다.");
}
}
}
Loading