diff --git a/README.md b/README.md index e69de29b..b0ab8283 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,41 @@ +## 구현 기능 목록 + +* 사용자로부터 구입 금액을 입력받아야 한다. + * (예외상황) 입력된 값이 숫자인지 검증해야 한다. + * (예외상황) 입력된 값이 1000원 이상인지 검증해야 한다. + * (예외상황) 입력된 값이 10만원 이하인지 검증해야 한다. > 1인당 로또 최대 구매가능 금액 + +* 입력받은 금액만큼 로또를 구매해야 한다. + * 입력받은 금액을 로또금액(LOTTO_PRICE)으로 나누어 구매 개수를 구해야 한다. + * 구매 개수만큼 Lotto 인스턴스를 생성해야 한다. + * 1~45 숫자 중 중복없이 랜덤하게 6개의 숫자를 생성한다. + + * 구매하고 남은 돈인 거스름돈을 구해야 한다. + * 구매 개수와 거스름돈, 구매 결과를 사용자에게 알려준다. + +* 지난주 당첨번호를 입력받아야 한다. + * 입력한 번호를 쉼표 기준으로 분리해야 한다. + * (예외상황) 입력된 값이 숫자인지 검증해야 한다. + * (예외상황) 입력된 값이 1~45 사이의 숫자인지 검증해야 한다. + * (예외상황) 입력된 값의 수가 6개인지 검증해야 한다. + * (예외상황) 입력된 값에 중복이 없는지 검증해야 한다. + +* 지난주 보너스번호를 입력받아야 한다. + * (예외상황) 입력된 값이 숫자인지 검증해야 한다. + * (예외상황) 입력된 값이 1~45 사이의 숫자인지 검증해야 한다. + * (예외상황) 입력된 값이 당첨번호와 겹치지 않는지 검증해야 한다. + * WinningLotto 인스턴스를 생성해야 한다. + +--- +### 여기까지 중복기능 정리 (리팩토링) +1. 입력받은 String이 숫자인지 검증하는 메소드 +2. 숫자인지 검증 이후, 해당 값이 특정 범위 내에 있는지 검증하는 메소드 +3. 사용자로부터 값을 올바른 값이 입력될 때까지 입력받는 메소드 +--- + +* 로또 당첨 결과를 도출해야 한다. + * 구매한 각 로또가 당첨번호+보너스번호와 매치되는 숫자 갯수(countOfMatch)를 구해야 한다. + * 구매한 각 로또가 보너스번호와 매치되는지 여부(matchBonus)를 구해야 한다. + * MISS를 제외 각 등수별 로또 개수를 구해야 한다. + * 총 상금액을 구해야 한다. + * 총 수익률을 구해야 한다. diff --git a/src/main/java/domain/Lotto.java b/src/main/java/domain/Lotto.java index 06694869..287d46e1 100644 --- a/src/main/java/domain/Lotto.java +++ b/src/main/java/domain/Lotto.java @@ -12,5 +12,25 @@ public Lotto(List numbers) { this.numbers = numbers; } - // 추가 기능 구현 + public List getNumbers() { + return numbers; + } + + public int isMatch(int number) { + if (numbers.contains(number)) { + return 1; + } + + return 0; + } + + public int howManyMatch(Lotto lotto) { + int countOfMatch = 0; + + for (int number : numbers) { + countOfMatch += lotto.isMatch(number); + } + + return countOfMatch; + } } diff --git a/src/main/java/domain/LottoGame.java b/src/main/java/domain/LottoGame.java new file mode 100644 index 00000000..4212b0b5 --- /dev/null +++ b/src/main/java/domain/LottoGame.java @@ -0,0 +1,329 @@ + +/* + * LottoGame + * + * ver 1.0 + * + * 2019/04/11 + * + * Copyright 2019. Jieun Jeong. All ringts reserved. + */ + +package domain; + +import java.util.*; + +public class LottoGame { + public static boolean isStringNumber(String number) { + try { + Integer.parseInt(number); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + public static boolean isRangeIn(int number, int min, int max) { + if ((min <= number) && (number <= max)) { + return true; + } + + return false; + } + + public static void alertMoneyNotice(int inputMoney, int min, int max) { + if (min > inputMoney) { + System.out.println("금액이 부족합니다."); + } + + if (inputMoney > max) { + System.out.println("1인당 최대 10만원까지 구매 가능합니다."); + } + } + + public static boolean isProperMoney(String inputMoney) { + if (isStringNumber(inputMoney)) { + int MIN_LOTTO_PRICE = 1000; + int MAX_LOTTO_PRICE = 100000; + int money = Integer.parseInt(inputMoney); + + alertMoneyNotice(money, MIN_LOTTO_PRICE, MAX_LOTTO_PRICE); + + return isRangeIn(money, MIN_LOTTO_PRICE, MAX_LOTTO_PRICE); + } + + return false; + } + + public static String inputMoney(boolean isFirstTry) { + Scanner scanner = new Scanner(System.in); + + if (isFirstTry) { + System.out.println("구입 금액을 입력해 주세요."); + } else { + System.out.println("구입 금액을 제대로 입력해 주세요."); + } + + String answer = scanner.nextLine(); + return answer; + } + + public static int payMoney() { + boolean isFirstTry = true; + String inputMoney = inputMoney(isFirstTry); + boolean isProper = isProperMoney(inputMoney); + + while (!isProper) { + isFirstTry = false; + inputMoney = inputMoney(isFirstTry); + isProper = isProperMoney(inputMoney); + } + + return Integer.parseInt(inputMoney); + } + + public static int getPurchasableNumber(int money) { + int ONE_LOTTO_PRICE = 1000; + int purchasableNumber = money / ONE_LOTTO_PRICE; + + return purchasableNumber; + } + + public static int getCharge(int money) { + int ONE_LOTTO_PRICE = 1000; + int charge = money % ONE_LOTTO_PRICE; + + return charge; + } + + public static List generateLottoNumber() { + HashSet numbers = new HashSet<>(); + + while (numbers.size() != 6) { + numbers.add((int) (Math.random() * 45 + 1)); + } + + List lottoNumbers = new ArrayList<>(numbers); + return lottoNumbers; + } + + public static void announcePurchaseResult(List lottos, int charge) { + int numberOfNumber = lottos.size(); + String message = String.format( + "\n거스름돈은 %d 원이고, %d개를 구매하였습니다.",charge, numberOfNumber); + + System.out.println(message); + + for (Lotto lotto : lottos) { + System.out.println(lotto.getNumbers()); + } + } + + public static List purchaseLotto(int money) { + int purchasableLotto = getPurchasableNumber(money); + int charge = getCharge(money); + List boughtLotto = new ArrayList<>(); + + for (int i = 0; i < purchasableLotto; i++) { + Lotto lotto = new Lotto(generateLottoNumber()); + boughtLotto.add(lotto); + } + + announcePurchaseResult(boughtLotto, charge); + return boughtLotto; + } + + public static boolean isProperLength(String[] inputNumbers) { + int PROPER_LOTTO_LENGTH = 6; + Set removeDuplicate = new HashSet<>(Arrays.asList(inputNumbers)); + + if (removeDuplicate.size() == PROPER_LOTTO_LENGTH) { + return true; + } + + return false; + } + + public static boolean isProperLottoNumber(String inputnumber) { + if (isStringNumber(inputnumber)) { + int MIN_LOTTO_NUMBER = 1; + int MAX_LOTTO_NUMBER = 45; + int number = Integer.parseInt(inputnumber); + + return isRangeIn(number, MIN_LOTTO_NUMBER, MAX_LOTTO_NUMBER); + } + + return false; + } + + public static boolean isProperLottoNumbers(String[] inputNumbers) { + if (!isProperLength(inputNumbers)) { + return false; + } + + for (String number : inputNumbers) { + if (!isProperLottoNumber(number)) { + return false; + } + } + + return true; + } + + public static String[] inputWinningNumbers(boolean isFirstTry) { + Scanner scanner = new Scanner(System.in); + + if (isFirstTry) { + System.out.println("\n지난 주 당첨 번호를 입력해 주세요."); + } else { + System.out.println("\n지난 주 당첨 번호를 제대로 입력해 주세요."); + } + + String inputNumbers = scanner.nextLine(); + return inputNumbers.split(","); + } + + public static String[] receiveWinningNumbers() { + boolean isFirstTry = true; + String[] inputNumbers = inputWinningNumbers(isFirstTry); + boolean isProper = isProperLottoNumbers(inputNumbers); + + while (!isProper) { + isFirstTry = false; + inputNumbers = inputWinningNumbers(isFirstTry); + isProper = isProperLottoNumbers(inputNumbers); + } + + return inputNumbers; + } + + public static boolean isProperBonusNumber(String inputBonusNumber, + String[] inputLottoNumber) { + if (isProperLottoNumber(inputBonusNumber)) { + return !Arrays.asList(inputLottoNumber).contains(inputBonusNumber); + } + + return false; + } + + public static String inputBonusNumber(boolean isFirstTry) { + Scanner scanner = new Scanner(System.in); + + if (isFirstTry) { + System.out.println("\n보너스 볼을 입력해 주세요."); + } else { + System.out.println("\n보너스 볼을 제대로 입력해 주세요."); + } + + String inputBonusNumber = scanner.nextLine(); + return inputBonusNumber; + } + + public static int receiveBonusNumber(String[] lottoNumbers) { + boolean isFirstTry = true; + String inputBonusNumber = inputBonusNumber(isFirstTry); + boolean isProper = isProperBonusNumber(inputBonusNumber, lottoNumbers); + + while (!isProper) { + isFirstTry = false; + inputBonusNumber = inputBonusNumber(isFirstTry); + isProper = isProperBonusNumber(inputBonusNumber, lottoNumbers); + } + + return Integer.parseInt(inputBonusNumber); + } + + public static List changeElementTypeStrToInt(String[] lottoNumbers) { + List numbers = new ArrayList<>(); + + for (String number : lottoNumbers) { + numbers.add(Integer.parseInt(number)); + } + + return numbers; + } + + public static WinningLotto generateWinningLotto() { + String[] inputNumbers = receiveWinningNumbers(); + List numbers = changeElementTypeStrToInt(inputNumbers); + int bonusNumber = receiveBonusNumber(inputNumbers); + + Lotto lotto = new Lotto(numbers); + WinningLotto winningLotto = new WinningLotto(lotto, bonusNumber); + + return winningLotto; + } + + public static List getLottoResult(List userLottos, + WinningLotto winningLotto) { + List lottoResult = Arrays.asList(0,0,0,0,0,0); + + for (Lotto lotto : userLottos) { + Rank rank = winningLotto.match(lotto); + lottoResult.set(rank.ordinal(), lottoResult.get(rank.ordinal()) + 1); + } + + return lottoResult; + } + + public static void announceRankResult(Rank rank, int countOfMatch, + int winningMoney, int countOfWin) { + if (rank == Rank.SECOND) { + System.out.println(String.format("%d개 일치, 보너스 볼 일치(%d원) - %d개", + countOfMatch, winningMoney, countOfWin)); + } else if (rank != Rank.MISS) { + System.out.println(String.format("%d개 일치(%d원) - %d개", + countOfMatch, winningMoney, countOfWin)); + } + } + + public static int getRankResult(List result, Rank rank) { + int countOfMatch = rank.getCountOfMatch(); + int winningMoney = rank.getWinningMoney(); + int countOfWin = result.get(rank.ordinal()); + int totalWinningMoney = winningMoney * countOfWin; + + announceRankResult(rank, countOfMatch, winningMoney, countOfWin); + + return totalWinningMoney; + } + + public static List reverseEnum(Rank[] initEnum) { + List reverseEnum = new ArrayList<>(); + + for (int i = initEnum.length - 1; i >= 0; i--) { + reverseEnum.add(initEnum[i]); + } + + return reverseEnum; + } + + public static int getWinningMoney(List userLottos, + WinningLotto winningLotto) { + int totalWinningMoney = 0; + List result = getLottoResult(userLottos,winningLotto); + + System.out.println("\n당첨통계\n--------"); + + for (Rank rank : reverseEnum(Rank.values())) { + totalWinningMoney += getRankResult(result, rank); + } + + return totalWinningMoney; + } + + public static void announceEarningRate(int paidMoney, int winningMoney) { + double earningRate = winningMoney / paidMoney; + + System.out.println(String.format("총 수익률은 %.3f 입니다.", earningRate)); + } + + public static void main(String[] args) { + int paidMoney = payMoney(); + List purchasedLotto = purchaseLotto(paidMoney); + WinningLotto winningLotto = generateWinningLotto(); + int winningMoney = getWinningMoney(purchasedLotto, winningLotto); + + announceEarningRate(paidMoney, winningMoney); + } +} diff --git a/src/main/java/domain/WinningLotto.java b/src/main/java/domain/WinningLotto.java index d810418b..4fc10c8f 100644 --- a/src/main/java/domain/WinningLotto.java +++ b/src/main/java/domain/WinningLotto.java @@ -13,7 +13,10 @@ public WinningLotto(Lotto lotto, int bonusNo) { } public Rank match(Lotto userLotto) { - // TODO 로직 구현 - return null; + int countOfMatch = lotto.howManyMatch(userLotto); + boolean matchBonus = userLotto.getNumbers().contains(bonusNo); + Rank rank = Rank.valueOf(countOfMatch, matchBonus); + + return rank; } }