Skip to content
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,50 @@
# java-lotto-precourse
## 간단한 로또 발매기를 구현한다.

### 학습 목표🤔

- 관련 함수를 묶어 클래스를 만들고, 객체들이 협력하여 하나의 큰 기능을 수행하도록 한다.
- 클래스와 함수에 대한 단위 테스트를 통해 의도한 대로 정확하게 작동하는 영역을 확보한다.
- 2주 차 공통 피드백을 최대한 반영한다.


### 기능 목록🎰

- [ ] 로또 구입 금액을 입력받는다.
- [ ] 로또를 발행한다.
- 구입 금액에 해당하는 만큼 발행한다.
- 로또 1장의 가격은 1,000원이다.
- 1에서 45 사이의 중복되지 않은 정수 6개를 반환한다.
- [ ] 당첨 번호를 입력받는다.
- 로또 번호의 숫자 범위는 1~45까지이다.
- 중복되지 않는 숫자 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원
- [ ] 수익률을 구한다.
- 사용자가 구매한 로또 번호와 당첨 번호를 비교해야 한다.
- [ ] 수익률을 출력한다.
- [ ] 사용자가 잘못된 값을 입력할 경우 `IllegalArgumentException`을 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다.
- `Exception`이 아닌 `IllegalArgumentException`, `IllegalStateException` 등과 같은 명확한 유형을 처리한다.

### 예외 처리🔎

#### 구입금액

- [ ] 구입 금액이 1,000원으로 나누어 떨어지지 않는 경우

#### 로또 번호

- [ ] 로또 번호의 숫자 범위를 벗어난 경우
- [ ] ,로 구분하지 않았을 경우

#### 당첨번호
- [ ] 당첨 번호에 있는 보너스 번호를 입력한 경우
17 changes: 16 additions & 1 deletion src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
package lotto;

import lotto.controller.LottoController;
import lotto.domain.GenerateLottos;
import lotto.service.LottoService;
import lotto.utils.Parsing;
import lotto.utils.Validator;
import lotto.view.InputView;
import lotto.view.OutputView;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
InputView inputView = new InputView();
OutputView outputView = new OutputView();
GenerateLottos generateLottos = new GenerateLottos();

LottoService lottoService = new LottoService(new Validator(),new Parsing(), generateLottos);
LottoController lottoController = new LottoController(inputView, outputView, lottoService);

lottoController.run();
}
}
41 changes: 41 additions & 0 deletions src/main/java/lotto/controller/LottoController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package lotto.controller;

import lotto.domain.Lotto;

import lotto.domain.Winning;
import lotto.service.LottoService;
import lotto.utils.Parsing;
import lotto.view.InputView;
import lotto.view.OutputView;

import java.util.List;

import static java.lang.System.in;

public class LottoController {
InputView inputView;
OutputView outputView;
LottoService service;

public LottoController(InputView inputView, OutputView outputView, LottoService service){
this.inputView = inputView;
this.outputView = outputView;
this.service = service;
}
public void run(){
outputView.purchasePrint();
String purchaseInput = inputView.purchaseInput();
int lottoQuantity = service.lottoQuantity(purchaseInput);
outputView.quantityPrint(lottoQuantity);
List<Lotto> lottos = service.issueLottos(lottoQuantity);
outputView.lottosPrint(lottos);
outputView.winningNumberPrint();
String winningNumberInput = inputView.winningNumberInput();
outputView.bonusNumberPrint();
String bonusNumberInput = inputView.bonusNumberInput();
List<Winning> results = Winning.FIRST.findWinningDetail(lottos, winningNumberInput, bonusNumberInput);
outputView.resultPrint(results);
double profit = Winning.FIRST.profitRate(purchaseInput);
outputView.profitPrint(profit);
}
}
24 changes: 24 additions & 0 deletions src/main/java/lotto/domain/GenerateLottos.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package lotto.domain;

import camp.nextstep.edu.missionutils.Randoms;

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

