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

[로또] 손지현 미션 제출합니다. #2097

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c87e5ae
feat Rank enum 클래스 추가
Nov 4, 2023
1b3d578
feat 로또 Output 클래스 생성, 출력값 정리
Nov 4, 2023
46fd73f
feat 랜덤 생성 로또 리스트 출력
Nov 4, 2023
07b2d8f
feat 사용자 입력 클래스 생성
Nov 4, 2023
4668b52
feat Exception 메시지 출력 클래스 추가
Nov 4, 2023
eff1715
chore view rename
Nov 4, 2023
04525bd
feat 도메인 클래스 생성
Nov 4, 2023
c3fca36
init Controller, Service 생성
Nov 4, 2023
07e1521
chore Lotto 패키지 위치 변경으로 인한 import 수정
Nov 4, 2023
0049bc3
remove 클래스 파일 삭제
Nov 5, 2023
403e1b5
chore view 값 수정
Nov 5, 2023
f479ca6
chore InputValidator 추가
Nov 5, 2023
0bd1284
feat Exception처리 변경(진행중)
Nov 5, 2023
d72ecdc
feat Rank Enum 생성
Nov 5, 2023
e346e30
feat Game, Lotto, Player 기능 추가
Nov 5, 2023
1801133
feat Game 서비스 구현 및 실행
Nov 5, 2023
66ecb74
chore commit 시 오타 수정
Nov 5, 2023
26b4afa
feat 입력 Exception 발생 시 해당 시점부터 재입력 추가
Nov 5, 2023
1c8724e
fix 보너스 번호 당첨 시 Rank count 미증가 수정
Nov 5, 2023
0c8323e
feat 상수 클래스 별도 추가
Nov 5, 2023
a5442dc
chore 유틸 패키지 정리
Nov 5, 2023
2982498
chore 예외처리 인터페이스 위치 변경
Nov 5, 2023
3568889
test Calculator Util 테스트 작성
Nov 5, 2023
d0fbffb
feat InputValidator 클래스 생성
Nov 5, 2023
f5a0a98
test InputValidator 테스트 코드 작성
Nov 5, 2023
7b92cd5
chore 소스 정리
Nov 5, 2023
675ae3c
test Lotto 클래스 테스트 추가
Nov 5, 2023
c43eb34
test Player 클래스 테스트 추가
Nov 5, 2023
8e16c13
test Game 클래스 테스트 추가
Nov 5, 2023
dc582cf
test 반복 입력 기능 테스트 추가
Nov 5, 2023
b6fe36b
test Rank 클래스 테스트 추가
Nov 5, 2023
837dae5
doc 주석 추가
Nov 5, 2023
54c9385
doc README.md 작성
Nov 5, 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
57 changes: 57 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# 로또 게임 기능 구현 정리

-------
## Controller
* GameController
* run : 게임 실행
--------
## Service
* GameService
* start : 로또 구매금액을 만큼의 로또를 발급
* gameSetting : 당첨 번호와 보너스 번호를 입력 받음
* gameInProgress :
* 입력 받은 당첨번호, 보너스 번호가 일치하는지 검증
* result :
* 당첨금 확인 및 수익률 확인하여 출력
--------
## Domain
* Game
* Game 진행을 위한 금액을 받는다.
* 로또 금액 검증
* 숫자 값으로만 이루어져 있는지 확인, 아닌 경우 예외 처리
* 1000의 배수인지 여부 확인, 아닌 경우 예외 처리
* 고객에게 로또 생성 후, 당첨 번호와 보너스 번호를 생성한다.
* 당첨 번호 리스트 검증
* 총 6개의 숫자 값인지, 1~45 사이의 숫자인, 중복 값이 없는지 확인
* 하나라도 맞지 않은 경우 예외 처리
* 보너스 번호 검증
* 숫자 값인지 1~45 사이의 숫자인지 당첨 번호 리스트와 중복되지 않은 값인지
* 하나라도 맞지 않은 경우 예외 처리
* Lotto
* 한 장의 로또로 6개의 번호를 갖고 있다.
* 로또 번호가 생성될 때 총 6개의 숫자 값인지 중복 값은 없는지 검증한다.
* 당첨 번호와 비교하여 등수 안에 들 경우, 랭크를 저장한다.
* Player
* 구매한 여러장의 로또를 갖고 있다.
* 당첨 번호를 받아 비교한다.
* 보너스 번호를 받아 비교한다.
* Rank
* 랭킹 정보를 갖고 있는 열거형 상수 값
* rankCount : 당첨된 등수 카운팅을 위한 맵 생성
* ranking : 일치하는 로또 번호 카운트에 따른 Rank 리턴을 위한 맵 생성


