Skip to content
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

[로또 다시만들기] 박진현 코드리뷰 부탁드립니다. #2104

Open
wants to merge 43 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
5e22781
docs: 요구사항 작성
tiemo0708 Nov 27, 2023
2133ea4
feat: 출력 메세지 상수 enum 생성
tiemo0708 Nov 27, 2023
fecc8f7
feat: 인풋 출력 클래스 생성
tiemo0708 Nov 27, 2023
efa1595
feat: 아웃풋 출력 클래스 생성
tiemo0708 Nov 27, 2023
1198f71
fix: Lotto 클래스를 model 패키지로 이동
tiemo0708 Nov 27, 2023
6f1a187
feat: 컨트롤러 클래스 생성
tiemo0708 Nov 27, 2023
e09a2cb
feat: 에러 메세지 enum 생성
tiemo0708 Nov 27, 2023
3cafc10
feat: 로또 번호를 생성하는 클래스 생성
tiemo0708 Nov 27, 2023
dbfa372
feat: 로또 구매 횟수 만큼 생성하는 메서드 추가
tiemo0708 Nov 27, 2023
553b0af
feat: 랜덤한 로또 번호 6개를 생성하는 메서드 추가
tiemo0708 Nov 27, 2023
976c8c1
feat: 로또 구매가격을 받는 메서드 추가
tiemo0708 Nov 27, 2023
2e2f60d
fix: 클래스명 첫글자 소문자에서 대문자로 변경
tiemo0708 Nov 27, 2023
3269272
feat: 로또 금액을 받을때 숫자 이외의 값이 들어 오면 예외처리후 다시 값을 받는 기능
tiemo0708 Nov 27, 2023
b464e29
fix: 필드 선언에 final 추가
tiemo0708 Nov 27, 2023
4dfdcac
feat: 라인을 한칸 뛰우는 메서드 추가
tiemo0708 Nov 27, 2023
53b4dc6
feat: 구매한 로또의 개수와 번호를 출력하는 메서드 추가
tiemo0708 Nov 27, 2023
8ff644d
feat: 구매한 로또번호들의 리스트를 가져오는 메서드 추가
tiemo0708 Nov 27, 2023
b548948
feat: 구매한 로또의 개수와 번호들을 출력하는 기능 추가
tiemo0708 Nov 27, 2023
7bfa33f
feat: 라인을 한칸 뛰우는 메서드 추가
tiemo0708 Nov 27, 2023
3a260e2
feat: 로또 당첨 번호를 입력받는 메서드 추가
tiemo0708 Nov 27, 2023
802b0f3
feat: 입력받은 문자열 리스트를 정수형 리스트로 바꿔주는 메서드 추가
tiemo0708 Nov 27, 2023
87a4b5c
feat: 로또 당첨번호를 입력 받아 저장하는 기능
tiemo0708 Nov 27, 2023
947ba69
feat: 로또 당첨 목록을 enum 으로 생성
tiemo0708 Nov 27, 2023
5a8d483
feat: 로또 보너스 번호를 입력받는 메서드 추가
tiemo0708 Nov 27, 2023
a88d7b6
feat: 로또 당첨 등수를 기록하는 메서드 추가
tiemo0708 Nov 27, 2023
196a744
feat: 로또 당첨 번호와 비교하여 등수를 기록하는 기능 추가
tiemo0708 Nov 27, 2023
87bc1e6
feat: 당첨 통계를 출력하는 기능
tiemo0708 Nov 27, 2023
675983c
feat: 담청번호 중복 예외처리
tiemo0708 Nov 28, 2023
bfda738
feat: 로또 번호 6개를 입력하지 않았을 경우에 예외처리
tiemo0708 Nov 28, 2023
dde99e2
fix: 에러메세지 enum 위치변경
tiemo0708 Nov 28, 2023
7ad4a50
fix: 에러메세지 이름변경
tiemo0708 Nov 28, 2023
ec18079
feat: 1~45이외의 숫자를 입력한 경우 예외 처리
tiemo0708 Nov 28, 2023
ffb4343
fix: 로또번호릉 6개 입력하지 않은 경우 종료되지않고 다시 입력받도록 수정
tiemo0708 Nov 28, 2023
2275081
feat: 로또 수익률 계산 클래스 생성
tiemo0708 Nov 28, 2023
184bada
feat: 로또 수익률 계산 하여 출력하는 기능 추가
tiemo0708 Nov 28, 2023
f081287
fix: 예외 발생시 프로그램이 종료되도록 변경
tiemo0708 Nov 28, 2023
6a682ac
docs: 요구사항 진행과정 업데이트
tiemo0708 Nov 28, 2023
e77c32c
fix: 보너스번호 입력 메서드를 input클래스로 이동
tiemo0708 Nov 28, 2023
988ee68
feat: 보너스 번호가 중복인경우 예외처리
tiemo0708 Nov 28, 2023
564e1ca
feat: 보너스 번호를 숫자 1개를 입력하지 않은 경우 예외처리
tiemo0708 Nov 28, 2023
3fa12da
test: 로또 번호가 1~45가 아닐경우 예외처리 테스트
tiemo0708 Nov 28, 2023
ef972e6
feat: 천원 단위로 입력받는 예외처리 생성
tiemo0708 Nov 28, 2023
5a85fa1
test: 로또 번호를 1개만 입력할경우 예외처리 테스트
tiemo0708 Nov 28, 2023
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
34 changes: 34 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 로또

