-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[로또 미션] 오지현 미션 제출합니다. #20
base: zhy2on
Are you sure you want to change the base?
Changes from all commits
a4853f5
d1c287a
fda63c4
a39799b
9864dfd
26ddc72
5b04e8e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import controller.LottoController; | ||
|
||
public class LottoApplication { | ||
public static void main(String[] args) { | ||
LottoController controller = new LottoController(); | ||
controller.run(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package controller; | ||
|
||
import domain.*; | ||
import view.InputView; | ||
import view.OutputView; | ||
|
||
import java.util.List; | ||
|
||
public class LottoController { | ||
public void run() { | ||
int purchaseAmount = InputView.getPurchaseAmount(); | ||
int manualLottoCount = InputView.getManualLottoCount(); | ||
List<Lotto> lottos = InputView.getManualLottos(manualLottoCount); | ||
|
||
int autoLottoCount = purchaseAmount / Lotto.LOTTO_PRICE - manualLottoCount; | ||
lottos.addAll(LottoMachine.generateLottos(autoLottoCount)); | ||
OutputView.printLottos(lottos, manualLottoCount, autoLottoCount); | ||
|
||
Lotto winningLotto = InputView.getWinningLottoNumbers(); | ||
LottoNumber bonusNumber = InputView.getBonusNumber(); | ||
|
||
LottoResult result = getLottoResult(lottos, winningLotto, bonusNumber); | ||
OutputView.printResult(result, purchaseAmount); | ||
} | ||
|
||
private LottoResult getLottoResult(final List<Lotto> lottos, final Lotto winningLotto, final LottoNumber bonusNumber) { | ||
List<LottoPrize> prizes = lottos.stream() | ||
.map(lotto -> getLottoPrize(lotto, winningLotto, bonusNumber)) | ||
.toList(); | ||
return new LottoResult(prizes); | ||
} | ||
|
||
private LottoPrize getLottoPrize(final Lotto lotto, final Lotto winningLotto, final LottoNumber bonusNumber) { | ||
int matchCount = countMatchingNumbers(lotto, winningLotto); | ||
boolean isMatchBonus = lotto.contains(bonusNumber); | ||
return LottoPrize.matchPrize(matchCount, isMatchBonus); | ||
} | ||
|
||
private int countMatchingNumbers(final Lotto lotto, final Lotto winningLotto) { | ||
return (int) lotto.numbers().stream() | ||
.filter(winningLotto.numbers()::contains) | ||
.count(); | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 원시 값 포장을 잘 사용하셨네요! 저는 그냥 1000으로 나눠버렸는데 하나 배워갑니다 :-) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아하 감사합니다! 그런데 저 부분은 매직넘버를 상수로 선언해서 제거한 부분이고 이번 과제에서 말한 원시값 포장이랑은 다른 개념인 것 같아요..!! 저도 잘은 모르지만 돈에 대해선 제가 원시값 포장을 못 했어요🥲 이 부분은 추가로 더 고민해보고 수정하겠습니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 죄송해요 저도 어제 스터디에서 설명해주시는 거 듣고 제가 틀렸단 걸 깨달았습니다..전 단순히 포장(감싼다)인 줄 알았어요ㅠㅠ저도 아직 배워야할 게 많은 것 같습니다..ㅠㅠ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package domain; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
public record Lotto(List<LottoNumber> numbers) { | ||
public static final int LOTTO_NUMBER_COUNT = 6; | ||
public static final int LOTTO_PRICE = 1000; | ||
|
||
public Lotto { | ||
validateNumbers(numbers); | ||
Collections.sort(numbers); | ||
} | ||
|
||
private void validateNumbers(final List<LottoNumber> numbers) { | ||
if (numbers.size() != LOTTO_NUMBER_COUNT) { | ||
throw new IllegalArgumentException("로또 숫자는 6개여야 합니다."); | ||
} | ||
if (numbers.stream().distinct().count() != LOTTO_NUMBER_COUNT) { | ||
throw new IllegalArgumentException("로또 숫자는 중복 되지 않아야 합니다."); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예외 처리도 잘 하신 것 같아요. |
||
} | ||
|
||
public static Lotto generate() { | ||
List<LottoNumber> numbers = Stream.generate(LottoNumber::generate) | ||
.distinct() | ||
.limit(LOTTO_NUMBER_COUNT) | ||
.collect(Collectors.toList()); | ||
return new Lotto(numbers); | ||
} | ||
|
||
public boolean contains(final LottoNumber number) { | ||
return numbers.contains(number); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return numbers.stream() | ||
.map(LottoNumber::toString) | ||
.collect(Collectors.joining(", ", "[", "]")); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package domain; | ||
|
||
import domain.Lotto; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
public class LottoMachine { | ||
|
||
public static List<Lotto> generateLottos(final int count) { | ||
return Stream.generate(Lotto::generate) | ||
.limit(count) | ||
.collect(Collectors.toList()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package domain; | ||
|
||
import java.util.Random; | ||
|
||
public record LottoNumber(int number) implements Comparable<LottoNumber> { | ||
private static final int MIN_NUMBER = 1; | ||
private static final int MAX_NUMBER = 45; | ||
private static final Random random = new Random(); | ||
|
||
public LottoNumber { | ||
valdateNumber(number); | ||
} | ||
|
||
private void valdateNumber(final int number) { | ||
if (number < MIN_NUMBER || number > MAX_NUMBER) { | ||
throw new IllegalArgumentException("로또 번호는 1부터 45 사이의 값이어야 합니다."); | ||
} | ||
} | ||
|
||
public static LottoNumber generate() { | ||
return new LottoNumber(random.nextInt(MAX_NUMBER - MIN_NUMBER + 1) + MIN_NUMBER); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return String.valueOf(number); | ||
} | ||
|
||
@Override | ||
public int compareTo(final LottoNumber other) { | ||
return Integer.compare(this.number, other.number); | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. enum을 잘 활용하신 것 같습니다. 저는 enum을 활용할 때 많이 헤맸는데 또 하나 배워갑니다! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package domain; | ||
|
||
import java.util.Arrays; | ||
|
||
public enum LottoPrize { | ||
MISS(0, 0, false), | ||
FIFTH(3, 5_000, false), | ||
FOURTH(4, 50_000, false), | ||
THIRD(5, 1_500_000, false), | ||
SECOND(5, 30_000_000, true), | ||
FIRST(6, 2_000_000_000, false); | ||
|
||
private final int matchCount; | ||
private final int prize; | ||
private final boolean isMatchBonus; | ||
|
||
LottoPrize(final int matchCount, final int prize, final boolean isMatchBonus) { | ||
this.matchCount = matchCount; | ||
this.prize = prize; | ||
this.isMatchBonus = isMatchBonus; | ||
} | ||
|
||
public static LottoPrize matchPrize(final int matchCount, final boolean isMatchBonus) { | ||
return Arrays.stream(LottoPrize.values()) | ||
.filter(prize -> prize.matchCount == matchCount) | ||
.filter(prize -> prize.isMatchBonus == isMatchBonus) | ||
.findFirst() | ||
.orElse(MISS); | ||
} | ||
|
||
public int getMatchCount() { | ||
return matchCount; | ||
} | ||
|
||
public int getPrize() { | ||
return prize; | ||
} | ||
|
||
public boolean isMatchBonus() { | ||
return isMatchBonus; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package domain; | ||
|
||
import java.util.List; | ||
|
||
public class LottoResult { | ||
private final List<LottoPrize> prizes; | ||
|
||
public LottoResult(final List<LottoPrize> prizes) { | ||
this.prizes = prizes; | ||
} | ||
|
||
public int getTotalPrize() { | ||
return prizes.stream() | ||
.mapToInt(LottoPrize::getPrize) | ||
.sum(); | ||
} | ||
|
||
public double getEarningRate(final int purchaseAmount) { | ||
return (double) getTotalPrize() / purchaseAmount; | ||
} | ||
|
||
public int getCountByPrize(final LottoPrize prize) { | ||
return (int) prizes.stream() | ||
.filter(p -> p == prize) | ||
.count(); | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 문자열도 포장을 하시면 좋을 것 같아요. 위에서 원시 값을 포장하신 것처럼요! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package view; | ||
|
||
import domain.Lotto; | ||
import domain.LottoNumber; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Scanner; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
|
||
public class InputView { | ||
private static final Scanner scanner = new Scanner(System.in); | ||
|
||
public static int getPurchaseAmount() { | ||
System.out.println("구입 금액을 입력해 주세요."); | ||
return Integer.parseInt(scanner.nextLine()); | ||
} | ||
|
||
public static int getManualLottoCount() { | ||
System.out.println("수동으로 구매할 로또 수를 입력해 주세요."); | ||
return Integer.parseInt(scanner.nextLine()); | ||
} | ||
|
||
public static List<Lotto> getManualLottos(final int count) { | ||
System.out.println("수동으로 구매할 번호를 입력해 주세요."); | ||
return IntStream.range(0, count) | ||
.mapToObj(i -> getLottoNumbers()) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
public static Lotto getWinningLottoNumbers() { | ||
System.out.println("지난 주 당첨 번호를 입력해 주세요."); | ||
return getLottoNumbers(); | ||
} | ||
|
||
private static Lotto getLottoNumbers() { | ||
String input = scanner.nextLine(); | ||
List<LottoNumber> numbers = Arrays.stream(input.split(",")) | ||
.map(String::trim) | ||
.map(Integer::parseInt) | ||
.map(LottoNumber::new) | ||
.collect(Collectors.toList()); | ||
return new Lotto(numbers); | ||
} | ||
|
||
public static LottoNumber getBonusNumber() { | ||
System.out.println("보너스 볼을 입력해 주세요."); | ||
int number = Integer.parseInt(scanner.nextLine()); | ||
return new LottoNumber(number); | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 문자열을 포장하시고 반복문으로 출력하시면 코드가 훨씬 더 간결해질 것 같습니다. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package view; | ||
|
||
import domain.Lotto; | ||
import domain.LottoPrize; | ||
import domain.LottoResult; | ||
|
||
import java.util.List; | ||
|
||
public class OutputView { | ||
public static void printLottos(final List<Lotto> lottos, final int manualLottoCount, final int autoLottoCount) { | ||
System.out.printf("수동으로 %d장, 자동으로 %d개를 구매했습니다.\n", manualLottoCount, autoLottoCount); | ||
lottos.stream().skip(0).limit(manualLottoCount).forEach(System.out::println); | ||
lottos.stream().skip(manualLottoCount).limit(autoLottoCount).forEach(System.out::println); | ||
} | ||
|
||
public static void printResult(final LottoResult result, final int purchaseAmount) { | ||
System.out.println("당첨 통계"); | ||
System.out.println("---------"); | ||
for (LottoPrize prize : LottoPrize.values()) { | ||
int count = result.getCountByPrize(prize); | ||
printPrizeStatics(prize, count); | ||
} | ||
double earningRate = result.getEarningRate(purchaseAmount); | ||
System.out.printf("총 수익률은 %.2f입니다.%n", earningRate); | ||
} | ||
|
||
private static void printPrizeStatics(final LottoPrize prize, final int statics) { | ||
if (prize == LottoPrize.MISS) { | ||
return; | ||
} | ||
if (prize.isMatchBonus()) { | ||
System.out.printf("%d개 일치, 보너스 볼 일치(%d원) - %d개%n", prize.getMatchCount(), prize.getPrize(), statics); | ||
return; | ||
} | ||
System.out.printf("%d개 일치 (%d원)- %d개%n", prize.getMatchCount(), prize.getPrize(), statics); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package domain; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.List; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
public class LottoMachineTest { | ||
|
||
@Test | ||
void generateLottos() { | ||
int count = 5; | ||
List<Lotto> lottos = LottoMachine.generateLottos(count); | ||
assertThat(lottos.size()).isEqualTo(count); | ||
assertThat(lottos.stream().distinct().count()).isEqualTo(count); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import domain.LottoNumber; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
|
||
public class LottoNumberTest { | ||
|
||
@Test | ||
void validateNumber() { | ||
// 유효한 숫자인 경우 | ||
assertThat(new LottoNumber(1)).isNotNull(); | ||
assertThat(new LottoNumber(45)).isNotNull(); | ||
|
||
// 유효하지 않은 숫자인 경우 | ||
assertThatThrownBy(() -> new LottoNumber(0)) | ||
.isInstanceOf(IllegalArgumentException.class) | ||
.hasMessageContaining("로또 번호는 1부터 45 사이의 값이어야 합니다."); | ||
assertThatThrownBy(() -> new LottoNumber(46)) | ||
.isInstanceOf(IllegalArgumentException.class) | ||
.hasMessageContaining("로또 번호는 1부터 45 사이의 값이어야 합니다."); | ||
} | ||
|
||
@Test | ||
void generate() { | ||
LottoNumber number = LottoNumber.generate(); | ||
assertThat(number.number()).isBetween(1, 45); | ||
} | ||
|
||
@Test | ||
void toString_test() { | ||
LottoNumber number = new LottoNumber(5); | ||
assertThat(number.toString()).isEqualTo("5"); | ||
} | ||
|
||
@Test | ||
void compareTo() { | ||
LottoNumber num1 = new LottoNumber(1); | ||
LottoNumber num2 = new LottoNumber(2); | ||
LottoNumber num3 = new LottoNumber(3); | ||
|
||
assertThat(num1.compareTo(num2)).isNegative(); | ||
assertThat(num2.compareTo(num1)).isPositive(); | ||
assertThat(num2.compareTo(num3)).isNegative(); | ||
assertThat(num2.compareTo(num2)).isZero(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1단계에서 구현을 하신 것처럼 Controller 안에서 말고 Application 안에서 컨트롤러 객체 생성 후 controller.run() 사용하시면 좋을 것 같습니다.