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
75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,76 @@
# java-lotto-precourse

### 기능 요구사항

1. 사용자 입력 처리
- 사용자로부터 다음 세 가지 값을 입력받는다:
- 로또 구입 비용
- 당첨 번호
- 보너스 번호
- 각 입력값에 대해 유효성을 검사하고 잘못된 경우 `IllegalArgumentException`을 발생시킨다:
- **로또 번호 입력**
- 입력된 로또 번호는 반드시 6개여야 하며, 1부터 45 사이의 정수만 포함해야 한다.
- 중복된 번호가 있을 경우 예외를 발생시킨다.
- **보너스 번호 입력**
- 보너스 번호는 1부터 45 사이의 정수여야 하며, 로또 번호와 중복되면 예외를 발생시킨다.
- **로또 구입 비용 입력**
- 로또 구입 비용은 비어있지 않아야 하며, 양수여야 한다.
- 1000원 단위여야 하며, 그렇지 않을 경우 예외를 발생시킨다.
- 입력값이 숫자가 아닐 경우 예외를 발생시킨다.
- 입력값이 0 이하일 경우 예외를 발생시킨다.

2. 로또 번호 파싱
- 사용자가 입력한 당첨 번호와 보너스 번호는 `','`를 기준으로 분리하여 정수 리스트로 변환한다.
- 각 번호가 유효한지 (1~45 범위) 확인한다.

3. 랜덤 로또 번호 생성기
- 로또 번호 생성기는 다음 방식으로 랜덤 번호를 생성한다:
- `RandomNumberCreator` 클래스에서 `createRandomNum(int start, int end, int count)` 메서드를 사용하여 1부터 45까지의 숫자 중 6개의 고유한 랜덤 숫자를 생성한다.
- 생성된 숫자는 오름차순으로 정렬된다.
- 생성된 번호는 `Lotto` 클래스에 전달되어 유효성 검사를 받는다 (6개 번호, 1~45 범위, 중복 검사).
- 사용자가 입력한 로또 구입 비용을 바탕으로 몇 개의 로또를 구매할 수 있는지 계산하고, 해당 수만큼 랜덤 로또 번호를 생성하여 `Lottos` 클래스에 추가한다.

4. 당첨 결과 처리
- 사용자가 입력한 당첨 번호와 보너스 번호를 기반으로 각 구매한 로또의 당첨 결과를 계산한다.
- 로또의 결과는 다음 기준에 따라 등급을 매긴다:
- 6개 일치: 1등
- 5개 일치 + 보너스 번호 일치: 2등
- 5개 일치: 3등
- 4개 일치: 4등
- 3개 일치: 5등
- 각 로또의 번호와 비교하여 당첨 결과를 저장한다.

5. 결과 출력
- 각 등급에 따른 당첨자 수를 출력한다.
- 총 수익률을 계산하여 출력한다.
- 수익률은 (총 당첨금 / 총 구입 비용) * 100의 형태로 계산하여 소수점 한 자리까지 출력한다.

### 패키지 구조
1. Application: 메인 애플리케이션 클래스. 프로그램의 시작 지점으로, 로또 플레이어를 초기화하고 실행합니다.
2. parser
- BonusNumberParser: 문자열로 입력된 보너스 번호를 정수로 파싱하고, 유효성을 검사하는 클래스입니다.
- LottoParser: 사용자로부터 입력받은 로또 번호 문자열을 파싱하여 Lotto 객체로 변환하는 클래스입니다.
- PriceParser: 로또 구입 비용을 파싱하고, 유효성을 검사하는 클래스입니다.
3. adapter
- InputAdapter: 입력 인터페이스를 구현하여 로또 번호, 보너스 번호, 구매 비용을 입력받는 기능을 제공합니다.
4. input
- Input: 로또 번호와 보너스 번호, 구매 비용을 입력받기 위한 인터페이스입니다.
- AutoLottoInput: 콘솔을 통해 사용자로부터 입력을 받는 클래스입니다.
5. output
- Output: 로또 당첨 결과를 출력하는 클래스입니다.
6. lottoPlayer
- LottoType: 로또 타입을 정의하는 열거형입니다. 현재는 AUTO 타입만 있습니다.
- LottoPlayer: 로또 플레이어 클래스로, 로또 게임을 시작하는 기능을 담당합니다.
- LottoList: 로또 타입에 따라 로또 객체를 반환하는 클래스입니다.
7. woowaLotto
- WooWaLotto: 로또 게임을 실행하기 위한 인터페이스입니다.
- WooWaAutoLotto: 자동 로또 구매 및 결과 계산 기능을 가진 클래스입니다.
8. handler
- AutoLottoHandler: 자동 로또 번호 생성을 위한 핸들러로, 로또 결과를 계산하고 반환합니다.
9. domain
- Lotto: 로또 번호를 관리하는 클래스입니다. 유효성 검사를 포함합니다.
- LottoResult: 로또 결과 및 수익률을 관리하는 클래스입니다.
- Lottos: 여러 개의 로또 번호를 관리하는 클래스입니다.
- PickedLotto: 사용자가 선택한 로또 번호와 보너스 번호를 관리하는 클래스입니다.
10. util
- RandomNumberCreator: 랜덤으로 로또 번호를 생성하는 유틸리티 클래스입니다.
5 changes: 5 additions & 0 deletions src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package lotto;