## 기능 목록
- [V] 랜덤 하게 생성한 로또 번호와 사용자가 임의로 선정한 당첨 번호를 비교하여
당첨된 등수와 수익률을 계산한다.
- [V] 사용자로부터 로또 구입 금액을 입력 받는다.
- [V] 입력 받은 금액에 따라 랜덤하게 6개의 숫자를 생성하여 로또 번호를 생성한다.(1~45범위, 중복X, 오름차순 정렬)
- [V] 사용자로부터 당첨 번호와 보너스 번호를 입력 받은 후, 생성한 로또 번호와 비교하여 등수를 출력한다.
- [V] 수익률을 계산하여 출력한다.(소수점 둘떄 자리 반올림)
-[]입력값 예외처리
-[V]로또 번호 중복 예외처리
-[V]로또 번호 범위 벗어남 예외처리
-[] 보너스 번호 예외처리
## 기능 요구 사항
- 로또 번호의 숫자 범위는 1~45까지이다.
- 1개의 로또를 발행할 때 중복되지 않는 6개의 숫자를 뽑는다.
- 당첨 번호 추첨 시 중복되지 않는 숫자 6개와 보너스 번호 1개를 뽑는다.
- 당첨은 1등부터 5등까지 있다. 당첨 기준과 금액은 아래와 같다.
- 1등: 6개 번호 일치 / 2,000,000,000원
- 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원
- 3등: 5개 번호 일치 / 1,500,000원
- 4등: 4개 번호 일치 / 50,000원
- 5등: 3개 번호 일치 / 5,000원

### 추가된 요구 사항
-[V] 함수(또는 메서드)의 길이가 15라인을 넘어가지 않도록 구현한다.
- 함수(또는 메서드)가 한 가지 일만 잘 하도록 구현한다.
-[V] else 예약어를 쓰지 않는다.
- 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다.
- else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다.
-[V] Java Enum을 적용한다.
-[] 도메인 로직에 단위 테스트를 구현해야 한다. 단, UI(System.out, System.in, Scanner) 로직은 제외한다.
- 핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 분리해 구현한다.
- 단위 테스트 작성이 익숙하지 않다면 `test/java/lotto/LottoTest`를 참고하여 학습한 후 테스트를 구현한다.
8 changes: 7 additions & 1 deletion src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package lotto;

import lotto.controller.LottoController;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
LottoController.setPrice();
LottoController.setBuyLottoNumberPrint();
LottoController.setPrizeNumberInput();
LottoController.winningStatistic();
LottoController.PerformanceCalculation();
}
}
20 changes: 0 additions & 20 deletions src/main/java/lotto/Lotto.java

This file was deleted.

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

