Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import domain.Input;
import domain.GenerateLotto;
import domain.WinningLotto;
import view.Print;

import java.util.ArrayList;

public class Main {
public static void main(String[] args) {
GenerateLotto lotto = new GenerateLotto();
WinningLotto winningLotto = new WinningLotto();
Print print = new Print();
Input input = new Input();

int purchaseAmount = input.setPurchaseAmount();

int manualCount = input.setManualCount();

if (manualCount > 0) {
lotto.getManualLotto(purchaseAmount, manualCount);
}

ArrayList<ArrayList<Integer>> totalLottos = lotto.getLotto(lotto.getRemainingMoney(purchaseAmount, manualCount));

print.printPurchasedLottoCount(manualCount, totalLottos);

ArrayList<Integer> winningNumbers = input.setWinningNumber();

int bonusNumber = input.setBonusNumber(winningNumbers);

winningLotto.totalCheckLotto(totalLottos, winningNumbers, bonusNumber);

print.printWinningCount(winningLotto.winningCount, winningLotto.calculateRate(purchaseAmount));

}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Main 이라는 객체는 최종 마무리 객체라고 생각해요

하나의 controller 객체를 만들어서 대부분의 내용을 그 객체에다 구현해놓고

Main이라는 곳에 마무리 정리 내용을 적는게 더 좋을거 같습니다

79 changes: 79 additions & 0 deletions src/main/java/domain/GenerateLotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package domain;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class GenerateLotto {
ArrayList<ArrayList<Integer>> totalLotto = new ArrayList<>();

Comment on lines +11 to +13

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ArrayList<ArrayList> totalLotto 형태로 코드를 작성하셨습니다.
Lotto라는 객체를 하나 만들어서
ArrayList totalLotto 형태로 바꿔주신다면 코드를 읽는것도 수월하고 무엇보다 확장성 및 유지보수에
좋다라고 생각해요.

만약에 프로그램을 만들어논 상태에서 로또의 색깔을 추가해야 된다는 상황이 발생할 경우
Lotto객체를 만들지 않은 프로그램은 GenerateLotto에서 직접 함수를 추가해야되서
GenerateLotto의 역할이 너무 많아진다고 생각해요.
Lotto객체가 있으면 Lotto객체의 멤버 변수를 만들어서 그 부분만 추가할 수 있어 편리하다고 생각합니다.

private ArrayList<Integer> getOne() {
GenerateRandom random = new GenerateRandom();

Set<Integer> set = new HashSet<>();

while (set.size() != 6) {
set.add(random.generateRandom());
}
ArrayList<Integer> lotto = new ArrayList<>(set);


Collections.sort(lotto);

return lotto;
}

Comment on lines +16 to +31

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

하나의 정수를 1~45번중 랜덤으로 가져와서 6개의 크기가 채워지면
lotto리스트에 넣는 함수로 보입니다.

로또의 번호가 중복이 될 수있어서 contains() 함수를 이용하여
로또 번호가 이미 존재하는지 안하는지를 판별하면 좋을거 같습니다

public ArrayList<ArrayList<Integer>> getLotto(int money) {
for (int i = 0; i < money; i += 1000) {
totalLotto.add(this.getOne());
}

return totalLotto;
}

public ArrayList<Integer> getManualOne() {

Input input = new Input();

ArrayList<Integer> manualOne = input.setManualNumber();

for (int one: manualOne){
validateLottoRange(one);
}

if (manualOne.stream().distinct().count() != 6) {
throw new IllegalArgumentException("로또 번호 중복 입력은 불가능합니다.");
}

Collections.sort(manualOne);

return manualOne;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 Input객체가 domain에 있습니다.
MVC 구조에서 보시면
View 패키지 안에 Input과 Print 객체를 선언하는게 좋을거 같습니다.

또한 domain 객체 안에 Input()을 사용하여 Text를 입력받기 보다는
controller패키지 안에서 domain 과 view를 사용하여 입력받는것이 좋을거 같습니다.


public void getManualLotto(int purchaseAmount, int manualCount) {
if (checkRemainingMoney(purchaseAmount, manualCount)) {
throw new IllegalArgumentException("구입 금액을 넘은 갯수 입니다.");
}
System.out.println("\n수동으로 구매할 번호를 입력해 주세요.");

for (int i = 0; i < manualCount; i++) {
totalLotto.add(this.getManualOne());
}
}

public int getRemainingMoney(int money, int manualCount) {
return money - (1000 * manualCount);
}

public boolean checkRemainingMoney(int money, int manualCount) {
return money < manualCount * 1000;
}

public void validateLottoRange(int number) {
if (number < 1 || number > 45) {
throw new IllegalArgumentException("1 ~ 45사이의 값만 입력할 수 있습니다.");
}

}
}
12 changes: 12 additions & 0 deletions src/main/java/domain/GenerateRandom.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package domain;

import java.util.Random;

public class GenerateRandom {
public int generateRandom() {
Random random = new Random();

return random.nextInt(45) + 1;
}

}
Comment on lines +1 to +12

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

따로 랜덤 객체를 만든건 너무 좋은 습관 같습니다.
이렇게 따로 랜덤 객체를 만들어 놓으면
랜덤 값을 받는 로또 객체를 Test할 때 더욱 쉽게 Test할수 있다고 생각해요

95 changes: 95 additions & 0 deletions src/main/java/domain/Input.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package domain;

import java.util.ArrayList;
import java.util.Scanner;

public class Input {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문제에서 예외상황을 정의해 주지 않아서 대부분의 경우의 수를 고려해야 될 거같습니다.

숫자가 아닌 문자열 형태나 공백을 입력 받았을 때 처리하는 예외도 있으면 좋을거 같아요

public int setPurchaseAmount() {
System.out.println("구입금액을 입력해주세요.");
Scanner scanner = new Scanner(System.in);

int money = scanner.nextInt();

if (validateNegativeNumber(money)) {
throw new IllegalArgumentException();
}

return money;
}

public ArrayList<Integer> setWinningNumber() {
System.out.println("\n지난 주 당첨 번호를 입력해 주세요.");
Scanner scanner = new Scanner(System.in);

String line = scanner.nextLine();

int count = separateNumber(line).size();

if (
validateNegativeNumber(count)
||
validateLottoLength(count)
||
separateNumber(line).stream().distinct().count() != 6
) {
throw new IllegalArgumentException();
}

return separateNumber(line);
}

public int setBonusNumber(ArrayList<Integer> winningNumbers) {
System.out.println("\n보너스 볼을 입력해 주세요");
Scanner scanner = new Scanner(System.in);
int bonusNumber = scanner.nextInt();

winningNumbers.add(bonusNumber);

if (winningNumbers.stream().distinct().count() != 7) {
throw new IllegalArgumentException("보너스 숫자는 중복이 불가능합니다.");
}
return bonusNumber;
}

public int setManualCount() {
System.out.println("\n수동으로 구매할 로또 수를 입력해 주세요.");
Scanner scanner = new Scanner(System.in);

int count = scanner.nextInt();

if (validateNegativeNumber(count)) {
throw new IllegalArgumentException();
}
return count;

}

public ArrayList<Integer> setManualNumber() {
Scanner scanner = new Scanner(System.in);

String line = scanner.nextLine();

return separateNumber(line);
}

public ArrayList<Integer> separateNumber(String raw) {
String[] numberStrings = raw.split(", ");
ArrayList<Integer> numbers = new ArrayList<>();

for (String numberString : numberStrings) {
numbers.add(Integer.parseInt(numberString));
}

return numbers;
}

public boolean validateNegativeNumber(int number) {
return number < 0;
}

public boolean validateLottoLength(int number) {
return number > 6;
}

}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전체적으로 함수 이름하고 변수 이름을 잘 작성하신거 같아요

읽는데 불편하지 않고 바로바로 의미를 알 수 있었습니다.

60 changes: 60 additions & 0 deletions src/main/java/domain/WinningLotto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package domain;

import java.util.ArrayList;
import java.util.Arrays;

public class WinningLotto {
public ArrayList<Integer> winningCount = new ArrayList<>(Arrays.asList(0, 0, 0, 0, 0));

private int checkLotto(ArrayList<Integer> lotto, ArrayList<Integer> winningNumbers) {
int count = 0;

for (int winningNumber : winningNumbers) {

if (lotto.contains(winningNumber)) {
count++;
}
}

return count;
}

private void addWinningCount(ArrayList<Integer> totalLotto, int count, int bonusNumber) {

if (count == 3) {
winningCount.set(0, winningCount.get(0) + 1);
return;
}
if (count == 4) {
winningCount.set(1, winningCount.get(1) + 1);
return;
}
if (count == 5) {
addBonusCount(totalLotto, bonusNumber);
return;
}
if (count == 6) {
winningCount.set(4, winningCount.get(4) + 1);
}
}

private void addBonusCount(ArrayList<Integer> lotto, int bonusNumber) {
if (lotto.contains(bonusNumber)) {
winningCount.set(3, winningCount.get(3) + 1);
return;
}

winningCount.set(2, winningCount.get(2) + 1);
}

public void totalCheckLotto(ArrayList<ArrayList<Integer>> totalLottes, ArrayList<Integer> winningNumbers, int bonusNumber) {
for (ArrayList<Integer> totalLotto : totalLottes) {
addWinningCount(totalLotto, checkLotto(totalLotto, winningNumbers), bonusNumber);
}
}

public double calculateRate(int money) {
return (double) (WinningNumbers.findByIndex(0) * winningCount.get(0) + WinningNumbers.findByIndex(1) * winningCount.get(1) + WinningNumbers.findByIndex(2) * winningCount.get(2) + WinningNumbers.findByIndex(3) * winningCount.get(3) + WinningNumbers.findByIndex(4) * winningCount.get(4)) / money;
}
Comment on lines +56 to +58

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 for 문을 사용해서 계산하는게 더 좋을거 같습니다.

}

28 changes: 28 additions & 0 deletions src/main/java/domain/WinningNumbers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package domain;

public enum WinningNumbers {
FIFTH(5000),
FOURTH(50000),
THIRD(1500000),
SECOND(30000000),
FIRST(2000000000);

private final int amount;

WinningNumbers(int amount) {
this.amount = amount;
}

public int amount() {
return amount;
}

public static int findByIndex(int index) {
if (index >= 0 && index < values().length) {
return values()[index].amount();
}

throw new IllegalArgumentException();
}

}
34 changes: 34 additions & 0 deletions src/main/java/view/Print.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package view;

import domain.WinningNumbers;

import java.util.ArrayList;

public class Print {

// 1~6개 일치하는 갯수
public void printPurchasedLottoCount(int manualCount, ArrayList<ArrayList<Integer>> totalLottos) {
System.out.printf("\n수동으로 %d장, 자동으로 %d개를 구매했습니다.\n", manualCount, totalLottos.size() - manualCount);
for (ArrayList<Integer> totalLotto : totalLottos) {
System.out.println(totalLotto);
}

// for
// System.out.printf("%d개 일치 (%d원)- %d개", );
}

public void printWinningCount(ArrayList<Integer> winningCount, double rate) {
System.out.println("\n당첨 통계");
System.out.println("---------");

System.out.printf("3개 일치 (%d원)- %d개\n", WinningNumbers.findByIndex(0), winningCount.get(0));
System.out.printf("4개 일치 (%d원)- %d개\n", WinningNumbers.findByIndex(1), winningCount.get(1));
System.out.printf("5개 일치 (%d원)- %d개\n", WinningNumbers.findByIndex(2), winningCount.get(2));
System.out.printf("5개 일치, 보너스 볼 일치(%d원) - %d개\n", WinningNumbers.findByIndex(3), winningCount.get(3));
System.out.printf("6개 일치 (%d원)- %d개\n", WinningNumbers.findByIndex(4), winningCount.get(4));

System.out.printf("총 수익률은 %.2f입니다.\n", rate);

}
Comment on lines +20 to +32

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 저도 뭐가 좋은지 잘 모르겠습니다.

for문을 이용하여 System.out.print()의 사용을 줄일지,
아니면 가독성을 위해 하나하나 전개할지는 아직도 고민이 있네요


}
Comment on lines +33 to +34

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주요 함수마다의 단위테스트가 있으면 더 좋을거 같습니다.

프로그램의 크기가 커짐에 따라 디버깅을 위해 매 프로그램을 재 실행 시키는데에는 많은 시간이 소요된다고 합니다.

각 하나의 함수마다 경우의 수를 고려해서 테스트 하게되면 이러한 부담을 줄일수 있다고 합니다.