-------
## View
* GameInput : 게임에 필요한 입력값
* GameOutput : 게임에 필요한 출력값
------
## Util
* Calculator : 숫자 관련 계산 기능
* InputValidator : 입력값에 대한 검증 메서드
------
## Constant
* Exception 메시지 정의
* LottoGame 상수 정의
------
입력에 대한 예외처리는 IllegalArgumentException 이다.
5 changes: 4 additions & 1 deletion src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package lotto;

import lotto.controller.GameController;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
GameController gameController = new GameController();
gameController.run();
}
}
20 changes: 0 additions & 20 deletions src/main/java/lotto/Lotto.java

This file was deleted.

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

public enum ExceptionMessage {
AMOUNT_NUMBER_ERROR("[ERROR] 로또 구입 금액은 1000원 단위로 입력하셔야 합니다."),
LOTTO_NUMBER_ERROR("[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다."),
LOTTO_NUMBER_VALID_ERROR("[ERROR] 로또 번호는 6개의 중복되지 않는 숫자를 입력 해주셔야 합니다."),
BONUS_NUMBER_ERROR("[ERROR] 보너스 번호는 1부터 45 사이의 중복되지 않는 숫자여야 합니다.");

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

private final String message;

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

public class LottoGame {
public final static int LOTTO_PRICE = 1000;
public static final String REGEX = "[0-9]+";
public final static int LOTTO_NUMBER_COUNT = 6;
public final static int LOTTO_MIN_NUMBER = 1;
public final static int LOTTO_MAX_NUMBER = 45;

public final static int WIN_MIN_COUNT = 3;
public final static String DECIMAL_FORMAT = "%.1f";
}
19 changes: 19 additions & 0 deletions src/main/java/lotto/controller/GameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package lotto.controller;

import lotto.service.GameService;
import lotto.view.GameOutput;

public class GameController {
private static GameService gameService = new GameService();

public void run() {
gameService.start();
GameOutput.printBlankLine();
gameService.gameSetting();
GameOutput.printBlankLine();
gameService.gameInProgress();
GameOutput.printBlankLine();
gameService.result();

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

import java.util.List;
import java.util.stream.Collectors;
import lotto.constant.ExceptionMessage;
import lotto.constant.LottoGame;
import lotto.util.Calculator;
import lotto.util.InputValidator;

public class Game {
public static int receiveAmount;
private List<Integer> winningNumbers;
private int bonusNumber;

public Game(String receiveAmount) {
validateAmount(receiveAmount);
this.receiveAmount = Integer.parseInt(receiveAmount);
}

public Game setWinningNumbers(String enterNumbers) {
List<String> numbers = List.of(enterNumbers.split(","));
validWinningNubmers(numbers);

winningNumbers = numbers.stream()
.map(Integer::valueOf)
.sorted()
.collect(Collectors.toList());

return this;
}

public List<Integer> getWinningNumbers() {
return winningNumbers;
}

public Game setBonusNumber(String enterNumber){
validBonusNubmer(enterNumber);
bonusNumber = Integer.parseInt(enterNumber);
return this;
}

public int getBonusNumber() {
return bonusNumber;
}


public int lottoPurchaseCount(){
return Calculator.divide(receiveAmount, LottoGame.LOTTO_PRICE);
}

private void validateAmount(String amount) {
if(!InputValidator.isNumber(amount) || !Calculator.isMultiple(Integer.parseInt(amount), LottoGame.LOTTO_PRICE)){
throw new IllegalArgumentException(ExceptionMessage.AMOUNT_NUMBER_ERROR.getMessage());
}
}

private static void validWinningNubmers(List<String> enterWinningNumbers) {
if(!InputValidator.isCorrectCount(enterWinningNumbers.size()) || InputValidator.isDuplicateNumberForString(enterWinningNumbers)) {
throw new IllegalArgumentException(ExceptionMessage.LOTTO_NUMBER_VALID_ERROR.getMessage());
}

validWinningNubmer(enterWinningNumbers);
}

private static void validWinningNubmer(List<String> winningNumbers) {
for (var winningNumber : winningNumbers) {
if (!InputValidator.isNumber(winningNumber) || !InputValidator.isCorrectNumber(Integer.parseInt(winningNumber))) {
throw new IllegalArgumentException(ExceptionMessage.LOTTO_NUMBER_ERROR.getMessage());
}
}
}

private void validBonusNubmer(String bonusNumber) {
if(!InputValidator.isNumber(bonusNumber)
|| !InputValidator.isCorrectNumber(Integer.parseInt(bonusNumber)) || winningNumbers.contains(bonusNumber)){
throw new IllegalArgumentException(ExceptionMessage.BONUS_NUMBER_ERROR.getMessage());
}
}
}
47 changes: 47 additions & 0 deletions src/main/java/lotto/domain/Lotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package lotto.domain;

import java.util.List;
import lotto.constant.ExceptionMessage;
import lotto.constant.LottoGame;
import lotto.util.InputValidator;

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


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

public List<Integer> getNumbers() {
return numbers;
}

private void validate(List<Integer> numbers) {
if (!InputValidator.isCorrectCount(numbers.size()) || InputValidator.isDuplicateNumber(numbers)) {
throw new IllegalArgumentException(ExceptionMessage.LOTTO_NUMBER_ERROR.getMessage());
}
}

public void setRank(int count) {
if(count >= LottoGame.WIN_MIN_COUNT) {
rank = Rank.getRank(count);
Rank.addRankCount(rank);
}
}

public Rank getRank() {
return rank;
}


public void matchBonusNumber(int bonusNumber) {
if(rank == Rank.THIRD && numbers.contains(bonusNumber)) {
Rank.minusThirdRankCount();
rank = Rank.SECOND;
Rank.addRankCount(rank);
}
}
}
59 changes: 59 additions & 0 deletions src/main/java/lotto/domain/Player.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package lotto.domain;


import camp.nextstep.edu.missionutils.Randoms;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import lotto.constant.LottoGame;
import lotto.util.Calculator;

public class Player {
public final List<Lotto> lottos;

public Player(int purchaseCount) {
this.lottos = receiveLotto(purchaseCount);
}

private List<Lotto> receiveLotto(int purchaseCount) {
List<Lotto> lottos = new ArrayList<>();
for (int i = 0; i < purchaseCount; i++) {
lottos.add(new Lotto(makeNumbers()));
}
return lottos;
}

private List<Integer> makeNumbers() {
return Randoms.pickUniqueNumbersInRange(LottoGame.LOTTO_MIN_NUMBER, LottoGame.LOTTO_MAX_NUMBER,
LottoGame.LOTTO_NUMBER_COUNT)
.stream()
.sorted()
.collect(Collectors.toList());
}

public List<Lotto> checkMatchWinningNumber(List<Integer> winningNumbers) {
List<Integer> matchList;
for (var lotto : lottos) {
matchList = lotto.getNumbers().stream()
.filter(number -> winningNumbers.stream()
.anyMatch(Predicate.isEqual(number)))
.collect(Collectors.toList());

lotto.setRank(matchList.size());
matchList.clear();
}
return lottos;
}

public void checkMatchBonusNumber(int bonusNumber) {
for (var lotto : lottos) {
lotto.matchBonusNumber(bonusNumber);
}
}

public String getEarningRate(double amount) {
double rate = Calculator.percentage(Rank.getTotalEarning(), amount);
return Calculator.rounds(rate);
}
}
Loading