From a0a5a4fcf3f3d00fb492d2dacf7c0017dba8ff08 Mon Sep 17 00:00:00 2001 From: xxxjinn Date: Tue, 14 Jan 2025 21:21:57 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=E3=85=A0=E3=85=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/Application.java | 6 ++ src/main/java/lotto/Lotto.java | 20 ----- src/main/java/lotto/config/AppConfig.java | 15 ++++ .../lotto/controller/LottoController.java | 46 ++++++++++ src/main/java/lotto/dto/LottoDto.java | 15 ++++ src/main/java/lotto/model/Lotto.java | 27 ++++++ src/main/java/lotto/service/LottoService.java | 12 +++ .../java/lotto/service/LottoServiceImpl.java | 77 +++++++++++++++++ src/main/java/lotto/view/InputView.java | 84 +++++++++++++++++++ src/main/java/lotto/view/OutputView.java | 34 ++++++++ src/test/java/lotto/LottoTest.java | 1 + 11 files changed, 317 insertions(+), 20 deletions(-) delete mode 100644 src/main/java/lotto/Lotto.java create mode 100644 src/main/java/lotto/config/AppConfig.java create mode 100644 src/main/java/lotto/controller/LottoController.java create mode 100644 src/main/java/lotto/dto/LottoDto.java create mode 100644 src/main/java/lotto/model/Lotto.java create mode 100644 src/main/java/lotto/service/LottoService.java create mode 100644 src/main/java/lotto/service/LottoServiceImpl.java create mode 100644 src/main/java/lotto/view/InputView.java create mode 100644 src/main/java/lotto/view/OutputView.java diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922ba44..ae4392228b1 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,13 @@ package lotto; +import lotto.config.AppConfig; +import lotto.controller.LottoController; + public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 + AppConfig appConfig = new AppConfig(); + LottoController lottoController = appConfig.lottoController(); + lottoController.run(); } } diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java deleted file mode 100644 index 519793d1f73..00000000000 --- a/src/main/java/lotto/Lotto.java +++ /dev/null @@ -1,20 +0,0 @@ -package lotto; - -import java.util.List; - -public class Lotto { - private final List numbers; - - public Lotto(List numbers) { - validate(numbers); - this.numbers = numbers; - } - - private void validate(List numbers) { - if (numbers.size() != 6) { - throw new IllegalArgumentException(); - } - } - - // TODO: 추가 기능 구현 -} diff --git a/src/main/java/lotto/config/AppConfig.java b/src/main/java/lotto/config/AppConfig.java new file mode 100644 index 00000000000..6ee0cbfc7f8 --- /dev/null +++ b/src/main/java/lotto/config/AppConfig.java @@ -0,0 +1,15 @@ +package lotto.config; + +import lotto.controller.LottoController; +import lotto.service.LottoService; +import lotto.service.LottoServiceImpl; + +public class AppConfig { + public LottoService lottoService(){ + return new LottoServiceImpl(); + }; + + public LottoController lottoController(){ + return new LottoController(lottoService()); + }; +} diff --git a/src/main/java/lotto/controller/LottoController.java b/src/main/java/lotto/controller/LottoController.java new file mode 100644 index 00000000000..72f2d045a67 --- /dev/null +++ b/src/main/java/lotto/controller/LottoController.java @@ -0,0 +1,46 @@ +package lotto.controller; + +import lotto.dto.LottoDto; +import lotto.model.Lotto; +import lotto.service.LottoService; +import lotto.view.InputView; +import lotto.view.OutputView; + +import java.util.List; +import java.util.Map; + +public class LottoController { + private final LottoService lottoService; + + public LottoController(LottoService lottoService) { + this.lottoService = lottoService; + } + + public void run(){ + int purchaseAmount = InputView.getPurchaseAmount(); + int numberOfLottos = purchaseAmount/1000; + Lotto winningLotto = null; + + List> lottoNumbersList = lottoService.generateLottoNumbers(numberOfLottos); + OutputView.printPurchaseCount(numberOfLottos); + OutputView.printLottoNumers(lottoNumbersList); + + while(true) { + LottoDto winningNumbersDto = InputView.getWinningNumbers(); + try { + winningLotto = new Lotto(winningNumbersDto.getNumbers()); + break; + } catch (IllegalArgumentException e) { + System.out.println("[ERROR] " + e.getMessage()); + } + } + + int bonusNumber = InputView.getBonusNumber(); + + Map statistics = lottoService.calculateLotto(lottoNumbersList, winningLotto, bonusNumber); + OutputView.printStatistics(statistics); + + double profitRate = lottoService.calculateProfitRate(purchaseAmount, statistics); + OutputView.printProfitRate(profitRate); + } +} diff --git a/src/main/java/lotto/dto/LottoDto.java b/src/main/java/lotto/dto/LottoDto.java new file mode 100644 index 00000000000..3a4a84ab677 --- /dev/null +++ b/src/main/java/lotto/dto/LottoDto.java @@ -0,0 +1,15 @@ +package lotto.dto; + +import java.util.List; + +public class LottoDto { + private final List numbers; + + public LottoDto(List numbers) { + this.numbers = numbers; + } + + public List getNumbers() { + return numbers; + } +} diff --git a/src/main/java/lotto/model/Lotto.java b/src/main/java/lotto/model/Lotto.java new file mode 100644 index 00000000000..9733a27596e --- /dev/null +++ b/src/main/java/lotto/model/Lotto.java @@ -0,0 +1,27 @@ +package lotto.model; + +import java.util.List; + +public class Lotto { + private final List numbers; + + public Lotto(List numbers) { + validate(numbers); + this.numbers = numbers; + } + + private void validate(List numbers) { + if (numbers.size() != 6) { + throw new IllegalArgumentException("로또 번호는 6개여야 합니다."); + } + for (int num : numbers) { + if (num < 1 || num > 45) { + throw new IllegalArgumentException("로또 번호는 1부터 45 사이의 숫자여야 합니다."); + } + } + } + + public List getNumbers() { + return numbers; + } +} diff --git a/src/main/java/lotto/service/LottoService.java b/src/main/java/lotto/service/LottoService.java new file mode 100644 index 00000000000..0516056b3bd --- /dev/null +++ b/src/main/java/lotto/service/LottoService.java @@ -0,0 +1,12 @@ +package lotto.service; + +import lotto.model.Lotto; + +import java.util.List; +import java.util.Map; + +public interface LottoService { + List> generateLottoNumbers(int numberOfLottos); + Map calculateLotto(List> lottoNumbers, Lotto winningLotto, int bonusNumber); + double calculateProfitRate(int purchaseAmount, Map lottoNumberMap); +} diff --git a/src/main/java/lotto/service/LottoServiceImpl.java b/src/main/java/lotto/service/LottoServiceImpl.java new file mode 100644 index 00000000000..908105f5ded --- /dev/null +++ b/src/main/java/lotto/service/LottoServiceImpl.java @@ -0,0 +1,77 @@ +package lotto.service; + +import camp.nextstep.edu.missionutils.Randoms; +import lotto.model.Lotto; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/* 실제 LottoService 기능 구현*/ +public class LottoServiceImpl implements LottoService { + @Override + public List> generateLottoNumbers(int numberOfLottos) { + List> lottoNumbersList = new ArrayList<>(); + for (int i = 0; i < numberOfLottos; i++) { + List lottoNumbers = Randoms.pickUniqueNumbersInRange(1, 45, 6); + lottoNumbers.sort(Integer::compareTo); + lottoNumbersList.add(lottoNumbers); + } + return lottoNumbersList; + } + + @Override + public Map calculateLotto(List> lottoNumbers, Lotto winningLotto, int bonusNumber){ + Map lottoNumbersMap = new HashMap<>(); + lottoNumbersMap.put("3개 일치", 0); + lottoNumbersMap.put("4개 일치", 0); + lottoNumbersMap.put("5개 일치", 0); + lottoNumbersMap.put("5개 일치, 보너스 볼 일치", 0); + lottoNumbersMap.put("6개 일치", 0); + + for (List lottoNumber : lottoNumbers) { + int matchCount = getMatchCount(lottoNumber, winningLotto.getNumbers()); + boolean bonusMatch = lottoNumber.contains(bonusNumber); + + if (matchCount == 6) { + lottoNumbersMap.put("6개 일치", lottoNumbersMap.get("6개 일치") + 1); + } else if (matchCount == 5 && bonusMatch) { + lottoNumbersMap.put("5개 일치, 보너스 볼 일치", lottoNumbersMap.get("5개 일치, 보너스 볼 일치") + 1); + } else if (matchCount == 5) { + lottoNumbersMap.put("5개 일치", lottoNumbersMap.get("5개 일치") + 1); + } else if (matchCount == 4) { + lottoNumbersMap.put("4개 일치", lottoNumbersMap.get("4개 일치") + 1); + } else if (matchCount == 3) { + lottoNumbersMap.put("3개 일치", lottoNumbersMap.get("3개 일치") + 1); + } + } + return lottoNumbersMap; + } + + private int getMatchCount(List lottoNumber, List winningNumbers) { + int matchCount = 0; + for (int number : lottoNumber) { + if(winningNumbers.contains(number)) matchCount++; + } + return matchCount; + } + + @Override + public double calculateProfitRate(int purchaseAmount, Map lottoNumberMap) { + int totalWinningAmount = calculateTotalWinningAmount(lottoNumberMap); + return (double) totalWinningAmount / purchaseAmount; + } + + private int calculateTotalWinningAmount(Map statistics) { + int totalAmount = 0; + + totalAmount += statistics.get("3개 일치") * 5000; + totalAmount += statistics.get("4개 일치") * 50000; + totalAmount += statistics.get("5개 일치") * 1500000; + totalAmount += statistics.get("5개 일치, 보너스 볼 일치") * 30000000; + totalAmount += statistics.get("6개 일치") * 2000000000; + + return totalAmount; + } +} diff --git a/src/main/java/lotto/view/InputView.java b/src/main/java/lotto/view/InputView.java new file mode 100644 index 00000000000..cada3e27212 --- /dev/null +++ b/src/main/java/lotto/view/InputView.java @@ -0,0 +1,84 @@ +package lotto.view; + +import camp.nextstep.edu.missionutils.Console; +import lotto.dto.LottoDto; + +import java.util.ArrayList; +import java.util.List; + + +public class InputView { + /* 구입 금액 입력 */ + public static int getPurchaseAmount() { + while (true) { + try { + System.out.println("구입 금액을 입력해주세요."); + String input = Console.readLine(); + validatePurchaseAmount(input); + return Integer.parseInt(input); + } catch (IllegalArgumentException e) { + System.out.println("[ERROR] " + e.getMessage()); + } + } + } + + private static void validatePurchaseAmount(String purchaseAmount) { + try { + int amount = Integer.parseInt(purchaseAmount); + if (amount <= 0) { + throw new IllegalArgumentException("구매 금액은 0보다 커야 합니다."); + } + if (amount % 1000 != 0) { + throw new IllegalArgumentException("구매 금액은 1000 단위로 나누어 떨어져야 합니다."); + } + } catch (NumberFormatException e) { + throw new IllegalArgumentException("구매 금액은 숫자여야 합니다."); + } + } + + /* 당첨 금액 입력 */ + public static LottoDto getWinningNumbers(){ + while (true) { + try { + System.out.println("\n당첨 번호를 입력해주세요."); + String inputWinningNumbers = Console.readLine(); + List numbers = parseWinningNumbers(inputWinningNumbers); + return new LottoDto(numbers); + } catch (IllegalArgumentException e) { + System.out.println("[ERROR] " + e.getMessage()); + } + } + } + + private static List parseWinningNumbers(String inputWinningNumbers) { + String[] numberStrings = inputWinningNumbers.split(","); + List numbers = new ArrayList<>(); + + try { + for (String numberString : numberStrings) { + numbers.add(Integer.parseInt(numberString.trim())); + } + } catch (NumberFormatException e) { + throw new IllegalArgumentException("로또 번호는 숫자여야 합니다."); + } + + return numbers; + } + + /* 보너스 번호 입력 */ + public static int getBonusNumber(){ + while (true) { + try { + System.out.println("\n보너스 번호를 입력해주세요."); + String input = Console.readLine(); + int bonusNumber = Integer.parseInt(input.trim()); + if (bonusNumber < 1 || bonusNumber > 45) { + throw new IllegalArgumentException("보너스 번호는 1과 45 사이의 숫자여야 합니다."); + } + return Integer.parseInt(input.trim()); + } catch (IllegalArgumentException e) { + System.out.println("[ERROR] " + e.getMessage()); + } + } + } +} diff --git a/src/main/java/lotto/view/OutputView.java b/src/main/java/lotto/view/OutputView.java new file mode 100644 index 00000000000..f4fe5ad9252 --- /dev/null +++ b/src/main/java/lotto/view/OutputView.java @@ -0,0 +1,34 @@ +package lotto.view; + +import java.util.List; +import java.util.Map; + +public class OutputView { + /* 로또 구입 개수 출력 */ + public static void printPurchaseCount(int numberOfLottos){ + System.out.println("\n"+numberOfLottos+"개를 구매했습니다."); + } + + /* 로또 번호 출력 */ + public static void printLottoNumers(List> lottoNumbers){ + for (List numbers : lottoNumbers) { + System.out.println(numbers); + } + } + + /* 당첨 통계 출력 */ + public static void printStatistics(Map statistics) { + System.out.println("\n당첨 통계"); + System.out.println("---"); + System.out.println("3개 일치 (5,000원) - " + statistics.get("3개 일치") + "개"); + System.out.println("4개 일치 (50,000원) - " + statistics.get("4개 일치") + "개"); + System.out.println("5개 일치 (1,500,000원) - " + statistics.get("5개 일치") + "개"); + System.out.println("5개 일치, 보너스 볼 일치 (30,000,000원) - " + statistics.get("5개 일치, 보너스 볼 일치") + "개"); + System.out.println("6개 일치 (2,000,000,000원) - " + statistics.get("6개 일치") + "개"); + } + + /* 수익률 출력 */ + public static void printProfitRate(double profitRate) { + System.out.printf("총 수익률은 %.1f%%입니다.\n", profitRate); + } +} diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 9f5dfe7eb83..33472c95fd0 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -1,5 +1,6 @@ package lotto; +import lotto.model.Lotto; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; From adbb79471065e88b424a5000a1b7085583632f14 Mon Sep 17 00:00:00 2001 From: xxxjinn Date: Tue, 14 Jan 2025 21:36:09 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=EB=8B=B9=EC=B2=A8=20=EB=B2=88=ED=98=B8=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=EC=95=88=EB=90=98=EA=B2=8C=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lotto/model/Lotto.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/lotto/model/Lotto.java b/src/main/java/lotto/model/Lotto.java index 9733a27596e..3b8ebaba390 100644 --- a/src/main/java/lotto/model/Lotto.java +++ b/src/main/java/lotto/model/Lotto.java @@ -1,6 +1,8 @@ package lotto.model; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class Lotto { private final List numbers; @@ -19,6 +21,10 @@ private void validate(List numbers) { throw new IllegalArgumentException("로또 번호는 1부터 45 사이의 숫자여야 합니다."); } } + Set uniqueNumbers = new HashSet<>(numbers); + if (uniqueNumbers.size() != numbers.size()) { + throw new IllegalArgumentException("로또 번호에는 중복이 존재하지 않아야 합니다."); + } } public List getNumbers() {