public enum ErrorMessage {
DUPLICATION("[ERROR] 값이 중복되었습니다"),
ISNOTINTEGER("[ERROR] 숫자를 입력해주세요"),
SIXNUMBER("[ERROR] 번호 6개를 입력해주세요"),
OUTFRANGE("[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다."),
ONENUMBER("[ERROR] 숫자 번호 1개를 입력해주세요"),
NOTTHOUSAND("[ERROR] 1000원 단위로 입력해 주세요");


private final String message;

ErrorMessage(String message) {
this.message = message;
}

public String getMessage() {
return message;
}
}
50 changes: 50 additions & 0 deletions src/main/java/lotto/controller/LottoController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package lotto.controller;

import lotto.model.Lotto;
import lotto.model.LottoNumberMaker;
import lotto.model.LottoPercentageCalculation;
import lotto.model.constants.LottoPrize;
import lotto.view.LottoInput;
import lotto.view.LottoOutput;

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

import static java.util.Arrays.asList;
import static lotto.model.constants.LottoPrize.*;

public class LottoController {
private static final LottoNumberMaker lottoNumberMaker = new LottoNumberMaker();
private static final LottoInput lottoInput = new LottoInput();
private static final LottoOutput lottoOutput = new LottoOutput();
private static final LottoPercentageCalculation lottoPercentageCalculation = new LottoPercentageCalculation();
public static void setPrice() {
lottoNumberMaker.checkInt();
}

// static List<LottoPrize> LottoPrizelist= asList(FIFTH_PRIZE,FOURTH_PRIZE,THIRD_PRIZE,SECOND_PRIZE,FIRST_PRIZE);
public static void setBuyLottoNumberPrint() {
lottoOutput.buyLottoNumberPrint(lottoNumberMaker.getLottoNumber());
}

public static void setPrizeNumberInput() {
Lotto lotto = new Lotto(lottoInput.prizeNumberInput());
lotto.checkSame(lottoInput.bonusNumberInput(),lottoNumberMaker.getLottoNumber());
}

public static void winningStatistic() {
List<String> lottoPrizes = new ArrayList<>();
for(LottoPrize lottoPrize: LottoPrize.values()){
lottoPrizes.add(lottoPrize.getText()+lottoPrize.getWinCount()+lottoPrize.getUnit());
}
LottoOutput.seeWinningStatstic(lottoPrizes);
}

public static void PerformanceCalculation() {
lottoOutput.seePercentage(lottoPercentageCalculation.percentageCalculation(LottoPrize.values(),lottoNumberMaker.getBuyPrice()));
}

public String askPrice() {
return lottoInput.askPrice();
}
}
79 changes: 79 additions & 0 deletions src/main/java/lotto/model/Lotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package lotto.model;

import lotto.model.constants.LottoPrize;

import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;

import static lotto.constants.ErrorMessage.DUPLICATION;
import static lotto.constants.ErrorMessage.SIXNUMBER;
import static lotto.model.constants.LottoPrize.*;
public class Lotto {
private final List<Integer> numbers;

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

private void duplicate(List<Integer> numbers) {
List<Integer> duplication = numbers.stream()
.distinct()
.toList();
if (duplication.size() != numbers.size()) {
throw new IllegalArgumentException(DUPLICATION.getMessage());
}
}

private void validate(List<Integer> numbers) {
if (numbers.size() != 6) {
throw new IllegalArgumentException(SIXNUMBER.getMessage());
}
}
public void checkSame(Integer bonusNumber, List<List<Integer>> lottoNumber) {
bonusDuplication(bonusNumber);
for (List<Integer> integers : lottoNumber) {
List<Integer> Result = integers.stream()
.filter(i -> this.numbers.stream().anyMatch(Predicate.isEqual(i)))
.toList();
long bonusResult = integers.stream()
.filter(bonusNumber::equals).count();
CheckPrize(Result.size(), bonusResult).addWinCount();

}
}

private void bonusDuplication(Integer bonusNumber) {
List<Integer> Result = this.numbers.stream()
.filter(i-> !Objects.equals(i, bonusNumber))
.toList();
if(Result.size()!=6){
throw new IllegalArgumentException(DUPLICATION.getMessage());
}

}

public LottoPrize CheckPrize(int result, long bonusResult){
if(result==6){
return FIRST_PRIZE;
}
if(result==5&&bonusResult==1){
return SECOND_PRIZE;
}
if(result==5&&bonusResult==0){
return THIRD_PRIZE;
}
if(result==4){
return FOURTH_PRIZE;
}
if(result==3){
return FIFTH_PRIZE;
}
if(result<3){
return LOOSE;
}
throw new IllegalArgumentException("존재 하지 않는 순위입니다.");
}
}
67 changes: 67 additions & 0 deletions src/main/java/lotto/model/LottoNumberMaker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package lotto.model;