import lotto.woowaLotto.lottoPlayer.LottoList;
import lotto.woowaLotto.lottoPlayer.LottoPlayer;
import lotto.woowaLotto.lottoPlayer.LottoType;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
new LottoPlayer().start(LottoList.getLottoWay(LottoType.AUTO));
}
}
20 changes: 0 additions & 20 deletions src/main/java/lotto/Lotto.java

This file was deleted.

31 changes: 31 additions & 0 deletions src/main/java/lotto/woowaLotto/common/adapter/InputAdapter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package lotto.woowaLotto.common.adapter;

import lotto.woowaLotto.common.adapter.parser.BonusNumberParser;
import lotto.woowaLotto.common.adapter.parser.LottoParser;
import lotto.woowaLotto.common.adapter.parser.PriceParser;
import lotto.woowaLotto.common.ui.input.Input;
import lotto.woowaLotto.lottoPlayer.woowaLotto.autoLotto.handler.domain.Lotto;

public class InputAdapter {

private final LottoParser lottoParser = new LottoParser();
private final PriceParser priceParser = new PriceParser();
private final BonusNumberParser bonusNumberParser = new BonusNumberParser();
private final Input input;

public InputAdapter(Input Input) {
this.input = Input;
}

public Lotto inputLotto() {
return lottoParser.parse(input.inputPickedNum());
}

public int inputBonusNum(){
return bonusNumberParser.parse(input.inputBonusNum());
}

public int inputPrice() {
return priceParser.parse(input.inputLottoPrice());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package lotto.woowaLotto.common.adapter.parser;

public class BonusNumberParser {

public Integer parse(String input) {
try{
int bonusNum = Integer.parseInt(input);
valid(bonusNum);
return bonusNum;
}
catch(NumberFormatException e){
throw new IllegalArgumentException("[ERROR] 보너스 번호는 정수여야 합니다.");
}
}

private void valid(int bonusNum){
if(bonusNum < 1 || bonusNum > 45){
throw new IllegalArgumentException("[ERROR] 보너스 번호는 1부터 45 사이의 숫자여야 합니다.");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package lotto.woowaLotto.common.adapter.parser;

import java.util.ArrayList;
import java.util.List;
import lotto.woowaLotto.lottoPlayer.woowaLotto.autoLotto.handler.domain.Lotto;

public class LottoParser {

public Lotto parse(String input) {
List<Integer> parsedList = parseInput(input);

return new Lotto(parsedList);
}

private List<Integer> parseInput(String input) {
List<Integer> parsedList = new ArrayList<>();
try {
for (String lottoWord : input.split(",")) {
parsedList.add(Integer.parseInt(lottoWord.trim()));
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("[ERROR] 로또 번호는 정수여야합니다.");
}
return parsedList;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package lotto.woowaLotto.common.adapter.parser;

public class PriceParser{

public int parse(String input) {
validEmpty(input);
try{
int price = Integer.parseInt(input);
validUnit(price);
validRange(price);
return price;
}
catch (NumberFormatException e){
System.out.println("[ERROR] 로또 구입 비용은 정수여야 합니다.");
e.printStackTrace();
return 0;
}
}

private void validEmpty(String input) {
if (input == null || input.trim().isEmpty()) {
throw new IllegalArgumentException("[ERROR] 로또 구입 비용은 비어있을 수 없습니다.");
}
}

private void validRange(int price) {
if(price <= 0){
throw new IllegalArgumentException("[ERROR] 로또 구입 비용은 양수여야 합니다.");
}
}

private void validUnit(int price){
if(price % 1000 != 0){
throw new IllegalArgumentException("[ERROR] 로또 구입 비용은 1000원 단위여야 합니다.");
}
}
}
31 changes: 31 additions & 0 deletions src/main/java/lotto/woowaLotto/common/ui/input/AutoLottoInput.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package lotto.woowaLotto.common.ui.input;

import camp.nextstep.edu.missionutils.Console;

public class AutoLottoInput implements Input{


@Override
public String inputLottoPrice() {
System.out.println("구입금액을 입력해 주세요.");
String price = Console.readLine();
System.out.println();
return price;
}

@Override
public String inputPickedNum() {
System.out.println("당첨 번호를 입력해 주세요.");
String pickedNum = Console.readLine();
System.out.println();
return pickedNum;
}

@Override
public String inputBonusNum() {
System.out.println("보너스 번호를 입력해 주세요.");
String bonusNum = Console.readLine();
System.out.println();
return bonusNum;
}
}
10 changes: 10 additions & 0 deletions src/main/java/lotto/woowaLotto/common/ui/input/Input.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package lotto.woowaLotto.common.ui.input;

public interface Input {

String inputLottoPrice();

String inputPickedNum();

String inputBonusNum();
}
22 changes: 22 additions & 0 deletions src/main/java/lotto/woowaLotto/common/ui/output/Output.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package lotto.woowaLotto.common.ui.output;

import java.util.Map;
import lotto.woowaLotto.lottoPlayer.woowaLotto.autoLotto.handler.domain.LottoResult;

public class Output {

public void printResult(LottoResult result) {

Map<Integer,Integer> rank = result.getRank();
float roi = result.getRoi();

System.out.println("당첨 통계\n---");
System.out.printf("%d개 일치 (5,000원) - %d개%n", 3,rank.get(5));
System.out.printf("%d개 일치 (50,000원) - %d개%n", 4,rank.get(4));
System.out.printf("%d개 일치 (1,500,000원) - %d개%n", 5,rank.get(3));
System.out.printf("%d개 일치, 보너스 볼 일치 (30,000,000원) - %d개%n", 5,rank.get(2));
System.out.printf("%d개 일치 (2,000,000,000원) - %d개%n", 6,rank.get(1));
System.out.printf("총 수익률은 %.1f%%입니다.%n", roi);
}

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

import java.util.HashMap;
import java.util.Map;
import lotto.woowaLotto.lottoPlayer.woowaLotto.WooWaLotto;
import lotto.woowaLotto.lottoPlayer.woowaLotto.autoLotto.WooWaAutoLotto;

public class LottoList {

private final static Map<LottoType, WooWaLotto> lottos = new HashMap<>() {{
put(LottoType.AUTO,new WooWaAutoLotto());
}};

public static WooWaLotto getLottoWay(LottoType lottoType){
return lottos.get(lottoType);
}
}
10 changes: 10 additions & 0 deletions src/main/java/lotto/woowaLotto/lottoPlayer/LottoPlayer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package lotto.woowaLotto.lottoPlayer;

import lotto.woowaLotto.lottoPlayer.woowaLotto.WooWaLotto;

public class LottoPlayer {

public void start(WooWaLotto wooWaLotto){
wooWaLotto.draw();
}
}
5 changes: 5 additions & 0 deletions src/main/java/lotto/woowaLotto/lottoPlayer/LottoType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package lotto.woowaLotto.lottoPlayer;

public enum LottoType {
AUTO
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package lotto.woowaLotto.lottoPlayer.woowaLotto;

public interface WooWaLotto {

void draw();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package lotto.woowaLotto.lottoPlayer.woowaLotto.autoLotto;

import lotto.woowaLotto.common.adapter.InputAdapter;
import lotto.woowaLotto.common.ui.input.AutoLottoInput;
import lotto.woowaLotto.common.ui.output.Output;
import lotto.woowaLotto.lottoPlayer.woowaLotto.WooWaLotto;
import lotto.woowaLotto.lottoPlayer.woowaLotto.autoLotto.handler.AutoLottoHandler;
import lotto.woowaLotto.lottoPlayer.woowaLotto.autoLotto.handler.domain.Lotto;
import lotto.woowaLotto.lottoPlayer.woowaLotto.autoLotto.handler.domain.LottoResult;
import lotto.woowaLotto.lottoPlayer.woowaLotto.autoLotto.handler.domain.Lottos;
import lotto.woowaLotto.lottoPlayer.woowaLotto.autoLotto.handler.domain.PickedLotto;

public class WooWaAutoLotto implements WooWaLotto {

private final InputAdapter inputAdapter = new InputAdapter(new AutoLottoInput());
private final AutoLottoHandler autoLottoHandler = new AutoLottoHandler();
private final Output output = new Output();

@Override
public void draw() {
int price = getInputPrice();
Lottos lottos = autoLottoHandler.getRandomLottos(price);
PickedLotto pickedLotto = getPickedLotto();
LottoResult result = autoLottoHandler.getResult(lottos, pickedLotto, price);

output.printResult(result);
}

private int getInputPrice() {
return inputAdapter.inputPrice();
}

private PickedLotto getPickedLotto() {
Lotto pickedLottoNums = inputAdapter.inputLotto();
int bonusNum = inputAdapter.inputBonusNum();
return new PickedLotto(pickedLottoNums, bonusNum);
}
}
Loading