-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Step4 - 로또(수동) #3238
base: gisungpark
Are you sure you want to change the base?
Step4 - 로또(수동) #3238
Changes from all commits
f75c148
7ecc77f
9145800
c2b5569
900ca93
0a50198
add408b
44bafd3
a18987d
f5830e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,83 @@ | ||
package step2.controller; | ||
|
||
import step2.domain.LottoTicket; | ||
import step2.domain.LottoGames; | ||
import step2.domain.LottoResultReport; | ||
import step2.domain.*; | ||
import step2.view.InputView; | ||
import step2.view.ResultView; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class LottoGameController { | ||
|
||
private static final int LOTTO_TICKET_PRICE = 1000; | ||
private LottoGames lottoGames = new LottoGames(); | ||
|
||
public void playLottoGame() { | ||
lxxjn0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Money balance = new Money(InputView.readMoney()); | ||
|
||
int money = InputView.readAmountOfPurchase(); | ||
int gameCount = lottoGames.calculateBuyingTicketCount(money); | ||
ResultView.printMessage(gameCount + "개를 구매했습니다."); | ||
if (gameCount == 0) { | ||
List<LottoTicket> manualLottoTickets = buyManualTickets(balance); | ||
List<LottoTicket> automaticLottoTickets = getBuyAutomaticTickets(balance); | ||
|
||
ResultView.printNumberOfTickets(manualLottoTickets.size(), automaticLottoTickets.size()); | ||
if (manualLottoTickets.size() == 0 && automaticLottoTickets.size() == 0) { | ||
return; | ||
} | ||
ResultView.printLottoTicket(automaticLottoTickets); | ||
LottoTicket winningTicket = readWinningTicket(); | ||
LottoNo bonusNumber = LottoNo.of(InputView.readBonusNumber()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 축약어는 최대한 지양하면 좋을 것 같아요!! LottoNumber라는 이름이 좀 더 직관적이고 가독성이 더 좋을 것 같아요!! |
||
|
||
printResultStatistic(getLottoResultReport(manualLottoTickets, automaticLottoTickets, winningTicket, bonusNumber)); | ||
} | ||
|
||
private List<LottoTicket> buyManualTickets(Money money) { | ||
int manualTicketCount = getManualTicketCount(money); | ||
money.pay(manualTicketCount * LOTTO_TICKET_PRICE); | ||
|
||
ResultView.printMessage("수동으로 구매할 번호를 입력해 주세요"); | ||
List<LottoTicket> manualLottoTickets = new ArrayList<>(manualTicketCount); | ||
for (int i = 0; i < manualTicketCount; i++) { | ||
LottoTicket lottoTicket = lottoGames.toLottoTicket(InputView.readManualTicketNumbers()); | ||
manualLottoTickets.add(lottoTicket); | ||
} | ||
return manualLottoTickets; | ||
} | ||
|
||
List<LottoTicket> lottoTickets = lottoGames.buyLottoGame(gameCount); | ||
ResultView.printLottoTicket(lottoTickets); | ||
LottoTicket winningTicket = lottoGames.readWinningNumber(InputView.readWinningNumbers()); | ||
int bonusNumber = InputView.readBonusNumber(); | ||
private int getManualTicketCount(Money money) { | ||
int manualTicketCount = InputView.readCountOfManualTicket(); | ||
int cost = manualTicketCount * LottoCommonValue.DEFAULT_LOTTO_NUMBER_COUNT.value(); | ||
money.pay(cost); | ||
return manualTicketCount; | ||
} | ||
|
||
private List<LottoTicket> getBuyAutomaticTickets(Money money) { | ||
int automaticTicketCount = money.balance() / LOTTO_TICKET_PRICE; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 로직은 getter를 사용해서 값을 가져와서 계산을 하고 있어요!! 이렇게 된다면 값을 객체로 감싼 의미가 조금은 퇴색될 수 있는데 어떻게 바꾸면 좋을까요? |
||
money.pay(automaticTicketCount * LOTTO_TICKET_PRICE); | ||
return lottoGames.buyAutomaticLottoTickets(automaticTicketCount); | ||
} | ||
|
||
private LottoTicket readWinningTicket() { | ||
ResultView.printMessage("지난 주 당첨 번호를 입력해 주세요"); | ||
return lottoGames.toLottoTicket(InputView.readWinningNumbers()); | ||
} | ||
|
||
private void printResultStatistic(LottoResultReport lottoResultReport) { | ||
ResultView.printBlankLine(); | ||
ResultView.printMessage("당첨 통계"); | ||
ResultView.printResultReport(lottoResultReport); | ||
ResultView.printMessage("총 수익률은 " + lottoResultReport.calculateProfit() + "입니다."); | ||
} | ||
|
||
private LottoResultReport getLottoResultReport(List<LottoTicket> manualLottoTickets, | ||
List<LottoTicket> automaticLottoTickets, | ||
LottoTicket winningTicket, LottoNo bonusNumber) { | ||
|
||
LottoResultReport lottoResultReport = new LottoResultReport(); | ||
for (LottoTicket lottoTicket : lottoTickets) { | ||
for (LottoTicket lottoTicket : manualLottoTickets) { | ||
lottoResultReport.recordRank(lottoTicket.checkLottoTicket(winningTicket, bonusNumber)); | ||
} | ||
|
||
ResultView.printResultReport(lottoResultReport); | ||
double profit = lottoResultReport.calculateProfit(gameCount); | ||
ResultView.printMessage("총 수익률은 " + profit + "입니다."); | ||
for (LottoTicket lottoTicket : automaticLottoTickets) { | ||
lottoResultReport.recordRank(lottoTicket.checkLottoTicket(winningTicket, bonusNumber)); | ||
} | ||
return lottoResultReport; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,9 +16,4 @@ public enum LottoCommonValue { | |
public int value() { | ||
return value; | ||
} | ||
|
||
|
||
|
||
|
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package step2.domain; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.stream.IntStream; | ||
|
||
public class LottoNo { | ||
lxxjn0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
private static final int MIN_LOTTO_NUMBER = 1; | ||
private static final int MAX_LOTTO_NUMBER = 45; | ||
|
||
private static final Map<Integer, LottoNo> lottoNumberCache = new HashMap<>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 네이밍도 상수 컨벤션에 맞게 바꾸면 좋을 것 같아요!! |
||
|
||
static { | ||
IntStream.range(MIN_LOTTO_NUMBER, MAX_LOTTO_NUMBER + 1) | ||
.forEach(i -> lottoNumberCache.put(i, new LottoNo(i))); | ||
} | ||
|
||
private int number; | ||
|
||
private LottoNo(int number) { | ||
this.number = number; | ||
} | ||
|
||
public static LottoNo of(int number) { | ||
if (isInvalidNumber(number)) { | ||
throw new IllegalArgumentException("잘못 입력하셨습니다."); | ||
} | ||
return lottoNumberCache.get(number); | ||
} | ||
|
||
private static boolean isInvalidNumber(int number) { | ||
return number < MIN_LOTTO_NUMBER || number > MAX_LOTTO_NUMBER; | ||
} | ||
|
||
public int number() { | ||
return number; | ||
} | ||
lxxjn0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
LottoNo lottoNo = (LottoNo) o; | ||
return number == lottoNo.number; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(number); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,45 +4,43 @@ | |
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
|
||
public class LottoTicket { | ||
|
||
private final List<Integer> lottoTicket; | ||
private final List<LottoNo> lottoTicket; | ||
|
||
public LottoTicket(List<Integer> lottoTicket) { | ||
validInputNumber(lottoTicket); | ||
this.lottoTicket = lottoTicket; | ||
public LottoTicket(List<LottoNo> lottoNumbers) { | ||
validInputNumber(lottoNumbers); | ||
this.lottoTicket = new ArrayList<>(lottoNumbers); | ||
} | ||
|
||
public LottoTicket(Set<Integer> numbers) { | ||
validInputNumber(numbers); | ||
lottoTicket = new ArrayList<>(numbers); | ||
public LottoTicket(Set<LottoNo> lottoNumbers) { | ||
validInputNumber(lottoNumbers); | ||
lottoTicket = new ArrayList<>(lottoNumbers); | ||
} | ||
|
||
private static void validInputNumber(Collection<Integer> numbers) { | ||
if (numbers.size() != LottoCommonValue.DEFAULT_LOTTO_NUMBER_COUNT.value()) { | ||
throw new IllegalArgumentException(numbers + " : 입력한 숫자를 확인해 주세요"); | ||
private static void validInputNumber(Collection<LottoNo> lottoNos) { | ||
if (lottoNos.size() != LottoCommonValue.DEFAULT_LOTTO_NUMBER_COUNT.value()) { | ||
throw new IllegalArgumentException(lottoNos + " : 입력한 숫자를 확인해 주세요"); | ||
} | ||
} | ||
|
||
public boolean isContain(Integer number) { | ||
public boolean isContain(LottoNo number) { | ||
return this.lottoTicket.contains(number); | ||
} | ||
|
||
public Rank checkLottoTicket(LottoTicket winningTicket, int bonusNumber) { | ||
public Rank checkLottoTicket(LottoTicket winningTicket, LottoNo bonusNumber) { | ||
int count = (int) lottoTicket.stream() | ||
.filter(i -> winningTicket.isContain(i)) | ||
.count(); | ||
|
||
if(count == 5 && isContain(bonusNumber)) { | ||
return Rank.SECOND; | ||
} | ||
|
||
return Rank.toPrizeMoney(count); | ||
return Rank.rank(count, isContain(bonusNumber)); | ||
} | ||
|
||
public String printTicket() { | ||
return lottoTicket.toString(); | ||
return lottoTicket.stream() | ||
.map(i -> String.valueOf(i.number())) | ||
.collect(Collectors.joining(",")); | ||
Comment on lines
+42
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 로또 번호들을 리스트로 반환해주고 뷰에서 출력 형식에 맞게 joining을 해서 출력하는 것이 어떨까요?? 이렇게 되면 출력 형식이 바뀔 때 LottoTicket 도메인도 영향을 받을 것 같아요 |
||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package step2.domain; | ||
|
||
import java.util.Objects; | ||
|
||
public class Money { | ||
private int money; | ||
|
||
public Money(int money) { | ||
if (money < 0) { | ||
throw new IllegalArgumentException("잔액은 음수를 가질 수 없습니다."); | ||
} | ||
this.money = money; | ||
} | ||
|
||
public int pay(int cost) { | ||
if (cost > this.money) { | ||
throw new IllegalArgumentException("잔액을 초과하셨습니다."); | ||
} | ||
this.money -= cost; | ||
return 0; | ||
} | ||
Comment on lines
+15
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 0이라는 반환 값이 별다른 의미가 없어보이는데 void 메서드로 만드는 것이 어떨까요? |
||
|
||
public int balance() { | ||
return money; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Money money1 = (Money) o; | ||
return money == money1.money; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(money); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
로또 금액은 비즈니스 영역에 해당하는 값으로 보여지는데 현재 Controller에서 상수로 관리되고 있어요! 적절한 도메인 객체에서 해당 값을 관리하는 것이 어떨까요?