From 2df0cb9ad1be72abff8a1bfc360a3b19b5a3304f Mon Sep 17 00:00:00 2001 From: SangBeom-Hahn Date: Fri, 14 Jul 2023 12:58:00 +0900 Subject: [PATCH 01/12] =?UTF-8?q?docs(README):=20=EC=9A=94=EA=B5=AC?= =?UTF-8?q?=EC=82=AC=ED=95=AD=EA=B3=BC=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/docs/README.md b/docs/README.md index e69de29..2318055 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,50 @@ +# 요구사항 명세서 +## [카테고리] +1. 사용자 +2. 로또 발행기 +3. 결과 비교기 +4. 시스템 + +## [카테고리 별 요구사항 내용] +### 1. 사용자 + - 로또 구입 금액을 입력한다. + - 당첨 번호 추첨 시 중복되지 않는 6개의 숫자와 보너스 번호를 1개를 입력한다. + + +### 2. 로또 발행기 + - 1개의 로또를 발행할 때 중복되지 않는 6개의 숫자를 뽑는다. + - 로또 구입 금액에 해당하는 만큼 로또를 발행한다. + + +### 3. 결과 비교기 + - 당첨 번호를 입력 받아 발행한 로또와 비교한다. + + +### 4. 시스템 + - 당첨 내역과 수익률을 출력하고 로또 게임을 종료한다. + - 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시키고 "[ERROR]"로 시작하는 에러 메세지를 출력 후 종료한다. + +# 기능 목록 +### 1. 입력 기능 + - 사용자가 입력하는 금액을 입력 받는 기능 + - 사용자가 입력하는 당첨 번호, 보너스 번호를 입력 받는 기능 + + +### 2. 출력 기능 + - 발행한 로또 내역 출력 기능 + - 당첨 통계와 수익률 출력 기능 + + +### 3. 게임 로직 기능 + - 로또 발행 기능 + - 당첨 통계 기능 + - 수익률 계산 기능 + + +### 4. 검증 기능 + - 입력 검증 + - 사용자가 입력한 금액이 1000원 단위로 1000의 배수인지 검증 + - 사용자가 입력한 당첨 번호가 정수 1 ~ 45인지 검증 + - 사용자가 입력한 당첨 번호가 숫자 6개인지 검증 + - 사용자가 입력한 보너스 번호가 정수 1 ~ 45인지 검증 + - 사용자가 입력한 보너스 번호가 숫자 1개인지 검증 \ No newline at end of file From 389c255ee288986fd54b75f30327758294ee5cae Mon Sep 17 00:00:00 2001 From: SangBeom-Hahn Date: Fri, 14 Jul 2023 14:13:25 +0900 Subject: [PATCH 02/12] =?UTF-8?q?feat:=20=EC=B4=88=EA=B8=B0=20=EC=97=94?= =?UTF-8?q?=ED=84=B0=ED=8B=B0=20=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 초기 엔터티를 구축, 테스트한다. --- src/main/java/lotto/domain/user/Lotto.java | 40 ++++++++++++++++++++++ src/main/java/lotto/domain/user/User.java | 15 ++++++++ src/test/java/lotto/LottoTest.java | 11 ++++-- 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 src/main/java/lotto/domain/user/Lotto.java create mode 100644 src/main/java/lotto/domain/user/User.java diff --git a/src/main/java/lotto/domain/user/Lotto.java b/src/main/java/lotto/domain/user/Lotto.java new file mode 100644 index 0000000..d3b55db --- /dev/null +++ b/src/main/java/lotto/domain/user/Lotto.java @@ -0,0 +1,40 @@ +package lotto.domain.user; + +import java.util.List; + +public class Lotto { + private final List numbers; + + public Lotto(List numbers) { + validateLottoSize(numbers); + validateLottoHasDuplicate(numbers); + validateLottoNumbersRange(numbers); + this.numbers = numbers; + } + + private void validateLottoSize(List numbers) { + if (numbers.size() != 6) { + throw new IllegalArgumentException("로또 번호가 6자리가 아닙니다."); + } + } + + private void validateLottoHasDuplicate(List numbers) { + if (hasDuplicate(numbers)) { + throw new IllegalArgumentException("로또 번호에 중복된 번호가 있습니다."); + } + } + + private boolean hasDuplicate(List numbers) { + return numbers.stream().distinct().count() != 6; + } + + private void validateLottoNumbersRange(List numbers) { + if (isNotInRange(numbers)) { + throw new IllegalArgumentException("로또 번호 중에 1 ~ 45가 아닌 것이 있습니다."); + } + } + + private boolean isNotInRange(List numbers) { + return numbers.stream().anyMatch(number -> number < 1 || number > 45); + } +} diff --git a/src/main/java/lotto/domain/user/User.java b/src/main/java/lotto/domain/user/User.java new file mode 100644 index 0000000..5613f55 --- /dev/null +++ b/src/main/java/lotto/domain/user/User.java @@ -0,0 +1,15 @@ +package lotto.domain.user; + +import java.util.List; + +public class User { + private List lottos; + + public User(List lottos) { + this.lottos = lottos; + } + + public List getLottos() { + return lottos; + } +} diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 0f3af0f..359aff0 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -1,5 +1,6 @@ package lotto; +import lotto.domain.user.Lotto; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -22,6 +23,12 @@ void createLottoByDuplicatedNumber() { assertThatThrownBy(() -> new Lotto(List.of(1, 2, 3, 4, 5, 5))) .isInstanceOf(IllegalArgumentException.class); } - - // 아래에 추가 테스트 작성 가능 + + @Test + @DisplayName("로또 번호에 1 ~ 45 외 범위의 숫자가 있으면 예외가 발생한다.") + void throwExceptionByLottoNumberIsNotInRange() { + // then + assertThatThrownBy(() -> new Lotto(List.of(66, 1, 2))) + .isInstanceOf(IllegalArgumentException.class); + } } From e94adefe9e8522475adb1ba22bc281b268d5b2d1 Mon Sep 17 00:00:00 2001 From: SangBeom-Hahn Date: Fri, 14 Jul 2023 15:57:33 +0900 Subject: [PATCH 03/12] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EB=B0=9C?= =?UTF-8?q?=ED=96=89=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *feat: LottoGenerator 기능 및 테스트 구현 *feat: Controller 관련 기능 구현 --- .../java/lotto/controller/Controller.java | 23 +++++++++ .../lotto/domain/user/LottoGenerator.java | 48 +++++++++++++++++++ src/test/java/lotto/LottoTest.java | 2 +- .../lotto/domain/user/LottoGeneratorTest.java | 48 +++++++++++++++++++ 4 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 src/main/java/lotto/controller/Controller.java create mode 100644 src/main/java/lotto/domain/user/LottoGenerator.java create mode 100644 src/test/java/lotto/domain/user/LottoGeneratorTest.java diff --git a/src/main/java/lotto/controller/Controller.java b/src/main/java/lotto/controller/Controller.java new file mode 100644 index 0000000..e0fdcb2 --- /dev/null +++ b/src/main/java/lotto/controller/Controller.java @@ -0,0 +1,23 @@ +package lotto.controller; + +import lotto.domain.user.LottoGenerator; +import lotto.domain.user.User; + +import static camp.nextstep.edu.missionutils.Console.readLine; + +public class Controller { + private User user; + + private void buyLotto() { + user = new User(LottoGenerator.generateLottos(inputMoney())); + } + + private int inputMoney() { + String inputMoney = readLine(); + return convertMoneyTypeStringToInt(inputMoney); + } + + private int convertMoneyTypeStringToInt(String inputMoney) { + return Integer.parseInt(inputMoney); + } +} diff --git a/src/main/java/lotto/domain/user/LottoGenerator.java b/src/main/java/lotto/domain/user/LottoGenerator.java new file mode 100644 index 0000000..4c92e57 --- /dev/null +++ b/src/main/java/lotto/domain/user/LottoGenerator.java @@ -0,0 +1,48 @@ +package lotto.domain.user; + +import camp.nextstep.edu.missionutils.Randoms; + +import java.util.ArrayList; +import java.util.List; + +public class LottoGenerator { + private LottoGenerator() { + } + + public static List generateLottos(int money) { + validateMoney(money); + List lottos = new ArrayList<>(); + final int quantity = money / 1000; + + for (int i = 0; i < quantity; i++) { + lottos.add(generateLotto()); + } + + return lottos; + } + + private static Lotto generateLotto() { + return new Lotto(getLottoNumbers()); + } + + private static List getLottoNumbers() { + return Randoms.pickUniqueNumbersInRange(1, 45, 6); + } + + private static void validateMoney(int money) { + validateMoneyIsPositive(money); + validateMoneyIsMultiplesOfPrice(money); + } + + private static void validateMoneyIsPositive(int money) { + if (money < 0) { + throw new IllegalArgumentException("구입금액은 음수를 입력할 수 없습니다."); + } + } + + private static void validateMoneyIsMultiplesOfPrice(int money) { + if (money / 1000 < 0 || money % 1000 > 0) { + throw new IllegalArgumentException("구입금액은 1000의 배수여야 합니다."); + } + } +} diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 359aff0..16653d8 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -26,7 +26,7 @@ void createLottoByDuplicatedNumber() { @Test @DisplayName("로또 번호에 1 ~ 45 외 범위의 숫자가 있으면 예외가 발생한다.") - void throwExceptionByLottoNumberIsNotInRange() { + void lottoNumberIsNotInRange() { // then assertThatThrownBy(() -> new Lotto(List.of(66, 1, 2))) .isInstanceOf(IllegalArgumentException.class); diff --git a/src/test/java/lotto/domain/user/LottoGeneratorTest.java b/src/test/java/lotto/domain/user/LottoGeneratorTest.java new file mode 100644 index 0000000..45456f6 --- /dev/null +++ b/src/test/java/lotto/domain/user/LottoGeneratorTest.java @@ -0,0 +1,48 @@ +package lotto.domain.user; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static lotto.domain.user.LottoGenerator.generateLottos; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class LottoGeneratorTest { + @Test + @DisplayName("입력한 돈에 따른 갯수의 로또를 발행한다.") + void generateLotto() { + // given + int money = 8000; + int quantity = money / 1000; + + // when + List lottos = generateLottos(money); + + // then + assertThat(lottos.size()).isEqualTo(quantity); + } + + @Test + @DisplayName("구입금액으로 음수를 입력하면 예외가 발생한다.") + void inputNegativeMoney() { + // given + int money = -1000; + + // then + assertThatThrownBy(() -> generateLottos(money)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("구입금액으로 음수를 입력하면 예외가 발생한다.") + void inputNotMultipleMoney() { + // given + int money = 1100; + + // then + assertThatThrownBy(() -> generateLottos(money)) + .isInstanceOf(IllegalArgumentException.class); + } +} From a14f5922020baf2f57739b1024815ab04174f424 Mon Sep 17 00:00:00 2001 From: SangBeom-Hahn Date: Fri, 14 Jul 2023 16:06:05 +0900 Subject: [PATCH 04/12] =?UTF-8?q?refactor(LottoGenerator):=20=EA=B5=AC?= =?UTF-8?q?=EB=A7=A4=EA=B8=88=EC=95=A1=20=EB=B0=B0=EC=88=98=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/domain/user/LottoGenerator.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/lotto/domain/user/LottoGenerator.java b/src/main/java/lotto/domain/user/LottoGenerator.java index 4c92e57..4046b41 100644 --- a/src/main/java/lotto/domain/user/LottoGenerator.java +++ b/src/main/java/lotto/domain/user/LottoGenerator.java @@ -41,8 +41,12 @@ private static void validateMoneyIsPositive(int money) { } private static void validateMoneyIsMultiplesOfPrice(int money) { - if (money / 1000 < 0 || money % 1000 > 0) { + if (isNotMultiplesOfPrice(money)) { throw new IllegalArgumentException("구입금액은 1000의 배수여야 합니다."); } } + + private static boolean isNotMultiplesOfPrice(int money) { + return (money / 1000) < 0 || (money % 1000) > 0; + } } From 4b3305b7ba8d74b46298da59ef510c4431a9831c Mon Sep 17 00:00:00 2001 From: SangBeom-Hahn Date: Sat, 15 Jul 2023 10:05:48 +0900 Subject: [PATCH 05/12] =?UTF-8?q?chore:=20Lotto=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/controller/Controller.java | 2 +- src/main/java/lotto/domain/{user => Lotto}/Lotto.java | 2 +- src/main/java/lotto/domain/{user => Lotto}/LottoGenerator.java | 2 +- src/main/java/lotto/domain/user/User.java | 2 ++ src/test/java/lotto/LottoTest.java | 2 +- src/test/java/lotto/domain/user/LottoGeneratorTest.java | 3 ++- 6 files changed, 8 insertions(+), 5 deletions(-) rename src/main/java/lotto/domain/{user => Lotto}/Lotto.java (97%) rename src/main/java/lotto/domain/{user => Lotto}/LottoGenerator.java (97%) diff --git a/src/main/java/lotto/controller/Controller.java b/src/main/java/lotto/controller/Controller.java index e0fdcb2..a4ce455 100644 --- a/src/main/java/lotto/controller/Controller.java +++ b/src/main/java/lotto/controller/Controller.java @@ -1,6 +1,6 @@ package lotto.controller; -import lotto.domain.user.LottoGenerator; +import lotto.domain.Lotto.LottoGenerator; import lotto.domain.user.User; import static camp.nextstep.edu.missionutils.Console.readLine; diff --git a/src/main/java/lotto/domain/user/Lotto.java b/src/main/java/lotto/domain/Lotto/Lotto.java similarity index 97% rename from src/main/java/lotto/domain/user/Lotto.java rename to src/main/java/lotto/domain/Lotto/Lotto.java index d3b55db..a3a4e4d 100644 --- a/src/main/java/lotto/domain/user/Lotto.java +++ b/src/main/java/lotto/domain/Lotto/Lotto.java @@ -1,4 +1,4 @@ -package lotto.domain.user; +package lotto.domain.Lotto; import java.util.List; diff --git a/src/main/java/lotto/domain/user/LottoGenerator.java b/src/main/java/lotto/domain/Lotto/LottoGenerator.java similarity index 97% rename from src/main/java/lotto/domain/user/LottoGenerator.java rename to src/main/java/lotto/domain/Lotto/LottoGenerator.java index 4046b41..51f86d4 100644 --- a/src/main/java/lotto/domain/user/LottoGenerator.java +++ b/src/main/java/lotto/domain/Lotto/LottoGenerator.java @@ -1,4 +1,4 @@ -package lotto.domain.user; +package lotto.domain.Lotto; import camp.nextstep.edu.missionutils.Randoms; diff --git a/src/main/java/lotto/domain/user/User.java b/src/main/java/lotto/domain/user/User.java index 5613f55..e999cea 100644 --- a/src/main/java/lotto/domain/user/User.java +++ b/src/main/java/lotto/domain/user/User.java @@ -1,5 +1,7 @@ package lotto.domain.user; +import lotto.domain.Lotto.Lotto; + import java.util.List; public class User { diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 16653d8..231ba81 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -1,6 +1,6 @@ package lotto; -import lotto.domain.user.Lotto; +import lotto.domain.Lotto.Lotto; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/lotto/domain/user/LottoGeneratorTest.java b/src/test/java/lotto/domain/user/LottoGeneratorTest.java index 45456f6..f7e208b 100644 --- a/src/test/java/lotto/domain/user/LottoGeneratorTest.java +++ b/src/test/java/lotto/domain/user/LottoGeneratorTest.java @@ -1,11 +1,12 @@ package lotto.domain.user; +import lotto.domain.Lotto.Lotto; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; -import static lotto.domain.user.LottoGenerator.generateLottos; +import static lotto.domain.Lotto.LottoGenerator.generateLottos; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; From ca99ae647f9924bba46a28d95979eaadbcfc5a55 Mon Sep 17 00:00:00 2001 From: SangBeom-Hahn Date: Sat, 15 Jul 2023 10:58:02 +0900 Subject: [PATCH 06/12] =?UTF-8?q?feat:=20=EA=B5=AC=EC=9E=85=EA=B8=88?= =?UTF-8?q?=EC=95=A1=20=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *feat: Application main 메서드 구현 *feat: Controller 관련 기능 구현 *refactor: MoneyGenerator를 LottoGenerator에서 분리 *feat: MoneyGenerator 기능 및 테스트 구현 *test: LottoGenerator 검증 테스트 삭제 --- src/main/java/lotto/Application.java | 3 + .../java/lotto/controller/Controller.java | 18 ++---- .../lotto/domain/Lotto/LottoGenerator.java | 22 ------- .../lotto/domain/Lotto/MoneyGenerator.java | 43 +++++++++++++ .../domain/Lotto/MoneyGeneratorTest.java | 64 +++++++++++++++++++ .../lotto/domain/user/LottoGeneratorTest.java | 22 ------- 6 files changed, 117 insertions(+), 55 deletions(-) create mode 100644 src/main/java/lotto/domain/Lotto/MoneyGenerator.java create mode 100644 src/test/java/lotto/domain/Lotto/MoneyGeneratorTest.java diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922..2d864fb 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,10 @@ package lotto; +import lotto.controller.Controller; + public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 + new Controller().run(); } } diff --git a/src/main/java/lotto/controller/Controller.java b/src/main/java/lotto/controller/Controller.java index a4ce455..a68f9dc 100644 --- a/src/main/java/lotto/controller/Controller.java +++ b/src/main/java/lotto/controller/Controller.java @@ -1,23 +1,19 @@ package lotto.controller; -import lotto.domain.Lotto.LottoGenerator; import lotto.domain.user.User; -import static camp.nextstep.edu.missionutils.Console.readLine; +import static lotto.domain.Lotto.LottoGenerator.generateLottos; +import static lotto.domain.Lotto.MoneyGenerator.generateMoney; public class Controller { private User user; - private void buyLotto() { - user = new User(LottoGenerator.generateLottos(inputMoney())); - } - - private int inputMoney() { - String inputMoney = readLine(); - return convertMoneyTypeStringToInt(inputMoney); + public void run() { + System.out.println("구입금액을 입력해 주세요."); + buyLotto(); } - private int convertMoneyTypeStringToInt(String inputMoney) { - return Integer.parseInt(inputMoney); + private void buyLotto() { + user = new User(generateLottos(generateMoney())); } } diff --git a/src/main/java/lotto/domain/Lotto/LottoGenerator.java b/src/main/java/lotto/domain/Lotto/LottoGenerator.java index 51f86d4..d33a4ae 100644 --- a/src/main/java/lotto/domain/Lotto/LottoGenerator.java +++ b/src/main/java/lotto/domain/Lotto/LottoGenerator.java @@ -10,7 +10,6 @@ private LottoGenerator() { } public static List generateLottos(int money) { - validateMoney(money); List lottos = new ArrayList<>(); final int quantity = money / 1000; @@ -28,25 +27,4 @@ private static Lotto generateLotto() { private static List getLottoNumbers() { return Randoms.pickUniqueNumbersInRange(1, 45, 6); } - - private static void validateMoney(int money) { - validateMoneyIsPositive(money); - validateMoneyIsMultiplesOfPrice(money); - } - - private static void validateMoneyIsPositive(int money) { - if (money < 0) { - throw new IllegalArgumentException("구입금액은 음수를 입력할 수 없습니다."); - } - } - - private static void validateMoneyIsMultiplesOfPrice(int money) { - if (isNotMultiplesOfPrice(money)) { - throw new IllegalArgumentException("구입금액은 1000의 배수여야 합니다."); - } - } - - private static boolean isNotMultiplesOfPrice(int money) { - return (money / 1000) < 0 || (money % 1000) > 0; - } } diff --git a/src/main/java/lotto/domain/Lotto/MoneyGenerator.java b/src/main/java/lotto/domain/Lotto/MoneyGenerator.java new file mode 100644 index 0000000..ecce5b6 --- /dev/null +++ b/src/main/java/lotto/domain/Lotto/MoneyGenerator.java @@ -0,0 +1,43 @@ +package lotto.domain.Lotto; + +import static camp.nextstep.edu.missionutils.Console.readLine; + +public class MoneyGenerator { + private MoneyGenerator() { + } + + public static int generateMoney() { + int money = inputMoney(); + validateMoney(money); + return money; + } + + private static int inputMoney() { + String inputMoney = readLine(); + return convertMoneyTypeStringToInt(inputMoney); + } + + private static int convertMoneyTypeStringToInt(String inputMoney) { + return Integer.parseInt(inputMoney); + } + private static void validateMoney(int money) { + validateMoneyIsPositive(money); + validateMoneyIsMultiplesOfPrice(money); + } + + private static void validateMoneyIsPositive(int money) { + if (money < 0) { + throw new IllegalArgumentException("구입금액은 음수를 입력할 수 없습니다."); + } + } + + private static void validateMoneyIsMultiplesOfPrice(int money) { + if (isNotMultiplesOfPrice(money)) { + throw new IllegalArgumentException("구입금액은 1000의 배수여야 합니다."); + } + } + + private static boolean isNotMultiplesOfPrice(int money) { + return (money / 1000) < 0 || (money % 1000) > 0; + } +} diff --git a/src/test/java/lotto/domain/Lotto/MoneyGeneratorTest.java b/src/test/java/lotto/domain/Lotto/MoneyGeneratorTest.java new file mode 100644 index 0000000..18400ea --- /dev/null +++ b/src/test/java/lotto/domain/Lotto/MoneyGeneratorTest.java @@ -0,0 +1,64 @@ +package lotto.domain.Lotto; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.stream.Stream; + +import static lotto.domain.Lotto.MoneyGenerator.generateMoney; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class MoneyGeneratorTest { + private InputStream in; + + @AfterEach + void afterEach() throws IOException { + in.close(); + } + + @Test + @DisplayName("올바른 구입 금액(1000원 단위로 1000의 배수 구입 금액)은 입력할 수 있다.") + void createMoneyValidFormat() { + // given + String money = "5000"; + in = new ByteArrayInputStream(money.getBytes()); + + // when + System.setIn(in); + + // then + assertThat(5000).isEqualTo(generateMoney()); + } + + @ParameterizedTest + @MethodSource("invalidMoney") + @DisplayName("올바른 구입 금액(1000원 단위로 1000의 배수 구입 금액)이 아니면 예외가 발생한다.") + void createMoneyInvalidFormat(String money) { + // given + in = new ByteArrayInputStream(money.getBytes()); + + // when + System.setIn(in); + + // then + assertThatThrownBy(() -> generateMoney()) + .isInstanceOf(IllegalArgumentException.class); + } + + private static Stream invalidMoney() { + return Stream.of( + Arguments.of("5001"), + Arguments.of("500"), + Arguments.of("-1000") + ); + } +} \ No newline at end of file diff --git a/src/test/java/lotto/domain/user/LottoGeneratorTest.java b/src/test/java/lotto/domain/user/LottoGeneratorTest.java index f7e208b..9bbe9e3 100644 --- a/src/test/java/lotto/domain/user/LottoGeneratorTest.java +++ b/src/test/java/lotto/domain/user/LottoGeneratorTest.java @@ -24,26 +24,4 @@ void generateLotto() { // then assertThat(lottos.size()).isEqualTo(quantity); } - - @Test - @DisplayName("구입금액으로 음수를 입력하면 예외가 발생한다.") - void inputNegativeMoney() { - // given - int money = -1000; - - // then - assertThatThrownBy(() -> generateLottos(money)) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - @DisplayName("구입금액으로 음수를 입력하면 예외가 발생한다.") - void inputNotMultipleMoney() { - // given - int money = 1100; - - // then - assertThatThrownBy(() -> generateLottos(money)) - .isInstanceOf(IllegalArgumentException.class); - } } From d8c2c3270b11cb0ba5e03b4c61a3ba938b5ae641 Mon Sep 17 00:00:00 2001 From: SangBeom-Hahn Date: Sun, 16 Jul 2023 13:21:40 +0900 Subject: [PATCH 07/12] =?UTF-8?q?feat:=20=EB=B0=9C=ED=96=89=ED=95=9C=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=20=EB=82=B4=EC=97=AD=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *feat: Lotto 기능 구현 *feat: Controller 관련 기능 구현 --- src/main/java/lotto/controller/Controller.java | 8 ++++++++ src/main/java/lotto/domain/Lotto/Lotto.java | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/lotto/controller/Controller.java b/src/main/java/lotto/controller/Controller.java index a68f9dc..afc323a 100644 --- a/src/main/java/lotto/controller/Controller.java +++ b/src/main/java/lotto/controller/Controller.java @@ -1,7 +1,10 @@ package lotto.controller; +import lotto.domain.Lotto.Lotto; import lotto.domain.user.User; +import java.util.List; + import static lotto.domain.Lotto.LottoGenerator.generateLottos; import static lotto.domain.Lotto.MoneyGenerator.generateMoney; @@ -11,6 +14,11 @@ public class Controller { public void run() { System.out.println("구입금액을 입력해 주세요."); buyLotto(); + List lottos = user.getLottos(); + System.out.println(lottos.size() + "개를 구매했습니다."); + for (Lotto lotto : lottos) { + System.out.println(lotto); + } } private void buyLotto() { diff --git a/src/main/java/lotto/domain/Lotto/Lotto.java b/src/main/java/lotto/domain/Lotto/Lotto.java index a3a4e4d..c6b22dd 100644 --- a/src/main/java/lotto/domain/Lotto/Lotto.java +++ b/src/main/java/lotto/domain/Lotto/Lotto.java @@ -37,4 +37,9 @@ private void validateLottoNumbersRange(List numbers) { private boolean isNotInRange(List numbers) { return numbers.stream().anyMatch(number -> number < 1 || number > 45); } + + @Override + public String toString() { + return numbers.toString(); + } } From 5e30c1ed481807d63a81b605e059fdc5b01651aa Mon Sep 17 00:00:00 2001 From: SangBeom-Hahn Date: Sun, 16 Jul 2023 14:14:42 +0900 Subject: [PATCH 08/12] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8,=20=EB=B3=B4=EB=84=88=EC=8A=A4=20=EB=B2=88=ED=98=B8?= =?UTF-8?q?=20=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *feat: AnswerLotto 기능 구현 및 테스트 *feat: Controller 관련 기능 구현 --- .../java/lotto/controller/Controller.java | 14 +++++ .../java/lotto/domain/Lotto/AnswerLotto.java | 44 +++++++++++++++ .../lotto/domain/Lotto/AnswerLottoTest.java | 55 +++++++++++++++++++ .../domain/Lotto/MoneyGeneratorTest.java | 1 - .../lotto/domain/user/LottoGeneratorTest.java | 1 - 5 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 src/main/java/lotto/domain/Lotto/AnswerLotto.java create mode 100644 src/test/java/lotto/domain/Lotto/AnswerLottoTest.java diff --git a/src/main/java/lotto/controller/Controller.java b/src/main/java/lotto/controller/Controller.java index afc323a..68d4b8a 100644 --- a/src/main/java/lotto/controller/Controller.java +++ b/src/main/java/lotto/controller/Controller.java @@ -4,7 +4,10 @@ import lotto.domain.user.User; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import static camp.nextstep.edu.missionutils.Console.readLine; import static lotto.domain.Lotto.LottoGenerator.generateLottos; import static lotto.domain.Lotto.MoneyGenerator.generateMoney; @@ -13,12 +16,23 @@ public class Controller { public void run() { System.out.println("구입금액을 입력해 주세요."); + buyLotto(); + List lottos = user.getLottos(); System.out.println(lottos.size() + "개를 구매했습니다."); for (Lotto lotto : lottos) { System.out.println(lotto); } + + System.out.println("당첨 번호를 입력해 주세요."); + String answerLottoNumbers = readLine(); + System.out.println("보너스 번호를 입력해 주세요."); + String bonusLottoNumbers = readLine(); + List answerLotto = Stream.of(answerLottoNumbers.split(",")) + .map(Integer::valueOf).collect(Collectors.toList()); + answerLotto.add(Integer.valueOf(bonusLottoNumbers)); + System.out.println(answerLotto); } private void buyLotto() { diff --git a/src/main/java/lotto/domain/Lotto/AnswerLotto.java b/src/main/java/lotto/domain/Lotto/AnswerLotto.java new file mode 100644 index 0000000..b62f660 --- /dev/null +++ b/src/main/java/lotto/domain/Lotto/AnswerLotto.java @@ -0,0 +1,44 @@ +package lotto.domain.Lotto; + +import java.util.List; + +public class AnswerLotto { + private List answerNumbers; + + public AnswerLotto(List answerNumbers) { + validateLottoSize(answerNumbers); + validateLottoHasDuplicate(answerNumbers); + validateLottoNumbersRange(answerNumbers); + this.answerNumbers = answerNumbers; + } + + private void validateLottoSize(List numbers) { + if (numbers.size() != 7) { + throw new IllegalArgumentException("정답 로또 번호가 7자리가 아닙니다."); + } + } + + private void validateLottoHasDuplicate(List numbers) { + if (hasDuplicate(numbers)) { + throw new IllegalArgumentException("로또 번호에 중복된 번호가 있습니다."); + } + } + + private boolean hasDuplicate(List numbers) { + return numbers.stream().distinct().count() != 7; + } + + private void validateLottoNumbersRange(List numbers) { + if (isNotInRange(numbers)) { + throw new IllegalArgumentException("로또 번호 중에 1 ~ 45가 아닌 것이 있습니다."); + } + } + + private boolean isNotInRange(List numbers) { + return numbers.stream().anyMatch(number -> number < 1 || number > 45); + } + + public List getAnswerNumbers() { + return answerNumbers; + } +} diff --git a/src/test/java/lotto/domain/Lotto/AnswerLottoTest.java b/src/test/java/lotto/domain/Lotto/AnswerLottoTest.java new file mode 100644 index 0000000..a1ae31d --- /dev/null +++ b/src/test/java/lotto/domain/Lotto/AnswerLottoTest.java @@ -0,0 +1,55 @@ +package lotto.domain.Lotto; + +import org.junit.jupiter.api.DisplayName; +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 AnswerLottoTest { + @Test + @DisplayName("당첨 번호 6자리와 보너스 번호 1자리를 입력하면 당첨 로또를 선언할 수 있다.") + void canCreateAnswerLotto() { + // given + List answerNumberList = List.of(1, 2, 3, 4, 5, 6, 7); + AnswerLotto answerLotto = new AnswerLotto(answerNumberList); + + // then + assertThat(answerLotto.getAnswerNumbers()).isEqualTo(answerNumberList); + } + + @Test + @DisplayName("당첨 로또 번호가 7개가 아니면 예외가 발생한다.") + void throwException_wrongSize() { + // given + List answerNumberList = List.of(1, 2, 3, 4, 5, 6); + + // then + assertThatThrownBy(() -> new AnswerLotto(answerNumberList)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("당첨 로또 번호에 중복이 있으면 예외가 발생한다.") + void throwException_hasDuplicate() { + // given + List answerNumberList = List.of(1, 2, 5, 4, 5, 6); + + // then + assertThatThrownBy(() -> new AnswerLotto(answerNumberList)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("당첨 로또 번호가 범위를 넘어가면 예외가 발생한다.") + void throwException_invalidRange() { + // given + List answerNumberList = List.of(1, 2, 5, 4, 5, 6); + + // then + assertThatThrownBy(() -> new AnswerLotto(answerNumberList)) + .isInstanceOf(IllegalArgumentException.class); + } +} \ No newline at end of file diff --git a/src/test/java/lotto/domain/Lotto/MoneyGeneratorTest.java b/src/test/java/lotto/domain/Lotto/MoneyGeneratorTest.java index 18400ea..7ec3e76 100644 --- a/src/test/java/lotto/domain/Lotto/MoneyGeneratorTest.java +++ b/src/test/java/lotto/domain/Lotto/MoneyGeneratorTest.java @@ -1,7 +1,6 @@ package lotto.domain.Lotto; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/lotto/domain/user/LottoGeneratorTest.java b/src/test/java/lotto/domain/user/LottoGeneratorTest.java index 9bbe9e3..8476ae4 100644 --- a/src/test/java/lotto/domain/user/LottoGeneratorTest.java +++ b/src/test/java/lotto/domain/user/LottoGeneratorTest.java @@ -8,7 +8,6 @@ import static lotto.domain.Lotto.LottoGenerator.generateLottos; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; class LottoGeneratorTest { @Test From 4e63004ebbac824f253331655ff61ed10934d40e Mon Sep 17 00:00:00 2001 From: SangBeom-Hahn Date: Sun, 16 Jul 2023 14:35:28 +0900 Subject: [PATCH 09/12] =?UTF-8?q?refactor:=20=EB=8B=B9=EC=B2=A8=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=EC=99=80=20=EB=B3=B4=EB=84=88=EC=8A=A4=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=EB=A5=BC=20=EB=94=B0=EB=A1=9C=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *refactor: AnswerLotto bonusNumber 필드 추가 *refactor: Controller AnswerLotto 객체 생성 --- src/main/java/lotto/controller/Controller.java | 6 +++--- src/main/java/lotto/domain/Lotto/AnswerLotto.java | 10 ++++++---- .../java/lotto/domain/Lotto/AnswerLottoTest.java | 15 ++++++++------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/main/java/lotto/controller/Controller.java b/src/main/java/lotto/controller/Controller.java index 68d4b8a..9a1f46d 100644 --- a/src/main/java/lotto/controller/Controller.java +++ b/src/main/java/lotto/controller/Controller.java @@ -1,5 +1,6 @@ package lotto.controller; +import lotto.domain.Lotto.AnswerLotto; import lotto.domain.Lotto.Lotto; import lotto.domain.user.User; @@ -28,11 +29,10 @@ public void run() { System.out.println("당첨 번호를 입력해 주세요."); String answerLottoNumbers = readLine(); System.out.println("보너스 번호를 입력해 주세요."); - String bonusLottoNumbers = readLine(); + Integer bonusLottoNumber = Integer.valueOf(readLine()); List answerLotto = Stream.of(answerLottoNumbers.split(",")) .map(Integer::valueOf).collect(Collectors.toList()); - answerLotto.add(Integer.valueOf(bonusLottoNumbers)); - System.out.println(answerLotto); + new AnswerLotto(answerLotto, bonusLottoNumber); } private void buyLotto() { diff --git a/src/main/java/lotto/domain/Lotto/AnswerLotto.java b/src/main/java/lotto/domain/Lotto/AnswerLotto.java index b62f660..f322b1e 100644 --- a/src/main/java/lotto/domain/Lotto/AnswerLotto.java +++ b/src/main/java/lotto/domain/Lotto/AnswerLotto.java @@ -4,17 +4,19 @@ public class AnswerLotto { private List answerNumbers; + private Integer bonusNumber; - public AnswerLotto(List answerNumbers) { + public AnswerLotto(List answerNumbers, Integer bonusNumber) { validateLottoSize(answerNumbers); validateLottoHasDuplicate(answerNumbers); validateLottoNumbersRange(answerNumbers); this.answerNumbers = answerNumbers; + this.bonusNumber = bonusNumber; } private void validateLottoSize(List numbers) { - if (numbers.size() != 7) { - throw new IllegalArgumentException("정답 로또 번호가 7자리가 아닙니다."); + if (numbers.size() != 6) { + throw new IllegalArgumentException("정답 로또 번호가 6자리가 아닙니다."); } } @@ -25,7 +27,7 @@ private void validateLottoHasDuplicate(List numbers) { } private boolean hasDuplicate(List numbers) { - return numbers.stream().distinct().count() != 7; + return numbers.stream().distinct().count() != 6; } private void validateLottoNumbersRange(List numbers) { diff --git a/src/test/java/lotto/domain/Lotto/AnswerLottoTest.java b/src/test/java/lotto/domain/Lotto/AnswerLottoTest.java index a1ae31d..82dbaac 100644 --- a/src/test/java/lotto/domain/Lotto/AnswerLottoTest.java +++ b/src/test/java/lotto/domain/Lotto/AnswerLottoTest.java @@ -13,21 +13,22 @@ class AnswerLottoTest { @DisplayName("당첨 번호 6자리와 보너스 번호 1자리를 입력하면 당첨 로또를 선언할 수 있다.") void canCreateAnswerLotto() { // given - List answerNumberList = List.of(1, 2, 3, 4, 5, 6, 7); - AnswerLotto answerLotto = new AnswerLotto(answerNumberList); + List answerNumberList = List.of(1, 2, 3, 4, 5, 6); + Integer bonusNumber = 1; + AnswerLotto answerLotto = new AnswerLotto(answerNumberList, bonusNumber); // then assertThat(answerLotto.getAnswerNumbers()).isEqualTo(answerNumberList); } @Test - @DisplayName("당첨 로또 번호가 7개가 아니면 예외가 발생한다.") + @DisplayName("당첨 로또 번호가 6개가 아니면 예외가 발생한다.") void throwException_wrongSize() { // given - List answerNumberList = List.of(1, 2, 3, 4, 5, 6); + List answerNumberList = List.of(1, 2, 3, 4, 5); // then - assertThatThrownBy(() -> new AnswerLotto(answerNumberList)) + assertThatThrownBy(() -> new AnswerLotto(answerNumberList, 0)) .isInstanceOf(IllegalArgumentException.class); } @@ -38,7 +39,7 @@ void throwException_hasDuplicate() { List answerNumberList = List.of(1, 2, 5, 4, 5, 6); // then - assertThatThrownBy(() -> new AnswerLotto(answerNumberList)) + assertThatThrownBy(() -> new AnswerLotto(answerNumberList, 0)) .isInstanceOf(IllegalArgumentException.class); } @@ -49,7 +50,7 @@ void throwException_invalidRange() { List answerNumberList = List.of(1, 2, 5, 4, 5, 6); // then - assertThatThrownBy(() -> new AnswerLotto(answerNumberList)) + assertThatThrownBy(() -> new AnswerLotto(answerNumberList, 0)) .isInstanceOf(IllegalArgumentException.class); } } \ No newline at end of file From 6fe18337b5d48b90d046e29bf38e28f185ecf1e5 Mon Sep 17 00:00:00 2001 From: SangBeom-Hahn Date: Sun, 16 Jul 2023 18:02:58 +0900 Subject: [PATCH 10/12] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *feat: ResultService 기능 및 테스트 구현 *refactor: AnswerLotto bonusNumber 필드 타입 Integer에서 int로 변경 *refactor: AnswerLotto bonusNumber getter 추가 *refactor: Lotto numbers getter 추가 --- .../java/lotto/controller/Controller.java | 4 +- .../java/lotto/domain/Lotto/AnswerLotto.java | 6 +- src/main/java/lotto/domain/Lotto/Lotto.java | 4 + .../java/lotto/service/ResultService.java | 54 ++++++ .../java/lotto/service/ResultServiceTest.java | 163 ++++++++++++++++++ 5 files changed, 228 insertions(+), 3 deletions(-) create mode 100644 src/main/java/lotto/service/ResultService.java create mode 100644 src/test/java/lotto/service/ResultServiceTest.java diff --git a/src/main/java/lotto/controller/Controller.java b/src/main/java/lotto/controller/Controller.java index 9a1f46d..1cb9318 100644 --- a/src/main/java/lotto/controller/Controller.java +++ b/src/main/java/lotto/controller/Controller.java @@ -19,7 +19,7 @@ public void run() { System.out.println("구입금액을 입력해 주세요."); buyLotto(); - + List lottos = user.getLottos(); System.out.println(lottos.size() + "개를 구매했습니다."); for (Lotto lotto : lottos) { @@ -29,7 +29,7 @@ public void run() { System.out.println("당첨 번호를 입력해 주세요."); String answerLottoNumbers = readLine(); System.out.println("보너스 번호를 입력해 주세요."); - Integer bonusLottoNumber = Integer.valueOf(readLine()); + int bonusLottoNumber = Integer.parseInt(readLine()); List answerLotto = Stream.of(answerLottoNumbers.split(",")) .map(Integer::valueOf).collect(Collectors.toList()); new AnswerLotto(answerLotto, bonusLottoNumber); diff --git a/src/main/java/lotto/domain/Lotto/AnswerLotto.java b/src/main/java/lotto/domain/Lotto/AnswerLotto.java index f322b1e..cc3abc6 100644 --- a/src/main/java/lotto/domain/Lotto/AnswerLotto.java +++ b/src/main/java/lotto/domain/Lotto/AnswerLotto.java @@ -4,7 +4,7 @@ public class AnswerLotto { private List answerNumbers; - private Integer bonusNumber; + private int bonusNumber; public AnswerLotto(List answerNumbers, Integer bonusNumber) { validateLottoSize(answerNumbers); @@ -43,4 +43,8 @@ private boolean isNotInRange(List numbers) { public List getAnswerNumbers() { return answerNumbers; } + + public int getBonusNumber() { + return bonusNumber; + } } diff --git a/src/main/java/lotto/domain/Lotto/Lotto.java b/src/main/java/lotto/domain/Lotto/Lotto.java index c6b22dd..3cf1cc9 100644 --- a/src/main/java/lotto/domain/Lotto/Lotto.java +++ b/src/main/java/lotto/domain/Lotto/Lotto.java @@ -38,6 +38,10 @@ private boolean isNotInRange(List numbers) { return numbers.stream().anyMatch(number -> number < 1 || number > 45); } + public List getNumbers() { + return numbers; + } + @Override public String toString() { return numbers.toString(); diff --git a/src/main/java/lotto/service/ResultService.java b/src/main/java/lotto/service/ResultService.java new file mode 100644 index 0000000..a9a94af --- /dev/null +++ b/src/main/java/lotto/service/ResultService.java @@ -0,0 +1,54 @@ +package lotto.service; + +import lotto.domain.Lotto.Lotto; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ResultService { + private Map collectMap = new HashMap<>(){{ + put(3, "THREE"); + put(4, "FOUR"); + put(5, "FIVE"); + put(6, "SIX"); + }}; + private Map statisticCollectCntMap = new HashMap<>(){{ + put("THREE", 0); + put("FOUR", 0); + put("FIVE", 0); + put("FIVEPLUSBONUS", 0); + put("SIX", 0); + }}; + + public Map getStatistics(List userLottos, List answerNumbers, int bonusNumber) { + int bonusCnt; + int collectCnt; + + for (Lotto userLotto : userLottos) { + List eachLottoNumbers = userLotto.getNumbers(); + bonusCnt = isContainsBonusNumber(eachLottoNumbers, bonusNumber); + collectCnt = getCollectCnt(eachLottoNumbers, answerNumbers); + + if (bonusCnt == 1 && collectCnt == 5) { // 보너스가 있을 때 맞는 게 5개면 + statisticCollectCntMap.compute("FIVEPLUSBONUS", (k, v) -> Integer.valueOf(v + 1)); + } else { // 그 외 + statisticCollectCntMap.compute(collectMap.get(collectCnt), (k, v) -> Integer.valueOf(v + 1)); + } + } + + return statisticCollectCntMap; + } + + private int isContainsBonusNumber(List eachLottoNumbers, Integer bonusNumber) { + if (eachLottoNumbers.contains(bonusNumber)) { + return 1; + } + return 0; + } + + private int getCollectCnt(List eachLottoNumbers, List answerNumbers) { + eachLottoNumbers.retainAll(answerNumbers); + return eachLottoNumbers.size(); + } +} diff --git a/src/test/java/lotto/service/ResultServiceTest.java b/src/test/java/lotto/service/ResultServiceTest.java new file mode 100644 index 0000000..905a8b3 --- /dev/null +++ b/src/test/java/lotto/service/ResultServiceTest.java @@ -0,0 +1,163 @@ +package lotto.service; + +import lotto.domain.Lotto.Lotto; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class ResultServiceTest { + private ResultService resultService; + + @BeforeEach + void beforeEach() { + resultService = new ResultService(); + } + + @Test + @DisplayName("3개 일치 1개 당첨 통계를 구한다.") + void getStatisticsOneThreeCollect() { + // given + List userLottos = List.of( + new Lotto(new ArrayList<>(List.of(1, 2, 3, 11, 12, 13))) + ); + List answerNumbers = List.of(1, 2, 3, 4, 5, 6); + int bonusNumber = 7; + + // when + Map statistics = resultService.getStatistics(userLottos, answerNumbers, bonusNumber); + + // then + assertAll( + () -> assertThat(statistics.get("THREE")).isEqualTo(1), + () -> assertThat(statistics.get("FOUR")).isEqualTo(0), + () -> assertThat(statistics.get("FIVE")).isEqualTo(0), + () -> assertThat(statistics.get("FIVEPLUSBONUS")).isEqualTo(0), + () -> assertThat(statistics.get("SIX")).isEqualTo(0) + ); + } + + @Test + @DisplayName("4개 일치 1개 당첨 통계를 구한다.") + void getStatisticsOneFourCollect() { + // given + List userLottos = List.of( + new Lotto(new ArrayList<>(List.of(1, 2, 3, 4, 11, 12))) + ); + List answerNumbers = List.of(1, 2, 3, 4, 5, 6); + int bonusNumber = 7; + + // when + Map statistics = resultService.getStatistics(userLottos, answerNumbers, bonusNumber); + + // then + assertAll( + () -> assertThat(statistics.get("THREE")).isEqualTo(0), + () -> assertThat(statistics.get("FOUR")).isEqualTo(1), + () -> assertThat(statistics.get("FIVE")).isEqualTo(0), + () -> assertThat(statistics.get("FIVEPLUSBONUS")).isEqualTo(0), + () -> assertThat(statistics.get("SIX")).isEqualTo(0) + ); + } + + @Test + @DisplayName("5개 일치 1개 당첨 통계를 구한다.") + void getStatisticsOneFiveCollect() { + // given + List userLottos = List.of( + new Lotto(new ArrayList<>(List.of(1, 2, 3, 4, 5, 11))) + ); + List answerNumbers = List.of(1, 2, 3, 4, 5, 6); + int bonusNumber = 7; + + // when + Map statistics = resultService.getStatistics(userLottos, answerNumbers, bonusNumber); + + // then + assertAll( + () -> assertThat(statistics.get("THREE")).isEqualTo(0), + () -> assertThat(statistics.get("FOUR")).isEqualTo(0), + () -> assertThat(statistics.get("FIVE")).isEqualTo(1), + () -> assertThat(statistics.get("FIVEPLUSBONUS")).isEqualTo(0), + () -> assertThat(statistics.get("SIX")).isEqualTo(0) + ); + } + + @Test + @DisplayName("5개 일치, 보너스 볼 일치 1개 당첨 통계를 구한다.") + void getStatisticsBonusCollect() { + // given + List userLottos = List.of( + new Lotto(new ArrayList<>(List.of(1, 2, 3, 4, 5, 7))) + ); + List answerNumbers = List.of(1, 2, 3, 4, 5, 6); + int bonusNumber = 7; + + // when + Map statistics = resultService.getStatistics(userLottos, answerNumbers, bonusNumber); + + // then + assertAll( + () -> assertThat(statistics.get("THREE")).isEqualTo(0), + () -> assertThat(statistics.get("FOUR")).isEqualTo(0), + () -> assertThat(statistics.get("FIVE")).isEqualTo(0), + () -> assertThat(statistics.get("FIVEPLUSBONUS")).isEqualTo(1), + () -> assertThat(statistics.get("SIX")).isEqualTo(0) + ); + } + + @Test + @DisplayName("6개 일치 1개 당첨 통계를 구한다.") + void getStatisticsOneSixCollect() { + // given + List userLottos = List.of( + new Lotto(new ArrayList<>(List.of(1, 2, 3, 4, 5, 6))) + ); + List answerNumbers = List.of(1, 2, 3, 4, 5, 6); + int bonusNumber = 7; + + // when + Map statistics = resultService.getStatistics(userLottos, answerNumbers, bonusNumber); + + // then + assertAll( + () -> assertThat(statistics.get("THREE")).isEqualTo(0), + () -> assertThat(statistics.get("FOUR")).isEqualTo(0), + () -> assertThat(statistics.get("FIVE")).isEqualTo(0), + () -> assertThat(statistics.get("FIVEPLUSBONUS")).isEqualTo(0), + () -> assertThat(statistics.get("SIX")).isEqualTo(1) + ); + } + + @Test + @DisplayName("6개 일치 2개 당첨 통계를 구한다.") + void getStatisticsTwoSixCollect() { + // given + List userLottos = List.of( + new Lotto(new ArrayList<>(List.of(1, 2, 3, 4, 5, 6))), + new Lotto(new ArrayList<>(List.of(1, 2, 3, 4, 5, 6))) + ); + List answerNumbers = List.of(1, 2, 3, 4, 5, 6); + int bonusNumber = 7; + + // when + Map statistics = resultService.getStatistics(userLottos, answerNumbers, bonusNumber); + + // then + assertAll( + () -> assertThat(statistics.get("THREE")).isEqualTo(0), + () -> assertThat(statistics.get("FOUR")).isEqualTo(0), + () -> assertThat(statistics.get("FIVE")).isEqualTo(0), + () -> assertThat(statistics.get("FIVEPLUSBONUS")).isEqualTo(0), + () -> assertThat(statistics.get("SIX")).isEqualTo(2) + ); + } +} From c06ea29c28bcfd9f3abfac69bff284c12b7a357e Mon Sep 17 00:00:00 2001 From: SangBeom-Hahn Date: Sun, 16 Jul 2023 18:28:26 +0900 Subject: [PATCH 11/12] =?UTF-8?q?feat:=20=EC=88=98=EC=9D=B5=EB=A5=A0=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *feat: ResultService 기능 및 테스트 구현 --- .../java/lotto/service/ResultService.java | 10 ++ .../java/lotto/service/ResultServiceTest.java | 126 +++++++++++++++++- 2 files changed, 132 insertions(+), 4 deletions(-) diff --git a/src/main/java/lotto/service/ResultService.java b/src/main/java/lotto/service/ResultService.java index a9a94af..e1abe7e 100644 --- a/src/main/java/lotto/service/ResultService.java +++ b/src/main/java/lotto/service/ResultService.java @@ -51,4 +51,14 @@ private int getCollectCnt(List eachLottoNumbers, List answerNu eachLottoNumbers.retainAll(answerNumbers); return eachLottoNumbers.size(); } + + public int getReturnRate(int money) { + return 100 * ( + statisticCollectCntMap.get("THREE") * 5000 + + statisticCollectCntMap.get("FOUR") * 50000 + + statisticCollectCntMap.get("FIVE") * 1500000 + + statisticCollectCntMap.get("FIVEPLUSBONUS") * 30000000 + + statisticCollectCntMap.get("SIX") * 2000000000 + ) / money; + } } diff --git a/src/test/java/lotto/service/ResultServiceTest.java b/src/test/java/lotto/service/ResultServiceTest.java index 905a8b3..f62c609 100644 --- a/src/test/java/lotto/service/ResultServiceTest.java +++ b/src/test/java/lotto/service/ResultServiceTest.java @@ -6,10 +6,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; @@ -160,4 +157,125 @@ void getStatisticsTwoSixCollect() { () -> assertThat(statistics.get("SIX")).isEqualTo(2) ); } + + + @Test + @DisplayName("3개 일치 총 수익률을 계산한다.") + void getReturnRateThreeCollecth() { + } + + @Test + @DisplayName("3개 일치 총 수익률을 계산한다.") + void getReturnRateThreeCollect() { + // given + List userLottos = List.of( + new Lotto(new ArrayList<>(List.of(1, 2, 3, 11, 12, 13))) + ); + List answerNumbers = List.of(1, 2, 3, 4, 5, 6); + int bonusNumber = 7; + + // when + resultService.getStatistics(userLottos, answerNumbers, bonusNumber); + int money = 1000; + int returnRate = resultService.getReturnRate(money); + + // then + assertThat(returnRate).isEqualTo(100 * 5000 / money); + } + + @Test + @DisplayName("4개 일치 총 수익률을 계산한다.") + void getReturnRateFourCollect() { + // given + List userLottos = List.of( + new Lotto(new ArrayList<>(List.of(1, 2, 3, 4, 11, 12))) + ); + List answerNumbers = List.of(1, 2, 3, 4, 5, 6); + int bonusNumber = 7; + + // when + resultService.getStatistics(userLottos, answerNumbers, bonusNumber); + int money = 1000; + int returnRate = resultService.getReturnRate(money); + + // then + assertThat(returnRate).isEqualTo(100 * 50000 / money); + } + + @Test + @DisplayName("5개 일치 총 수익률을 계산한다.") + void getReturnRateFiveCollect() { + // given + List userLottos = List.of( + new Lotto(new ArrayList<>(List.of(1, 2, 3, 4, 5, 11))) + ); + List answerNumbers = List.of(1, 2, 3, 4, 5, 6); + int bonusNumber = 7; + + // when + resultService.getStatistics(userLottos, answerNumbers, bonusNumber); + int money = 1000; + int returnRate = resultService.getReturnRate(money); + + // then + assertThat(returnRate).isEqualTo(100 * 1500000 / money); + } + + @Test + @DisplayName("5개 일치, 보너스 일치 총 수익률을 계산한다.") + void getReturnRateBonusCollect() { + // given + List userLottos = List.of( + new Lotto(new ArrayList<>(List.of(1, 2, 3, 4, 5, 7))) + ); + List answerNumbers = List.of(1, 2, 3, 4, 5, 6); + int bonusNumber = 7; + + // when + resultService.getStatistics(userLottos, answerNumbers, bonusNumber); + int money = 1000; + int returnRate = resultService.getReturnRate(money); + + // then + assertThat(returnRate).isEqualTo(100 * 30000000 / money); + } + + @Test + @DisplayName("6개 일치 총 수익률을 계산한다.") + void getReturnRateSixCollect() { + // given + List userLottos = List.of( + new Lotto(new ArrayList<>(List.of(1, 2, 3, 4, 5, 6))) + ); + List answerNumbers = List.of(1, 2, 3, 4, 5, 6); + int bonusNumber = 7; + + // when + resultService.getStatistics(userLottos, answerNumbers, bonusNumber); + int money = 1000; + int returnRate = resultService.getReturnRate(money); + + // then + assertThat(returnRate).isEqualTo(100 * 2000000000 / money); + } + + @Test + @DisplayName("6개 일치 2개 총 수익률을 계산한다.") + void getReturnRateTwoSixCollect() { + // given + List userLottos = List.of( + new Lotto(new ArrayList<>(List.of(1, 2, 3, 4, 5, 6))), + new Lotto(new ArrayList<>(List.of(1, 2, 3, 4, 5, 6))) + ); + List answerNumbers = List.of(1, 2, 3, 4, 5, 6); + int bonusNumber = 7; + + // when + resultService.getStatistics(userLottos, answerNumbers, bonusNumber); + int money = 1000; + int returnRate = resultService.getReturnRate(money); + + // then + assertThat(returnRate).isEqualTo(100 * 2000000000 * 2 / money); + } } From 1e752fbfd8a2244d104afc5f4e5448c329c6c29a Mon Sep 17 00:00:00 2001 From: SangBeom-Hahn Date: Sun, 16 Jul 2023 21:36:04 +0900 Subject: [PATCH 12/12] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=EC=99=80=20=EC=88=98=EC=9D=B5=EB=A5=A0=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *feat: ResultService 기능 및 테스트 구현 *feat: Controller 관련 기능 구현 --- .../java/lotto/controller/Controller.java | 34 +++++++++++++++---- .../java/lotto/service/ResultService.java | 18 ++++++---- .../java/lotto/service/ResultServiceTest.java | 29 ++++++++-------- 3 files changed, 53 insertions(+), 28 deletions(-) diff --git a/src/main/java/lotto/controller/Controller.java b/src/main/java/lotto/controller/Controller.java index 1cb9318..f5edf18 100644 --- a/src/main/java/lotto/controller/Controller.java +++ b/src/main/java/lotto/controller/Controller.java @@ -3,8 +3,10 @@ import lotto.domain.Lotto.AnswerLotto; import lotto.domain.Lotto.Lotto; import lotto.domain.user.User; +import lotto.service.ResultService; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -14,11 +16,17 @@ public class Controller { private User user; + private ResultService resultService; + + public Controller() { + this.resultService = new ResultService(); + } public void run() { System.out.println("구입금액을 입력해 주세요."); - - buyLotto(); + int money = generateMoney(); + + buyLotto(money); List lottos = user.getLottos(); System.out.println(lottos.size() + "개를 구매했습니다."); @@ -27,15 +35,27 @@ public void run() { } System.out.println("당첨 번호를 입력해 주세요."); - String answerLottoNumbers = readLine(); + String answerNumbers = readLine(); System.out.println("보너스 번호를 입력해 주세요."); int bonusLottoNumber = Integer.parseInt(readLine()); - List answerLotto = Stream.of(answerLottoNumbers.split(",")) + List answerLottoNumbers = Stream.of(answerNumbers.split(",")) .map(Integer::valueOf).collect(Collectors.toList()); - new AnswerLotto(answerLotto, bonusLottoNumber); + AnswerLotto answerLotto = new AnswerLotto(answerLottoNumbers, bonusLottoNumber); + + Map statistics = resultService.getStatistics(lottos, answerLotto.getAnswerNumbers(), answerLotto.getBonusNumber()); + double returnRate = resultService.getReturnRate(money); + + System.out.println("당첨 통계"); + System.out.println("---"); + System.out.println("3개 일치 (5,000원)" + "-" + statistics.get("THREE") + "개"); + System.out.println("4개 일치 (50,000원)" + "-" + statistics.get("FOUR") + "개"); + System.out.println("5개 일치 (1,500,000원)" + "-" + statistics.get("FIVE") + "개"); + System.out.println("5개 일치, 보너스 볼 일치 (30,000,000원)" + "-" + statistics.get("FIVEPLUSBONUS") + "개"); + System.out.println("6개 일치 (2,000,000,000원)" + "-" + statistics.get("SIX") + "개"); + System.out.println(String.format("총 수익률은 %.1f입니다.", returnRate)); } - private void buyLotto() { - user = new User(generateLottos(generateMoney())); + private void buyLotto(int money) { + user = new User(generateLottos(money)); } } diff --git a/src/main/java/lotto/service/ResultService.java b/src/main/java/lotto/service/ResultService.java index e1abe7e..43e02ed 100644 --- a/src/main/java/lotto/service/ResultService.java +++ b/src/main/java/lotto/service/ResultService.java @@ -29,11 +29,15 @@ public Map getStatistics(List userLottos, List List eachLottoNumbers = userLotto.getNumbers(); bonusCnt = isContainsBonusNumber(eachLottoNumbers, bonusNumber); collectCnt = getCollectCnt(eachLottoNumbers, answerNumbers); - - if (bonusCnt == 1 && collectCnt == 5) { // 보너스가 있을 때 맞는 게 5개면 - statisticCollectCntMap.compute("FIVEPLUSBONUS", (k, v) -> Integer.valueOf(v + 1)); - } else { // 그 외 - statisticCollectCntMap.compute(collectMap.get(collectCnt), (k, v) -> Integer.valueOf(v + 1)); + + try { + if (bonusCnt == 1 && collectCnt == 5) { + statisticCollectCntMap.compute("FIVEPLUSBONUS", (k, v) -> Integer.valueOf(v + 1)); + } else { + statisticCollectCntMap.compute(collectMap.get(collectCnt), (k, v) -> Integer.valueOf(v + 1)); + } + } catch (NullPointerException e) { + } } @@ -52,8 +56,8 @@ private int getCollectCnt(List eachLottoNumbers, List answerNu return eachLottoNumbers.size(); } - public int getReturnRate(int money) { - return 100 * ( + public double getReturnRate(int money) { + return (double) 100 * ( statisticCollectCntMap.get("THREE") * 5000 + statisticCollectCntMap.get("FOUR") * 50000 + statisticCollectCntMap.get("FIVE") * 1500000 + diff --git a/src/test/java/lotto/service/ResultServiceTest.java b/src/test/java/lotto/service/ResultServiceTest.java index f62c609..9637926 100644 --- a/src/test/java/lotto/service/ResultServiceTest.java +++ b/src/test/java/lotto/service/ResultServiceTest.java @@ -1,15 +1,16 @@ package lotto.service; import lotto.domain.Lotto.Lotto; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertAll; class ResultServiceTest { private ResultService resultService; @@ -177,7 +178,7 @@ void getReturnRateThreeCollect() { // when resultService.getStatistics(userLottos, answerNumbers, bonusNumber); int money = 1000; - int returnRate = resultService.getReturnRate(money); + double returnRate = resultService.getReturnRate(money); // then assertThat(returnRate).isEqualTo(100 * 5000 / money); @@ -196,7 +197,7 @@ void getReturnRateFourCollect() { // when resultService.getStatistics(userLottos, answerNumbers, bonusNumber); int money = 1000; - int returnRate = resultService.getReturnRate(money); + double returnRate = resultService.getReturnRate(money); // then assertThat(returnRate).isEqualTo(100 * 50000 / money); @@ -215,10 +216,10 @@ void getReturnRateFiveCollect() { // when resultService.getStatistics(userLottos, answerNumbers, bonusNumber); int money = 1000; - int returnRate = resultService.getReturnRate(money); + double returnRate = resultService.getReturnRate(money); // then - assertThat(returnRate).isEqualTo(100 * 1500000 / money); + assertThat(returnRate).isEqualTo(100d * 1500000 / money); } @Test @@ -234,10 +235,10 @@ void getReturnRateBonusCollect() { // when resultService.getStatistics(userLottos, answerNumbers, bonusNumber); int money = 1000; - int returnRate = resultService.getReturnRate(money); + double returnRate = resultService.getReturnRate(money); // then - assertThat(returnRate).isEqualTo(100 * 30000000 / money); + assertThat(returnRate).isEqualTo(100d * 30000000 / money); } @Test @@ -253,10 +254,10 @@ void getReturnRateSixCollect() { // when resultService.getStatistics(userLottos, answerNumbers, bonusNumber); int money = 1000; - int returnRate = resultService.getReturnRate(money); + double returnRate = resultService.getReturnRate(money); // then - assertThat(returnRate).isEqualTo(100 * 2000000000 / money); + assertThat(returnRate).isEqualTo(100d * 2000000000 / money); } @Test @@ -272,10 +273,10 @@ void getReturnRateTwoSixCollect() { // when resultService.getStatistics(userLottos, answerNumbers, bonusNumber); - int money = 1000; - int returnRate = resultService.getReturnRate(money); + int money = 2000; + double returnRate = resultService.getReturnRate(money); // then - assertThat(returnRate).isEqualTo(100 * 2000000000 * 2 / money); + assertThat(returnRate).isEqualTo((double) 100 * (2 * 2000000000) / money); } }