import camp.nextstep.edu.missionutils.Randoms;
import lotto.controller.LottoController;

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

import static lotto.constants.ErrorMessage.ISNOTINTEGER;
import static lotto.constants.ErrorMessage.NOTTHOUSAND;

public class LottoNumberMaker {
private static int buyPrice;
private static final List<List<Integer>> numbers = new ArrayList<>();
private static final LottoController lottoController = new LottoController();

public static int getBuyPrice() {
return buyPrice;
}

public void makeLottoNumber(Integer count) {
buyPrice = count;
checkThousand(count);
IntStream.range(0, count / 1000)
.forEach(i -> numbers.add(makeRandomNumber()));
}

private void checkThousand(Integer count) {
if(count%1000!=0){
throw new IllegalArgumentException(NOTTHOUSAND.getMessage());
}
return;
}

private List<Integer> makeRandomNumber() {
return Randoms.pickUniqueNumbersInRange(1, 45, 6).stream()
.sorted()
.collect(Collectors.toList());
}

public void checkInt() {
while (true) {
try {
int number = checkCount();
makeLottoNumber(number);
break;
} catch (IllegalArgumentException e) {
System.out.println(ISNOTINTEGER.getMessage());
System.out.println(NOTTHOUSAND.getMessage());
}
}
}

private int checkCount() {
try {
return Integer.parseInt(lottoController.askPrice());
} catch (NumberFormatException e) {
throw new IllegalArgumentException(ISNOTINTEGER.getMessage());
}
}

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

import lotto.model.constants.LottoPrize;

public class LottoPercentageCalculation {

public double percentageCalculation(LottoPrize[] values, int lottoPrice) {
double profit = 0;
for(LottoPrize lottoPrize: values){
profit+=lottoPrize.getWinCount()*lottoPrize.getPrizeMoney();
}
return (profit/lottoPrice)*100;
}
}
39 changes: 39 additions & 0 deletions src/main/java/lotto/model/constants/LottoPrize.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package lotto.model.constants;

public enum LottoPrize {
FIRST_PRIZE(0,"6개 일치 (2,000,000,000원) - ","개",2000000000),
SECOND_PRIZE(0,"5개 일치, 보너스 볼 일치 (30,000,000원) - ","개", 30000000),
THIRD_PRIZE(0,"5개 일치 (1,500,000원) - ","개", 1500000),
FOURTH_PRIZE(0,"4개 일치 (50,000원) - ","개", 50000),
FIFTH_PRIZE(0,"3개 일치 (5,000원) - ","개", 5000),
LOOSE(0,"","개", 0);


private int winCount;
private final String text;
private final String unit;
private int prizeMoney;

LottoPrize(int winCount, String text, String unit, int prizemoney) {
this.winCount = winCount;
this.text = text;
this.unit = unit;
this.prizeMoney = prizemoney;
}
public int getWinCount() {
return winCount;
}
public String getText() {
return text;
}
public String getUnit() {
return unit;
}
public int getPrizeMoney() {
return prizeMoney;
}

public void addWinCount() {
this.winCount ++;
}
}
21 changes: 21 additions & 0 deletions src/main/java/lotto/view/ConstantsMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package lotto.view;

public enum ConstantsMessage {
ASK_BUY_PRICE("구입 금액을 입력해 주세요."),
BUY_RESULT_MESSAGE("개를 구매했습니다."),
ASK_PRIZE_NUMBER("당첨 번호를 입력해 주세요."),
ASK_BONUS_NUMBER("보너스 번호를 입력해 주세요."),
WIN_RESULT_MESSAGE("당첨통계"),
lINE_SEPARATION_MESSAGE("---"),
PERCENT_FRONT_MESSAGE("총 수익률은 "),
PERCENT_BACK_MESSAGE("%입니다.");

private final String message;

ConstantsMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
Loading