From 1acb64429a5b2d7ee7da036c90b8704afc3a928c Mon Sep 17 00:00:00 2001 From: eunho Date: Thu, 30 Oct 2025 18:44:32 +0900 Subject: [PATCH 01/23] chore: update .gitignore and README --- .gitignore | 67 ++++++++++++++++++++++++++++++---------------------- README.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 107 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index 5dca701a77..68c92da03d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,35 +1,46 @@ -HELP.md -.gradle -build/ +# ===================================== +# (Java / Gradle / IntelliJ 프로젝트 기준) +# ===================================== + +# === 빌드 & 실행 결과물 === +/build/ +out/ +bin/ +.gradle/ !gradle/wrapper/gradle-wrapper.jar -!**/src/main/** -!**/src/test/** - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -### IntelliJ IDEA ### -.idea -*.iws + +# === IntelliJ IDEA 설정 === +.idea/ *.iml *.ipr -out/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ +*.iws -### VS Code ### +# === VSCode (혹시 사용할 경우) === .vscode/ -### Mac OS ### +# === OS 자동 생성 파일 === .DS_Store +Thumbs.db + +# === 로그 & 캐시 파일 === +*.log +*.tmp +*.bak +*.swp + +# === 컴파일 산출물 === +*.class +*.jar +*.war +*.ear + +# === 테스트 관련 === +/test-output/ +/reports/ + +# === 환경변수, 개인 설정 === +*.env +*.local + +# === 백업 파일 === +*~ diff --git a/README.md b/README.md index 5fa2560b46..2af98e5f9d 100644 --- a/README.md +++ b/README.md @@ -1 +1,68 @@ -# java-lotto-precourse +# 🎰 로또 + +--- +## ⚙️ 구현 목록 + +### 입력 + +### 로또 생성 및 로직 + +### 출력 + +### 예외 처리 + +--- + +## 🧪 실행 예시 + +```markdown +구입금액을 입력해 주세요. +8000 + +8개를 구매했습니다. +[8, 21, 23, 41, 42, 43] +[3, 5, 11, 16, 32, 38] +... + +당첨 번호를 입력해 주세요. +1,2,3,4,5,6 +보너스 번호를 입력해 주세요. +7 + +당첨 통계 + +3개 일치 (5,000원) - 1개 +4개 일치 (50,000원) - 0개 +5개 일치 (1,500,000원) - 0개 +5개 일치, 보너스 볼 일치 (30,000,000원) - 0개 +6개 일치 (2,000,000,000원) - 0개 +총 수익률은 62.5%입니다. +``` + +## ✅ 피드백 기반 미니 퀘스트 + +--- + +### 🚗 2주차 피드백 +- [ ] **README.md를 살아있는 문서로 유지** + - 기능 목록을 구현하면서 지속적으로 업데이트 + - 정상/예외 흐름 모두 포함 +- [ ] **값 하드코딩 금지** + - 상수(`private static final`)로 선언하고 의미 있는 이름 부여 +- [ ] **클래스 작성 순서 준수** 상수 → 멤버 변수 → 생성자 → 메서드 +- [ ] **메서드는 한 가지 일만 하도록 분리** +- 길이가 15라인 이상이라면 분리 고려 +- 입출력, 검증, 로직을 분리하여 책임 명확화 +- [ ] **중복 로직은 별도 메서드로 추출** +- 동일한 검증/출력 로직이 여러 곳에 있다면 재사용하도록 리팩터링 +- [ ] **테스트 코드 작성 및 단위 분리** +- 큰 단위 테스트보다 기능 단위로 쪼개어 작성 +- 예: + - 무작위 값이 4 이상일 때 전진 + - 무작위 값이 3 이하일 때 멈춤 +- [ ] **하드코딩된 문자열 대신 상수 사용** +- [ ] **테스트의 목적을 명확히 이해** +- "내 코드가 동작하나?"가 아니라 + "내 코드가 **의도한 대로** 동작하나?"를 검증 + +--- \ No newline at end of file From 21af506d0f26eb33f8dee906fbab4a0222b32315 Mon Sep 17 00:00:00 2001 From: eunho Date: Thu, 30 Oct 2025 19:39:50 +0900 Subject: [PATCH 02/23] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=9E=91=EC=84=B1=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 2af98e5f9d..73f8146865 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,25 @@ ## ⚙️ 구현 목록 ### 입력 +- [ ] 구입 금액 입력 (콘솔 입력, 1000원 단위 검증) +- [ ] 당첨 번호 6개 입력 (쉼표 구분) +- [ ] 보너스 번호 1개 입력 -### 로또 생성 및 로직 +### 로또 로직 +- [ ] 구입 금액만큼 로또 생성 +- [ ] 당첨 번호 및 보너스 번호 저장 +- [ ] 구매한 로또 번호 비교 +- [ ] 일치 및 보너스 여부에 따른 등수 계산 +- [ ] 당첨 내역 및 수익률 계산 ### 출력 +- [ ] 구매한 로또 수량 및 번호 출력 +- [ ] 당첨 내역 및 등수별 결과 출력 +- [ ] 총 수익률 출력 (소수점 둘째 자리, nn.n%) + ### 예외 처리 +- [ ] 잘못된 입력 시 `[ERROR]`로 시작하는 에러 메시지 출력 후 재입력 --- @@ -38,31 +51,16 @@ 6개 일치 (2,000,000,000원) - 0개 총 수익률은 62.5%입니다. ``` +--- ## ✅ 피드백 기반 미니 퀘스트 ---- +### 🚗 2주차 피드백 반영 (✅ 이미 완료된 항목 제외) +- **테스트 코드 작성 및 단위 분리** + - 이번 주는 본격적으로 도메인 중심 단위 테스트를 작성한다. +- **테스트의 목적을 명확히 이해** + - “동작 확인”이 아니라 “의도 검증” 중심으로 작성 +- **입력/출력(UI)과 로직 분리** + - 기존 분리 구조 유지, 로또 로직은 도메인 중심으로 구성 -### 🚗 2주차 피드백 -- [ ] **README.md를 살아있는 문서로 유지** - - 기능 목록을 구현하면서 지속적으로 업데이트 - - 정상/예외 흐름 모두 포함 -- [ ] **값 하드코딩 금지** - - 상수(`private static final`)로 선언하고 의미 있는 이름 부여 -- [ ] **클래스 작성 순서 준수** 상수 → 멤버 변수 → 생성자 → 메서드 -- [ ] **메서드는 한 가지 일만 하도록 분리** -- 길이가 15라인 이상이라면 분리 고려 -- 입출력, 검증, 로직을 분리하여 책임 명확화 -- [ ] **중복 로직은 별도 메서드로 추출** -- 동일한 검증/출력 로직이 여러 곳에 있다면 재사용하도록 리팩터링 -- [ ] **테스트 코드 작성 및 단위 분리** -- 큰 단위 테스트보다 기능 단위로 쪼개어 작성 -- 예: - - 무작위 값이 4 이상일 때 전진 - - 무작위 값이 3 이하일 때 멈춤 -- [ ] **하드코딩된 문자열 대신 상수 사용** -- [ ] **테스트의 목적을 명확히 이해** -- "내 코드가 동작하나?"가 아니라 - "내 코드가 **의도한 대로** 동작하나?"를 검증 - ---- \ No newline at end of file +--- From 14a1aff64d50f688bea96e4177301f1c4dde5745 Mon Sep 17 00:00:00 2001 From: eunho Date: Fri, 31 Oct 2025 18:03:40 +0900 Subject: [PATCH 03/23] =?UTF-8?q?docs:=20=EB=8B=A8=EC=9C=84=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EA=B3=84=ED=9A=8D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index 73f8146865..8a8078c0ab 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,31 @@ ``` --- +## 🧩 단위 테스트 계획 + +### LottoTest +- [ ] 로또 번호 개수가 6개가 아니면 예외 +- [ ] 로또 번호에 중복된 숫자가 있으면 예외 발생 +- [ ] 로또 번호가 1~45 범위를 벗어나면 예외 발생 + +### RankTest +- [ ] 일치 개수가 6개면 1등으로 판단 +- [ ] 일치 개수가 5개이고 보너스 번호 일치 시 2등으로 판단 +- [ ] 일치 개수가 5개이고 보너스 번호 불일치 시 3등으로 판단 +- [ ] 일치 개수가 4개면 4등으로 판단 +- [ ] 일치 개수가 3개면 5등으로 판단 +- [ ] 일치 개수가 2개 이하일 경우 당첨 아님 처리 + +### LottoResultTest +- [ ] 여러 로또의 당첨 결과 집계가 정확한지 확인 +- [ ] 수익률 계산이 정확한지 검증 (소수점 둘째 자리 반올림) + +### LottoMachineTest +- [ ] 구입 금액에 따라 로또가 알맞게 생성되는지 확인 +- [ ] 생성된 모든 로또가 중복되지 않고 유효한 번호를 가지는지 검증 + +--- + ## ✅ 피드백 기반 미니 퀘스트 ### 🚗 2주차 피드백 반영 (✅ 이미 완료된 항목 제외) From 0902581b6886071ed583ca314bd01643aeda5162 Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 22:35:06 +0900 Subject: [PATCH 04/23] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/lotto/ApplicationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/lotto/ApplicationTest.java b/src/test/java/lotto/ApplicationTest.java index a15c7d1f52..d81765b7d5 100644 --- a/src/test/java/lotto/ApplicationTest.java +++ b/src/test/java/lotto/ApplicationTest.java @@ -13,7 +13,7 @@ class ApplicationTest extends NsTest { private static final String ERROR_MESSAGE = "[ERROR]"; @Test - void 기능_테스트() { + void Function_Test () { assertRandomUniqueNumbersInRangeTest( () -> { run("8000", "1,2,3,4,5,6", "7"); @@ -47,7 +47,7 @@ class ApplicationTest extends NsTest { } @Test - void 예외_테스트() { + void Exception_Test () { assertSimpleTest(() -> { runException("1000j"); assertThat(output()).contains(ERROR_MESSAGE); From ddd9af76c6cec11ef762c111979ba627bd923031 Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 22:35:37 +0900 Subject: [PATCH 05/23] =?UTF-8?q?feat:=20LottoTest=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/lotto/LottoTest.java | 44 ++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 309f4e50ae..b1945a8631 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -1,25 +1,45 @@ package lotto; -import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; - -import java.util.List; - import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.assertThat; +import java.util.List; class LottoTest { + @Test - void 로또_번호의_개수가_6개가_넘어가면_예외가_발생한다() { - assertThatThrownBy(() -> new Lotto(List.of(1, 2, 3, 4, 5, 6, 7))) - .isInstanceOf(IllegalArgumentException.class); + void WrongQuantityNumbersOfLotto_Test() { + List numbers = List.of(1, 2, 3, 4, 5); + + assertThatThrownBy(() -> new Lotto(numbers)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("로또 번호는 6개여야 합니다"); } - @DisplayName("로또 번호에 중복된 숫자가 있으면 예외가 발생한다.") @Test - void 로또_번호에_중복된_숫자가_있으면_예외가_발생한다() { - assertThatThrownBy(() -> new Lotto(List.of(1, 2, 3, 4, 5, 5))) - .isInstanceOf(IllegalArgumentException.class); + void DuplicateLotto_Test () { + List numbers = List.of(1, 2, 3, 3, 4, 5); + + assertThatThrownBy(() -> new Lotto(numbers)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("중복된 숫자는 허용되지 않습니다"); } - // TODO: 추가 기능 구현에 따른 테스트 코드 작성 + @Test + void WrongRangeOfLotto_Test () { + List numbers = List.of(0, 2, 3, 4, 5, 6); + + assertThatThrownBy(() -> new Lotto(numbers)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("로또 번호는 1부터 45 사이여야 합니다"); + } + + @Test + void SuccessLotto_Test() { + List numbers = List.of(1, 2, 3, 4, 5, 6); + + Lotto lotto = new Lotto(numbers); + + assertThat(lotto.getNumbers()).containsExactly(1, 2, 3, 4, 5, 6); + } } From 4332f1f73bfc750bb3d23652224d0aa91f63c1aa Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 22:35:49 +0900 Subject: [PATCH 06/23] =?UTF-8?q?docs:=20=EC=A7=84=ED=96=89=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8a8078c0ab..6a6f072538 100644 --- a/README.md +++ b/README.md @@ -56,9 +56,9 @@ ## 🧩 단위 테스트 계획 ### LottoTest -- [ ] 로또 번호 개수가 6개가 아니면 예외 -- [ ] 로또 번호에 중복된 숫자가 있으면 예외 발생 -- [ ] 로또 번호가 1~45 범위를 벗어나면 예외 발생 +- [x] 로또 번호 개수가 6개가 아니면 예외 +- [x] 로또 번호에 중복된 숫자가 있으면 예외 발생 +- [x] 로또 번호가 1~45 범위를 벗어나면 예외 발생 ### RankTest - [ ] 일치 개수가 6개면 1등으로 판단 From ca868029b48a203466bcd8beb25cd39fbbb69c3e Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 22:36:16 +0900 Subject: [PATCH 07/23] =?UTF-8?q?feat:=20=EB=8B=A8=EC=9C=84=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=9A=A9=20Lotto=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/Lotto.java | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java index 88fc5cf12b..691c63820f 100644 --- a/src/main/java/lotto/Lotto.java +++ b/src/main/java/lotto/Lotto.java @@ -1,20 +1,39 @@ package lotto; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class Lotto { + private static final int LOTTO_SIZE = 6; + private static final int MIN_NUMBER = 1; + private static final int MAX_NUMBER = 45; + private final List numbers; public Lotto(List numbers) { validate(numbers); - this.numbers = numbers; + this.numbers = List.copyOf(numbers); } private void validate(List numbers) { - if (numbers.size() != 6) { - throw new IllegalArgumentException("[ERROR] 로또 번호는 6개여야 합니다."); + if (numbers.size() != LOTTO_SIZE) { + throw new IllegalArgumentException("로또 번호는 6개여야 합니다"); + } + + Set unique = new HashSet<>(numbers); + if (unique.size() != LOTTO_SIZE) { + throw new IllegalArgumentException("중복된 숫자는 허용되지 않습니다"); + } + + boolean outOfRange = numbers.stream() + .anyMatch(n -> n < MIN_NUMBER || n > MAX_NUMBER); + if (outOfRange) { + throw new IllegalArgumentException("로또 번호는 1부터 45 사이여야 합니다"); } } - // TODO: 추가 기능 구현 + public List getNumbers() { + return numbers; + } } From a1d72e13274d1a9e224a412bbf41305a7ca78ed2 Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:04:39 +0900 Subject: [PATCH 08/23] =?UTF-8?q?feat:=20RankTest=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/lotto/RankTest.java | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/test/java/lotto/RankTest.java diff --git a/src/test/java/lotto/RankTest.java b/src/test/java/lotto/RankTest.java new file mode 100644 index 0000000000..35a2cb9ff7 --- /dev/null +++ b/src/test/java/lotto/RankTest.java @@ -0,0 +1,43 @@ +package lotto; + +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; + +class RankTest { + + @Test + void FirstRank_Test() { + assertThat(Rank.determineRank(6, true)).isEqualTo(Rank.FIRST); + assertThat(Rank.determineRank(6, false)).isEqualTo(Rank.FIRST); + } + + @Test + void SecondRank_Test() { + assertThat(Rank.determineRank(5, true)).isEqualTo(Rank.SECOND); + } + + @Test + void ThirdRank_Test() { + assertThat(Rank.determineRank(5, false)).isEqualTo(Rank.THIRD); + } + + @Test + void FourthRank_Test() { + assertThat(Rank.determineRank(4, true)).isEqualTo(Rank.FOURTH); + assertThat(Rank.determineRank(4, false)).isEqualTo(Rank.FOURTH); + } + + @Test + void FifthRank_Test() { + assertThat(Rank.determineRank(3, true)).isEqualTo(Rank.FIFTH); + assertThat(Rank.determineRank(3, false)).isEqualTo(Rank.FIFTH); + } + + @Test + void MissRank_Test() { + assertThat(Rank.determineRank(2, true)).isEqualTo(Rank.ZERO); + assertThat(Rank.determineRank(2, false)).isEqualTo(Rank.ZERO); + assertThat(Rank.determineRank(1, true)).isEqualTo(Rank.ZERO); + assertThat(Rank.determineRank(0, false)).isEqualTo(Rank.ZERO); + } +} \ No newline at end of file From e67e6121af9e80f6897904a2cfb464757774a1c7 Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:10:09 +0900 Subject: [PATCH 09/23] =?UTF-8?q?docs:=20=EC=A7=84=ED=96=89=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6a6f072538..1606bc346f 100644 --- a/README.md +++ b/README.md @@ -61,12 +61,12 @@ - [x] 로또 번호가 1~45 범위를 벗어나면 예외 발생 ### RankTest -- [ ] 일치 개수가 6개면 1등으로 판단 -- [ ] 일치 개수가 5개이고 보너스 번호 일치 시 2등으로 판단 -- [ ] 일치 개수가 5개이고 보너스 번호 불일치 시 3등으로 판단 -- [ ] 일치 개수가 4개면 4등으로 판단 -- [ ] 일치 개수가 3개면 5등으로 판단 -- [ ] 일치 개수가 2개 이하일 경우 당첨 아님 처리 +- [x] 일치 개수가 6개면 1등으로 판단 +- [x] 일치 개수가 5개이고 보너스 번호 일치 시 2등으로 판단 +- [x] 일치 개수가 5개이고 보너스 번호 불일치 시 3등으로 판단 +- [x] 일치 개수가 4개면 4등으로 판단 +- [x] 일치 개수가 3개면 5등으로 판단 +- [x] 일치 개수가 2개 이하일 경우 당첨 아님 처리 ### LottoResultTest - [ ] 여러 로또의 당첨 결과 집계가 정확한지 확인 From cb81c9524418c9d9428e59a5e82668e391ac4ce9 Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:29:25 +0900 Subject: [PATCH 10/23] =?UTF-8?q?feat:=20LottoResultTest=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/lotto/LottoResultTest.java | 59 ++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/test/java/lotto/LottoResultTest.java diff --git a/src/test/java/lotto/LottoResultTest.java b/src/test/java/lotto/LottoResultTest.java new file mode 100644 index 0000000000..77f605452c --- /dev/null +++ b/src/test/java/lotto/LottoResultTest.java @@ -0,0 +1,59 @@ +package lotto; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; + +class LottoResultTest { + + private LottoResult lottoResult; + + @BeforeEach + void setUp() { + lottoResult = new LottoResult(); + } + + @Test + void ResultAggregation_Test() { + lottoResult.addResult(Rank.FIFTH); + lottoResult.addResult(Rank.THIRD); + lottoResult.addResult(Rank.ZERO); + lottoResult.addResult(Rank.ZERO); + + assertThat(lottoResult.getCount(Rank.FIFTH)).isEqualTo(1); + assertThat(lottoResult.getCount(Rank.THIRD)).isEqualTo(1); + assertThat(lottoResult.getCount(Rank.ZERO)).isEqualTo(2); + + assertThat(lottoResult.getCount(Rank.FIRST)).isEqualTo(0); + assertThat(lottoResult.getCount(Rank.SECOND)).isEqualTo(0); + assertThat(lottoResult.getCount(Rank.FOURTH)).isEqualTo(0); + } + + @Test + void RateOfReturn_Example_Test() { + lottoResult.addResult(Rank.FIFTH); + + double rate = lottoResult.calculateRateOfReturn(8000); + + assertThat(rate).isEqualTo(62.5); + } + + @Test + void RateOfReturn_Rounding_Test() { + lottoResult.addResult(Rank.FIFTH); + + double rate = lottoResult.calculateRateOfReturn(3000); + + assertThat(rate).isEqualTo(166.7); + } + + @Test + void RateOfReturn_ZeroPrize_Test() { + lottoResult.addResult(Rank.ZERO); + lottoResult.addResult(Rank.ZERO); + + double rate = lottoResult.calculateRateOfReturn(2000); + + assertThat(rate).isEqualTo(0.0); + } +} \ No newline at end of file From e2a4c84980e28cfaeb0af4368132340f445f1516 Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:29:48 +0900 Subject: [PATCH 11/23] =?UTF-8?q?feat:=20LottoResult=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/LottoResult.java | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/main/java/lotto/LottoResult.java diff --git a/src/main/java/lotto/LottoResult.java b/src/main/java/lotto/LottoResult.java new file mode 100644 index 0000000000..1b38617163 --- /dev/null +++ b/src/main/java/lotto/LottoResult.java @@ -0,0 +1,43 @@ +package lotto; + +import java.util.EnumMap; // Enum에 최적화된 Map +import java.util.Map; + +public class LottoResult { + + private final Map resultCounts; + + public LottoResult() { + this.resultCounts = new EnumMap<>(Rank.class); + for (Rank rank : Rank.values()) { + resultCounts.put(rank, 0); + } + } + + public void addResult(Rank rank) { + resultCounts.put(rank, resultCounts.get(rank) + 1); + } + + public int getCount(Rank rank) { + return resultCounts.get(rank); + } + + private double calculateTotalPrize() { + double totalPrize = 0; + for (Rank rank : resultCounts.keySet()) { + totalPrize += (double) rank.getPrizeMoney() * resultCounts.get(rank); + } + return totalPrize; + } + + public double calculateRateOfReturn(int purchaseAmount) { + double totalPrize = calculateTotalPrize(); + if (purchaseAmount == 0) { + return 0.0; + } + + double rate = (totalPrize / purchaseAmount) * 100.0; + + return Math.round(rate * 10.0) / 10.0; + } +} \ No newline at end of file From 60fc6aeb885365aaa2e2ed3f963481e10a541ccf Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:30:11 +0900 Subject: [PATCH 12/23] =?UTF-8?q?feat:=20LottoMachine=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/LottoMachine.java | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/main/java/lotto/LottoMachine.java diff --git a/src/main/java/lotto/LottoMachine.java b/src/main/java/lotto/LottoMachine.java new file mode 100644 index 0000000000..72a44709fc --- /dev/null +++ b/src/main/java/lotto/LottoMachine.java @@ -0,0 +1,36 @@ +package lotto; + +import camp.nextstep.edu.missionutils.Randoms; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class LottoMachine { + public static final int LOTTO_PRICE = 1000; + + public List purchaseLottos(int purchaseAmount) { + validatePurchaseAmount(purchaseAmount); + int numberOfLottos = purchaseAmount / LOTTO_PRICE; + + List lottos = new ArrayList<>(); + for (int i = 0; i < numberOfLottos; i++) { + lottos.add(createLotto()); + } + return lottos; + } + + private Lotto createLotto() { + List numbers = Randoms.pickUniqueNumbersInRange(1, 45, 6); + + List sortedNumbers = new ArrayList<>(numbers); + Collections.sort(sortedNumbers); + + return new Lotto(sortedNumbers); + } + + private void validatePurchaseAmount(int purchaseAmount) { + if (purchaseAmount <= 0 || purchaseAmount % LOTTO_PRICE != 0) { + throw new IllegalArgumentException("[ERROR] 구입 금액은 1,000원 단위여야 합니다."); + } + } +} \ No newline at end of file From 9ba210823246e4a06605e081d7c6ba343781dd9a Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:30:32 +0900 Subject: [PATCH 13/23] =?UTF-8?q?feat:=20LottoMachineTest=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/lotto/LottoMachineTest.java | 59 +++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/test/java/lotto/LottoMachineTest.java diff --git a/src/test/java/lotto/LottoMachineTest.java b/src/test/java/lotto/LottoMachineTest.java new file mode 100644 index 0000000000..64cafd3e48 --- /dev/null +++ b/src/test/java/lotto/LottoMachineTest.java @@ -0,0 +1,59 @@ +package lotto; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class LottoMachineTest { + + private LottoMachine lottoMachine; + + @BeforeEach + void setUp() { + lottoMachine = new LottoMachine(); + } + + @Test + void PurchaseAmount_Test() { + int money = 8000; + + List lottos = lottoMachine.purchaseLottos(money); + assertThat(lottos.size()).isEqualTo(8); + } + + @Test + void InvalidPurchaseAmount_Test() { + int money = 1500; + + assertThatThrownBy(() -> lottoMachine.purchaseLottos(money)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("[ERROR] 구입 금액은 1,000원 단위여야 합니다."); + } + + @Test + void ZeroPurchaseAmount_Test() { + int money = 0; + + assertThatThrownBy(() -> lottoMachine.purchaseLottos(money)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("[ERROR] 구입 금액은 1,000원 단위여야 합니다."); + } + + @Test + void CreatedLottos_Validation_Test() { + int money = 1000; + + List lottos = lottoMachine.purchaseLottos(money); + + assertThat(lottos.size()).isEqualTo(1); + + Lotto lotto = lottos.get(0); + assertThat(lotto.getNumbers().size()).isEqualTo(6); + + List numbers = lotto.getNumbers(); + assertThat(numbers).isSorted(); + } +} \ No newline at end of file From 3d9042c8a59f07c5affb0bd3db6632a6967896ed Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:31:27 +0900 Subject: [PATCH 14/23] =?UTF-8?q?feat:=20Rank=20Enum=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/Rank.java | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/main/java/lotto/Rank.java diff --git a/src/main/java/lotto/Rank.java b/src/main/java/lotto/Rank.java new file mode 100644 index 0000000000..76db0e2f6a --- /dev/null +++ b/src/main/java/lotto/Rank.java @@ -0,0 +1,41 @@ +package lotto; + +public enum Rank { + // 3개 일치부터 6개 일치까지 순서대로 정의 + FIFTH(5_000, "3개 일치 (5,000원)"), + FOURTH(50_000, "4개 일치 (50,000원)"), + THIRD(1_500_000, "5개 일치 (1,500,000원)"), + SECOND(30_000_000, "5개 일치, 보너스 볼 일치 (30,000,000원)"), + FIRST(2_000_000_000, "6개 일치 (2,000,000,000원)"), + ZERO(0, ""); + + private final int prizeMoney; + private final String message; + + Rank(int prizeMoney, String message) { + this.prizeMoney = prizeMoney; + this.message = message; + } + + public int getPrizeMoney() { + return prizeMoney; + } + + public String getMessage() { + return message; + } + + public static Rank determineRank(int matchRank, boolean bonusRank) { + if (matchRank == 6) + return FIRST; + if (matchRank == 5 && bonusRank) + return SECOND; + if (matchRank == 5) + return THIRD; + if (matchRank == 4) + return FOURTH; + if (matchRank == 3) + return FIFTH; + return ZERO; + } +} \ No newline at end of file From d1bd24bb70d68e4638ff41a90842e09219178797 Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:32:28 +0900 Subject: [PATCH 15/23] =?UTF-8?q?refactor:=20whitespace=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/lotto/ApplicationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/lotto/ApplicationTest.java b/src/test/java/lotto/ApplicationTest.java index d81765b7d5..8889c73306 100644 --- a/src/test/java/lotto/ApplicationTest.java +++ b/src/test/java/lotto/ApplicationTest.java @@ -13,7 +13,7 @@ class ApplicationTest extends NsTest { private static final String ERROR_MESSAGE = "[ERROR]"; @Test - void Function_Test () { + void Function_Test() { assertRandomUniqueNumbersInRangeTest( () -> { run("8000", "1,2,3,4,5,6", "7"); @@ -47,7 +47,7 @@ void Function_Test () { } @Test - void Exception_Test () { + void Exception_Test() { assertSimpleTest(() -> { runException("1000j"); assertThat(output()).contains(ERROR_MESSAGE); From 4eb770c173b8c17757c154918c89bda642a48006 Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:32:38 +0900 Subject: [PATCH 16/23] =?UTF-8?q?refactor:=20whitespace=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/lotto/LottoTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index b1945a8631..4d45551a2c 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -17,7 +17,7 @@ void WrongQuantityNumbersOfLotto_Test() { } @Test - void DuplicateLotto_Test () { + void DuplicateLotto_Test() { List numbers = List.of(1, 2, 3, 3, 4, 5); assertThatThrownBy(() -> new Lotto(numbers)) @@ -26,7 +26,7 @@ void DuplicateLotto_Test () { } @Test - void WrongRangeOfLotto_Test () { + void WrongRangeOfLotto_Test() { List numbers = List.of(0, 2, 3, 4, 5, 6); assertThatThrownBy(() -> new Lotto(numbers)) From 15b7180d7af5f4c6dfd5218616bae7ea4789e140 Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:33:04 +0900 Subject: [PATCH 17/23] =?UTF-8?q?docs:=20=EC=A7=84=ED=96=89=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1606bc346f..963d0e5bdb 100644 --- a/README.md +++ b/README.md @@ -69,12 +69,12 @@ - [x] 일치 개수가 2개 이하일 경우 당첨 아님 처리 ### LottoResultTest -- [ ] 여러 로또의 당첨 결과 집계가 정확한지 확인 -- [ ] 수익률 계산이 정확한지 검증 (소수점 둘째 자리 반올림) +- [x] 여러 로또의 당첨 결과 집계가 정확한지 확인 +- [x] 수익률 계산이 정확한지 검증 (소수점 둘째 자리 반올림) ### LottoMachineTest -- [ ] 구입 금액에 따라 로또가 알맞게 생성되는지 확인 -- [ ] 생성된 모든 로또가 중복되지 않고 유효한 번호를 가지는지 검증 +- [x] 구입 금액에 따라 로또가 알맞게 생성되는지 확인 +- [x] 생성된 모든 로또가 중복되지 않고 유효한 번호를 가지는지 검증 --- From 507e97c96507e5b60ca4f4aed40f4e761536319d Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:52:16 +0900 Subject: [PATCH 18/23] =?UTF-8?q?feat:=20Application=EC=97=90=20=EA=B0=84?= =?UTF-8?q?=EB=8B=A8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/Application.java | 101 ++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 2 deletions(-) diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922ba4..5141ec4c34 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,104 @@ package lotto; +import camp.nextstep.edu.missionutils.Console; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + LottoMachine lottoMachine = new LottoMachine(); + OutputView outputView = new OutputView(); + LottoResult lottoResult = new LottoResult(); + + List lottos; + int money; + while (true) { + try { + System.out.println("구입금액을 입력해 주세요."); + String inputMoney = Console.readLine(); + money = parseNumber(inputMoney); + + lottos = lottoMachine.purchaseLottos(money); + + outputView.printPurchaseCount(lottos.size()); + outputView.printLottos(lottos); + break; + } catch (IllegalArgumentException e) { + outputView.printError(e.getMessage()); + } + } + + Lotto winningLotto; + while (true) { + try { + System.out.println("\n당첨 번호를 입력해 주세요."); + String inputWinningNumbers = Console.readLine(); + List numbers = parseWinningNumbers(inputWinningNumbers); + winningLotto = new Lotto(numbers); + break; + } catch (IllegalArgumentException e) { + outputView.printError(e.getMessage()); + } + } + + int bonusNumber; + while (true) { + try { + System.out.println("\n보너스 번호를 입력해 주세요."); + String inputBonusNumber = Console.readLine(); + bonusNumber = parseNumber(inputBonusNumber); + validateBonusNumber(winningLotto, bonusNumber); // 범위, 당첨 번호와 중복 검증 + break; + } catch (IllegalArgumentException e) { + outputView.printError(e.getMessage()); + } + } + + for (Lotto lotto : lottos) { + int matchCount = calculateMatchCount(lotto, winningLotto); + boolean bonusMatch = lotto.getNumbers().contains(bonusNumber); + + Rank rank = Rank.determineRank(matchCount, bonusMatch); + lottoResult.addResult(rank); + } + + outputView.printStatistics(lottoResult); + double rateOfReturn = lottoResult.calculateRateOfReturn(money); + outputView.printRateOfReturn(rateOfReturn); + } + + private static List parseWinningNumbers(String input) { + try { + return Stream.of(input.split(",")) + .map(String::trim) + .map(Integer::parseInt) + .collect(Collectors.toList()); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("[ERROR] 당첨 번호는 숫자여야 합니다."); + } + } + + private static int parseNumber(String input) { + try { + return Integer.parseInt(input.trim()); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("[ERROR] 숫자를 입력해야 합니다."); + } + } + + private static void validateBonusNumber(Lotto winningLotto, int bonusNumber) { + if (bonusNumber < 1 || bonusNumber > 45) { + throw new IllegalArgumentException("[ERROR] 보너스 번호는 1부터 45 사이의 숫자여야 합니다."); + } + if (winningLotto.getNumbers().contains(bonusNumber)) { + throw new IllegalArgumentException("[ERROR] 보너스 번호는 당첨 번호와 중복될 수 없습니다."); + } + } + + private static int calculateMatchCount(Lotto userLotto, Lotto winningLotto) { + return (int) userLotto.getNumbers().stream() + .filter(winningLotto.getNumbers()::contains) + .count(); } -} +} \ No newline at end of file From 11e4a78eed4167e0563a701a4defab6e0417c919 Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:52:41 +0900 Subject: [PATCH 19/23] =?UTF-8?q?feat:=20OutputView=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/OutputView.java | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/main/java/lotto/OutputView.java diff --git a/src/main/java/lotto/OutputView.java b/src/main/java/lotto/OutputView.java new file mode 100644 index 0000000000..a0a7edf11c --- /dev/null +++ b/src/main/java/lotto/OutputView.java @@ -0,0 +1,44 @@ +package lotto; + +import java.util.List; + +public class OutputView { + + public void printPurchaseCount(int count) { + System.out.println("\n" + count + "개를 구매했습니다."); + } + + public void printLottos(List lottos) { + for (Lotto lotto : lottos) { + System.out.println(lotto.getNumbers().toString()); + } + } + + public void printStatistics(LottoResult lottoResult) { + System.out.println("\n당첨 통계"); + System.out.println("---"); + + List ranksToPrint = List.of( + Rank.FIFTH, + Rank.FOURTH, + Rank.THIRD, + Rank.SECOND, + Rank.FIRST + ); + + for (Rank rank : ranksToPrint) { + String message = rank.getMessage(); // "3개 일치 (5,000원)" + int count = lottoResult.getCount(rank); + + System.out.println(message + " - " + count + "개"); + } + } + + public void printRateOfReturn(double rate) { + System.out.printf("총 수익률은 %.1f%%입니다.\n", rate); + } + + public void printError(String message) { + System.out.println(message); + } +} \ No newline at end of file From bdb0618deaff45eb660f4901e5cd0b42138c2e18 Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:56:29 +0900 Subject: [PATCH 20/23] =?UTF-8?q?refactor:=20whitespaces=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/Application.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index 5141ec4c34..5dfc3010ca 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -48,7 +48,7 @@ public static void main(String[] args) { System.out.println("\n보너스 번호를 입력해 주세요."); String inputBonusNumber = Console.readLine(); bonusNumber = parseNumber(inputBonusNumber); - validateBonusNumber(winningLotto, bonusNumber); // 범위, 당첨 번호와 중복 검증 + validateBonusNumber(winningLotto, bonusNumber); break; } catch (IllegalArgumentException e) { outputView.printError(e.getMessage()); From 4a7cddf1569ab658e7acea5f034265c6189f08a2 Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:56:49 +0900 Subject: [PATCH 21/23] =?UTF-8?q?feat:=20=EC=B5=9C=EB=8C=80=20=EC=88=98?= =?UTF-8?q?=EB=9F=89=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/LottoMachine.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/lotto/LottoMachine.java b/src/main/java/lotto/LottoMachine.java index 72a44709fc..d33388ea5e 100644 --- a/src/main/java/lotto/LottoMachine.java +++ b/src/main/java/lotto/LottoMachine.java @@ -7,6 +7,7 @@ public class LottoMachine { public static final int LOTTO_PRICE = 1000; + public static final int LOTTO_MAX_PRICE = 100000; public List purchaseLottos(int purchaseAmount) { validatePurchaseAmount(purchaseAmount); @@ -29,8 +30,9 @@ private Lotto createLotto() { } private void validatePurchaseAmount(int purchaseAmount) { - if (purchaseAmount <= 0 || purchaseAmount % LOTTO_PRICE != 0) { + if (purchaseAmount <= 0 || purchaseAmount % LOTTO_PRICE != 0) throw new IllegalArgumentException("[ERROR] 구입 금액은 1,000원 단위여야 합니다."); - } + if (purchaseAmount > LOTTO_MAX_PRICE) + throw new IllegalArgumentException("[ERROR] 1회 구매 금액은 10만 원을 초과할 수 없습니다."); } } \ No newline at end of file From da6c9433e61333e97ee633199ae6356abe29d47e Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:57:05 +0900 Subject: [PATCH 22/23] =?UTF-8?q?refactor:=20whitespaces=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/LottoResult.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/lotto/LottoResult.java b/src/main/java/lotto/LottoResult.java index 1b38617163..aa7f13b405 100644 --- a/src/main/java/lotto/LottoResult.java +++ b/src/main/java/lotto/LottoResult.java @@ -1,6 +1,6 @@ package lotto; -import java.util.EnumMap; // Enum에 최적화된 Map +import java.util.EnumMap; import java.util.Map; public class LottoResult { @@ -37,7 +37,6 @@ public double calculateRateOfReturn(int purchaseAmount) { } double rate = (totalPrize / purchaseAmount) * 100.0; - return Math.round(rate * 10.0) / 10.0; } } \ No newline at end of file From dc564014e79a5653161707a65ea46b8cf0502dde Mon Sep 17 00:00:00 2001 From: eunho Date: Mon, 3 Nov 2025 23:57:41 +0900 Subject: [PATCH 23/23] =?UTF-8?q?docs:=20=EC=98=88=EC=99=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 963d0e5bdb..6d68391c3d 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ ## ⚙️ 구현 목록 ### 입력 -- [ ] 구입 금액 입력 (콘솔 입력, 1000원 단위 검증) -- [ ] 당첨 번호 6개 입력 (쉼표 구분) -- [ ] 보너스 번호 1개 입력 +- [x] 구입 금액 입력 (콘솔 입력, 1000원 단위 검증) +- [x] 당첨 번호 6개 입력 (쉼표 구분) +- [x] 보너스 번호 1개 입력 ### 로또 로직 - [ ] 구입 금액만큼 로또 생성