Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ dependencies {
implementation 'org.mockito:mockito-inline:3.12.4'
implementation 'org.assertj:assertj-core:3.21.0'
implementation 'org.junit.jupiter:junit-jupiter:5.8.1'

}

java {
Expand Down
114 changes: 114 additions & 0 deletions src/main/java/controller/LottoController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package controller;

import domain.*;
import view.*;


import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;




public class LottoController {
private static final int TICKET_PRICE = 1000;//로또 개당 가격
private static final int PERCENTAGE = 100;//추후 성공률 계산에 이용
Copy link
Member

Choose a reason for hiding this comment

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

상수를 따로 지정해둔 부분이 좋은 것 같습니다! 그런데 클래스를 따로 만들어서 상수들을 모아두는 것도 좋을 것 같아요

Copy link
Author

Choose a reason for hiding this comment

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

수정하겠습니다!


private static PlayerLottoAmount playerLottoAmount;//금액을 받고 로또를 할 수 있는 금액인지 적합성 검사 후 발행할 로또 개수
//정해줌
private static List<Integer> lotto = new ArrayList<>();
private static List<Lotto> lottoList;//로또들을 발행한 개수 만큼 리스트에 저장
private static WinningResult winningResult;//당첨 로또 번호 6개와 와 보너스 번호 1개를 가지고 있는 객체, 추후 가지고 있는
//로또(리스트)들과 당첨 로또 간의 비교를 한 후 Ranking enum 반환 할 예정
public void run() {
start();
return;
}
public void start(){
int ticketCount = inputPlayerAmount();//발행할 로또 개수
OutputView.printTicketCount(ticketCount);//로또 개수 출략
lottoList = makeLottoList(ticketCount);//로또 개수 만큼의 리스트 배열 생성
winningResult = validateBonus();
lottoResult(lottoList, winningResult, ticketCount);


}
public int inputPlayerAmount(){
playerLottoAmount = new PlayerLottoAmount(InputView.inputPlayerAmount());
return playerLottoAmount.calculateLottoCount();

}
public WinningResult validateBonus(){
Lotto lotto = new Lotto(InputView.inputLottoWinningNum());
List<Integer>winningList = lotto.getLottoNumbers();
int ball = InputView.inputBonusNumber();
lotto.validateBonusNumber(winningList, ball);


return new WinningResult(lotto, ball);

}


public List<Lotto>makeLottoList(int ticketCount){
lottoList = new ArrayList<>();
for(int i = 0; i < ticketCount; i++){
lottoList.add(makeLotto());//로또 개수만큼 로또 내부 리스트 생성(6개) 후 해당 로또를 lottoList에 저장함

}
return lottoList;//저장 후 결과 값 반환
}

private static Lotto makeLotto(){//로또 만드는 과정은 외부에서 접근하지 못하도록(랜덤하게 made) private 접근 제한자 사용
LottoNumbers lottoNumbers = new LottoNumbers();
lotto = lottoNumbers.setRandomLottos();//랜덤하게 로또 만들어 리스트 형태로 반환해 lotto에 넘겨줌
System.out.println(lotto);
return new Lotto(lotto);
}

public void lottoResult(List<Lotto>lottoList, WinningResult winningResult, int ticketCount){
Map<Ranking, Integer>result = setResult();//map 초기화 작업 진행 key에는 Ranking values() 각각 넣고 value는 0으로 초기화
Ranking r;

OutputView.printSuccessResult();
for(int i = 0; i < lottoList.size(); i++){
r = winningResult.match(lottoList.get(i));//lottoList에 들어있는 로또 하나씩을 꺼내서 당첨 로또와 유사성 비교 후
//적절한 Ranking Enum 객체를 반환해주는 역할 수행
result.put(r, result.get(r) + 1);//헤당 enum 객체와 그 수량을 하나 증가시켜서 map에 put해줌
}
printResult(result);//결과를 map으로 출력
printEarningRate(result, ticketCount);//수익률 계산하는 메서드 수행


}

public void printResult(Map<Ranking, Integer> result){
for(int i = Ranking.values().length -1; i >= 0; i--){//3~6순으로 해야되므로 인덱스 역순으로 출력하게 작성
Ranking.values()[i].printMessage(result.get(Ranking.values()[i]));//헤당 enum객체의 정보 출력
}
}

Choose a reason for hiding this comment

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

출력 함수를 컨트롤러에 만들어 놓으신 이유가 있을까요

public void printEarningRate(Map<Ranking, Integer>result, int ticketCount){
double percent = 0.0;

for(Ranking r : result.keySet()){
percent += ((double)((r.getWinningAmount() * result.get(r))*PERCENTAGE)
/ (TICKET_PRICE * ticketCount));


}
OutputView.printRevenueRate(percent);


}
public Map<Ranking, Integer>setResult(){
Map<Ranking, Integer>result = new LinkedHashMap<>();
for(Ranking r : Ranking.values()){
result.put(r, 0);
}
return result;

}

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

import java.util.List;

public class Lotto {
private static final int MIN_NUMBER = 1;
private static final int MAX_NUMBER = 45;
private final List<Integer> numbers;

public Lotto(List<Integer> numbers) {
validate(numbers);//로또 번호 개수가 6개로 정상적으로 들어왔는지 여부 확인
validateRange(numbers);//1~45까지의 값이 있나 확인
this.numbers = numbers;//검사 통과하면 numbers라는 리스트 객체에 저장
}

public List<Integer> getLottoNumbers(){//로또 리스트 반환
return numbers;
}

public boolean containNumber(int number){//로또 리스트에 해당 숫자가 있는지 검사할 수 있는 메서드
return numbers.contains(number);
}

Choose a reason for hiding this comment

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

이거 굳이 필요 없어 보이는데 쓰신 이유가 있나요? 그냥 contains 써도 똑같은 거 아닌가요??

public int countMatch(Lotto winningLotto){//winningLotto에 들어있는 로또 리스트 객체와 확인하고자 하는 로또
//비교 후 같은 정수가 있으면 값을 증가시켜 반환
return (int)numbers.stream().filter(w -> winningLotto.numbers.contains(w)).count();
}


private void validate(List<Integer> numbers) {
if (numbers.size() != 6) {
throw new IllegalArgumentException();
}
}
private void validateRange(List<Integer> numbers) {
for(int i = 0; i < numbers.size(); i++){
if(numbers.get(i) < MIN_NUMBER || numbers.get(i) > MAX_NUMBER){
throw new IllegalArgumentException();
}
}
}

public static void validateBonusNumber(List<Integer> numbers, int bonusNumber) {
//추후 당첨 로또의 6개의 로또 번호와 1개의 보너스 번호에서 보너스 변호와 로또 번호가 겹치는게 있는지 확인하기 위한 매서드
if (numbers.contains(bonusNumber)) {
throw new IllegalArgumentException();
}
}


}

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



import org.kokodak.Randoms;

import java.util.Collections;
import java.util.List;


public class LottoNumbers {
private static final int CNT_LOTTO_NUMBER = 6;
private static final int MIN_LOTTO_NUMBER = 1;
private static final int MAX_LOTTO_NUMBER = 45;

private static List<Integer> lottoNumberList;
public static List<Integer> setRandomLottos(){
lottoNumberList = Randoms.pickUniqueNumbersInRange(MIN_LOTTO_NUMBER, MAX_LOTTO_NUMBER, CNT_LOTTO_NUMBER);
//해당 범위내 값에서 CNT만큼 증복되지 않는 로또 번호 가져와 리스트 형태로 반환해줌
Collections.sort(lottoNumberList);//오름차순 정렬 위함
return lottoNumberList;
}

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

public class PlayerLottoAmount {
private static final int Lotto_Min_Amount = 1000;//로또 한개 당 가격
private final int amount;

public PlayerLottoAmount(String amount){
int amountNum = changeToInt(amount);
validateAmount(amountNum);
validateNum(amountNum);
this.amount = amountNum;
}
public int changeToInt(String amount){
return Integer.parseInt(amount);
}
public int calculateLottoCount() {//발행할 로또 개수 반환
return amount / Lotto_Min_Amount;
}

public void validateAmount(int amountNum){//1000보다 작으면 로또 못삼(예외 처리)
if(amountNum < Lotto_Min_Amount){
throw new IllegalArgumentException();
}

}

Choose a reason for hiding this comment

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

이 함수는 PlayerLottoAmount 클래스 내부에서만 쓰는 것 같은데 접근지정자를 private로 바꾸는 게 어떨까요?


public void validateNum(int amountNum){//1000으로 안나누어지면 오류
if(amountNum % Lotto_Min_Amount != 0){
throw new IllegalArgumentException();
}
}

Choose a reason for hiding this comment

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

이 함수도 마찬가지로 접근지정자를 private로 바꾸는 게 어떨까요


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

import view.OutputView;

public enum Ranking {
FIRST(6, 2_000_000_000, "6개 일치 (2,000,000,000원) - "), // 1등
SECOND(5, 30_000_000, "5개 일치, 보너스 볼 일치 (30,000,000원) - "), // 2등
THIRD(5, 1_500_000, "5개 일치 (1,500,000원) - "), // 3등
FOURTH(4, 50_000, "4개 일치 (50,000원) - "), // 4등
FIFTH(3, 5_000, "3개 일치 (5,000원) - "), // 5등
MISS(0, 0, "");//3개 미만 맞으면 꽝

private int countOfMatch;
private int winningAmount;
private String message;

Ranking(int countOfMatch, int winningAmount, String message){
this.countOfMatch = countOfMatch;
this.winningAmount = winningAmount;
this.message = message;
}
private static final int WINNING_MIN_COUNT = 3;
public static Ranking valuesOf(int countOfMatch, boolean bonusCheck){
if(countOfMatch < WINNING_MIN_COUNT){
return MISS;
}
if(SECOND.matchCount(countOfMatch) && bonusCheck){
return SECOND;
}
for(Ranking rank : values()){
if(rank.matchCount(countOfMatch) && rank != SECOND){
return rank;
}
}
throw new IllegalArgumentException();
}

public int getCountOfMatch(){
return countOfMatch;
}
public int getWinningAmount(){
return winningAmount;
}

public void printMessage(int countOfMatch){
if(this != MISS){
OutputView.printSuccessMessage(message, countOfMatch);
}
}

private boolean matchCount(int countOfMatch) {
return this.countOfMatch == countOfMatch;
}




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

public class WinningResult {
private final Lotto lotto;
private final int bonus;
public WinningResult(Lotto lotto, int bonus){
this.lotto = lotto;
this.bonus = bonus;
}
public Ranking match(Lotto playerNumber){
int countOfMatch = playerNumber.countMatch(lotto);//각 로또들과 당첨 로또 비교해 몇개의 숫자 맞는지 반환
boolean bonusCheck = playerNumber.containNumber(bonus);//보너스 번호를 맞았는지 여부 boolean형태로 반환
return Ranking.valuesOf(countOfMatch, bonusCheck);//해당 정보들 가지고 Ranking Enum의 객체와 매치시키게 됨
}
}
5 changes: 4 additions & 1 deletion src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package lotto;

import controller.LottoController;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
LottoController lottoController = new LottoController();
lottoController.run();
}
}
20 changes: 0 additions & 20 deletions src/main/java/lotto/Lotto.java

This file was deleted.

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



import org.kokodak.Console;

import java.util.ArrayList;
import java.util.List;

public class InputView {
private static final String INPUT_LOTTO_AMOUNT = "구입금액을 입력해 주세요.";
private static final String INPUT_LOTTO_WINNING = "당첨 번호를 입력해 주세요.";
private static final String INPUT_BONUS_NUMBER = "보너스 번호를 입력해 주세요.";

public static List<Integer> winningNumberList;

public static String inputPlayerAmount(){
System.out.println(INPUT_LOTTO_AMOUNT);
return Console.readLine();
}

public static List<Integer> inputLottoWinningNum(){
System.out.println(INPUT_LOTTO_WINNING);
return numberList(Console.readLine());
}
public static int inputBonusNumber() {
System.out.println(INPUT_BONUS_NUMBER);
return Integer.parseInt(Console.readLine());
}
public static List<Integer>numberList(String winningNumber){
String[]result = winningNumber.split(",");
winningNumberList = new ArrayList<>();
for(int i = 0; i < result.length; i++){
winningNumberList.add(convertToInt(result[i]));
}
return winningNumberList;
}
public static int convertToInt(String s){

return Integer.parseInt(s);
}






}
Loading