public class GenerateLottos{
List<Lotto> lottos = new ArrayList<>();

public Lotto generateLotto() {
List<Integer> sixRandomNumbers = Randoms.pickUniqueNumbersInRange(1, 45, 6);
return new Lotto(sixRandomNumbers);
}

public List<Lotto> addLotto(Lotto lotto){
lottos.add(lotto);
return lottos;
}

public List<Lotto> getLottos(){
return lottos;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package lotto;
package lotto.domain;

import java.util.HashSet;
import java.util.List;
import camp.nextstep.edu.missionutils.Randoms;

public class Lotto {
private final List<Integer> numbers;
Expand All @@ -14,7 +16,12 @@ private void validate(List<Integer> numbers) {
if (numbers.size() != 6) {
throw new IllegalArgumentException("[ERROR] 로또 번호는 6개여야 합니다.");
}
if (new HashSet<>(numbers).size() != numbers.size()) {
throw new IllegalArgumentException("[ERROR] 로또 번호에 중복된 숫자가 있습니다.");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

에러 메시지는 error 패키지에서 따로 관리하면 더 좋을 것 같습니다.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

아 그러네요!! 감사합니다😊

}
}

// TODO: 추가 기능 구현
public List<Integer> getLotto(){
return numbers;
}
}
107 changes: 107 additions & 0 deletions src/main/java/lotto/domain/Winning.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package lotto.domain;

import lotto.utils.Parsing;

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

public enum Winning {
FIFTH(3,"5,000",0),
FOURTH(4,"50,000",0),
THIRD(5,"1,500,000", 0),
SECOND(5,"30,000,000", 0),
FIRST(6,"2,000,000,000", 0);

private int numberOfMatches;
private String prizeMoney;
private int numberOfLottos;

Winning(int numberOfMatches, String prizeMoney, int numberOfLottos){
this.numberOfMatches = numberOfMatches;
this.prizeMoney = prizeMoney;
this.numberOfLottos = numberOfLottos;
}

public int getNumberOfMatches() {
return numberOfMatches;
}

public String getPrizeMoney() {
return prizeMoney;
}

public int getNumberOfLottos() {
return numberOfLottos;
}

public List<Winning> findWinningDetail(List<Lotto> lottos, String winningNumberInput, String bonusNumberInput) {
Parsing parsing = new Parsing();
int getvalidNumber = 0;
int getvalidBonus = 0;
List<Integer> getWinningNumber = parsing.stringToIntegerArray(winningNumberInput);
for(Lotto lotto : lottos){
getvalidNumber = compareLottoAndWinning(lotto.getLotto(),getWinningNumber);
getvalidBonus = compareLottoAndBonus(lotto.getLotto(),parsing.stringToInteger(bonusNumberInput));
if (3<= getvalidNumber){
increaseNumberOfLottos(getvalidNumber,getvalidBonus);
}
}

List<Winning> winningResults = new ArrayList<>();
for (Winning winning : Winning.values()) {
winningResults.add(winning);
}
return winningResults;
}

public int compareLottoAndWinning(List<Integer> lotto, List<Integer> getWinningNumber){
int matchingNumber = 0;
for(int i=0; i<6; i++){
boolean hasWinningNumber = lotto.contains(getWinningNumber.get(i));
if(hasWinningNumber){
matchingNumber += 1;
}
}
return matchingNumber;
}

public int compareLottoAndBonus(List<Integer> lotto, int bonusNumberInput){
int matchingNumber = 0;
for(int i=0; i<6; i++){
boolean hasWinningNumber = lotto.contains(bonusNumberInput);
if(hasWinningNumber){
matchingNumber += 1;
}
}
return matchingNumber;
}

public void increaseNumberOfLottos(int getvalidNumber, int getvalidBonus){
for (Winning winning : Winning.values()) {
if (winning.numberOfMatches == 5 && getvalidNumber == 5 && getvalidBonus==1) {
winning.numberOfLottos += 1;
break;
}

if (winning.numberOfMatches == getvalidNumber) {
winning.numberOfLottos += 1;
break;
}
}

}

public double profitRate(String purchaseInput) {
int totalPrize = 0;

for (Winning result : Winning.values()) {
int prizeAmount = Integer.parseInt(result.getPrizeMoney().replace(",", ""));
totalPrize += prizeAmount * result.getNumberOfLottos();
}
Parsing parsing = new Parsing();
int purchase = parsing.stringToInteger(purchaseInput);
double profitRate = (double) totalPrize / purchase * 100;
return Math.round(profitRate * 100) / 100.0;
}

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

import lotto.domain.Lotto;
import lotto.domain.GenerateLottos;
import lotto.utils.Parsing;
import lotto.utils.Validator;

import java.util.List;

public class LottoService {
Validator validator;
Parsing parsing;
GenerateLottos generateLottos;

public LottoService(Validator validator, Parsing parsing, GenerateLottos generateLottos){
this.validator = validator;
this.parsing = parsing;
this.generateLottos = generateLottos;
}


//로또 발행 수량
public int lottoQuantity(String purchaseInput){
if(!validator.isPositiveInteger(purchaseInput)){
throw new IllegalArgumentException("[ERROR] 양의 정수를 입력해주세요.");
}

int purchase = parsing.stringToInteger(purchaseInput);

if(!validator.isDivisibleBy1000(purchase)){
throw new IllegalArgumentException("[ERROR] 1,000원 단위로 입력해주세요.");
}
return purchase/1000;
}

//수량만큼 로또 발행
public List<Lotto> issueLottos(int lottoQuantity){
for(int i=0; i<lottoQuantity; i++){
generateLottos.addLotto(generateLottos.generateLotto());
}
return generateLottos.getLottos();
}
}
19 changes: 19 additions & 0 deletions src/main/java/lotto/utils/Parsing.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package lotto.utils;

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

public class Parsing {
public int stringToInteger(String purchaseInput){
return Integer.parseInt(purchaseInput);
}

public List<Integer> stringToIntegerArray(String winningNumberInput){
String[] separated = winningNumberInput.split(",");
List<Integer> getIntegerArray = new ArrayList<>();
for(String str:separated){
getIntegerArray.add(Integer.parseInt(str));
}
return getIntegerArray;
}
}
15 changes: 15 additions & 0 deletions src/main/java/lotto/utils/Validator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package lotto.utils;

public class Validator {

public boolean isPositiveInteger(String purchaseInput){
return purchaseInput.matches("^[1-9]\\d*$");
}

public boolean isDivisibleBy1000(int purchase){
if(purchase%100 == 0){
return true;
}
return false;
}
}
15 changes: 15 additions & 0 deletions src/main/java/lotto/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package lotto.view;
import camp.nextstep.edu.missionutils.Console;
public class InputView {

public String purchaseInput(){
return Console.readLine();
}

public String winningNumberInput(){
return Console.readLine();
}
public String bonusNumberInput(){
return Console.readLine();
}
}
Loading