-
Notifications
You must be signed in to change notification settings - Fork 0
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
[로또 main2] 조윤호 제출합니다 #4
base: main2
Are you sure you want to change the base?
Changes from all commits
fe17173
66761c9
85ecc2d
a4f2913
54b297e
2d8b6a1
c8a3902
9852c03
b909ad2
dffd69c
72f238d
e4ee5d6
6710f7a
55db99a
1e073f7
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 |
---|---|---|
@@ -0,0 +1,40 @@ | ||
## 기능 리스트 | ||
|
||
- [ ] 가격 -> 개수 반환 | ||
- [ ] 로또 발행 | ||
- [ ] 총 일치 수, 금액, 수익률 계산 | ||
- [ ] 정답로또 입력받기 | ||
- validation | ||
- 보너스점수 | ||
- [ ] ㅇ | ||
|
||
|
||
PurchaseService | ||
- (금액) -> 개수 // thr | ||
|
||
Enum Prize | ||
- 출력문구 matches bonus reward | ||
|
||
LottoService | ||
|
||
|
||
LottoBundle | ||
- 로또 수 | ||
- LottoStatus list | ||
- | ||
- Lotto 정답로또 | ||
- 보너스번호 | ||
- | ||
|
||
LottoStatus | ||
- Lotto | ||
- 일치 수 | ||
- 보너스 여부 | ||
- (정답로또, 보너스) -> 일치 수 , 보너스 여부 | ||
- | ||
|
||
Lotto | ||
- 랜덤로또 발행 | ||
- 정답로또 생성 | ||
- | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,10 @@ | ||
package lotto; | ||
|
||
import lotto.lotto.LottoService; | ||
|
||
public class Application { | ||
public static void main(String[] args) { | ||
// TODO: 프로그램 구현 | ||
LottoService lottoService = new LottoService(); | ||
lottoService.run(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package lotto.lotto; | ||
|
||
public class Bonus { | ||
private final int bonusNumber; | ||
|
||
private Bonus(int bonusNumber) { | ||
this.bonusNumber = bonusNumber; | ||
} | ||
|
||
public static Bonus from(int num, Lotto lotto) { | ||
lotto.validateBonusNumber(num); | ||
return new Bonus(num); | ||
} | ||
|
||
public int getBonusNumber() { | ||
return bonusNumber; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package lotto.lotto; | ||
|
||
|
||
import lotto.lotto.lottoCreator.LottoCreator; | ||
import lotto.lotto.lottoCreator.RandomLottoCreator; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Comparator; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public class Lotto { | ||
private final static int LOTTO_NUM_LENGTH = 6; | ||
private final static int LOTTO_MIN_NUM = 1; | ||
private final static int LOTTO_MAX_NUM = 45; | ||
private final List<Integer> numbers; | ||
|
||
public Lotto(List<Integer> numbers) { | ||
this.numbers = numbers; | ||
} | ||
|
||
public static Lotto from(LottoCreator lottoCreator) { | ||
return lottoCreator.getLotto( | ||
LOTTO_MIN_NUM, | ||
LOTTO_MAX_NUM, | ||
LOTTO_NUM_LENGTH | ||
); | ||
} | ||
|
||
public Prize comparePrize(Lotto winningLotto, int bonus) { | ||
List<Integer> list = new ArrayList<>(); | ||
list.addAll(numbers); | ||
list.addAll(winningLotto.numbers); | ||
int matches = list.size() - (new HashSet<>(list)).size(); | ||
boolean isBonus = numbers.contains(bonus); | ||
|
||
Prize prize = Prize.NONE; | ||
for (Prize p : Prize.values()) { | ||
if ( | ||
p.isPrized() && | ||
p.getMatchNum() <= matches && | ||
p.getGrade() <= prize.getGrade() | ||
) { | ||
if (p.isBonus() && !isBonus) // 보너스 true인 경우 isBonus 확인한다. | ||
continue; | ||
prize = p; | ||
} | ||
} | ||
return prize; | ||
} | ||
|
||
public void validateBonusNumber(int bonus) { | ||
validateBonusDuplicateWithLotto(bonus); | ||
validateBonusRange(bonus); | ||
} | ||
|
||
public boolean contains(int num) { | ||
return numbers.contains(num); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return numbers.toString(); | ||
} | ||
|
||
public List<Integer> getNumbers() { | ||
return numbers; | ||
} | ||
|
||
|
||
private void validateBonusDuplicateWithLotto(int bonus) { | ||
if (numbers.contains(bonus)) | ||
throw new IllegalArgumentException("[ERROR] 보너스 번호와 당첨 번호에 중복이 있습니다."); | ||
|
||
} | ||
|
||
private void validateBonusRange(int bonus) { | ||
if (bonus < LOTTO_MIN_NUM || bonus > LOTTO_MAX_NUM) | ||
throw new IllegalArgumentException("[ERROR] 보너스 번호와 당첨 번호에 중복이 있습니다."); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package lotto.lotto; | ||
|
||
import lotto.lotto.lottoCreator.LottoCreator; | ||
import lotto.lotto.model.StatusOutputModel; | ||
import lotto.purchase.PurchaseService; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class LottoBundle { | ||
private final List<Lotto> lottos; | ||
private final Lotto winningLotto; | ||
private final Bonus bonus; | ||
|
||
private LottoBundle(Builder builder) { | ||
this.lottos = builder.lottos; | ||
this.winningLotto = builder.winningLotto; | ||
this.bonus = builder.bonus; | ||
} | ||
|
||
public static class Builder { | ||
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. 빌더 패턴을 사용하신 이유가 궁금해요! |
||
private List<Lotto> lottos = new ArrayList<>(); | ||
private Lotto winningLotto; | ||
private Integer bonusNumber; | ||
private Bonus bonus; | ||
|
||
public Builder() {} | ||
|
||
/** | ||
* lottoCreators만큼 새로운 로또 생성하기 | ||
*/ | ||
public Builder createLottos(List<LottoCreator> lottoCreators) { | ||
for (LottoCreator creator : lottoCreators) { | ||
Lotto lotto = Lotto.from(creator); | ||
lottos.add(lotto); | ||
} | ||
return this; | ||
} | ||
|
||
/** | ||
* 당첨번호 저장하기 | ||
*/ | ||
public Builder winningLotto(LottoCreator creator) { | ||
Lotto lotto = Lotto.from(creator); | ||
this.winningLotto = lotto; | ||
if (bonusNumber != null) | ||
bonus = Bonus.from(bonusNumber, winningLotto); | ||
return this; | ||
} | ||
|
||
/** | ||
* 보너스번호 저장하기 | ||
*/ | ||
public Builder bonus(int bonusNumber) { | ||
this.bonusNumber = bonusNumber; | ||
if (winningLotto != null) | ||
this.bonus = Bonus.from(bonusNumber, winningLotto); | ||
return this; | ||
} | ||
|
||
private void validateBonusNumber(List<Integer> numbers, int num){ | ||
if (numbers.contains(num)) | ||
throw new IllegalArgumentException("[ERROR] 보너스 번호와 당첨 번호에 중복이 있습니다."); | ||
} | ||
Comment on lines
+62
to
+65
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. 사용되지 않는 메소드는 삭제해주세요! |
||
|
||
public LottoBundle build() { | ||
return new LottoBundle(this); | ||
} | ||
} | ||
|
||
/** | ||
* 로또 출력하기 | ||
*/ | ||
public List<List<Integer>> getLottosNumList() { | ||
List<List<Integer>> lottoNumbers = new ArrayList<>(); | ||
for (Lotto lotto : lottos) | ||
lottoNumbers.add(lotto.getNumbers()); | ||
return lottoNumbers; | ||
} | ||
|
||
/** | ||
* 당첨 통계 출력하기 | ||
*/ | ||
public StatusOutputModel getResultStatus() { | ||
Map<Prize, Integer> prizeMap = getPrizeStat(); | ||
int totalreward = getTotalReward(prizeMap); | ||
double rewardPercent = PurchaseService.getRewardPercent(lottos.size(), totalreward); | ||
|
||
StringBuilder sb = new StringBuilder(); | ||
for (Prize prize : Prize.values()) { | ||
if (!prize.isPrized()) continue; | ||
sb.append(prize.getToString()); | ||
sb.append( | ||
String.format(" (%,d원) - %d개", | ||
prize.getReward(), | ||
prizeMap.get(prize) | ||
)); | ||
sb.append("\n"); | ||
} | ||
sb.append(String.format("총 수익률은 %.1f%%입니다.", rewardPercent)); | ||
|
||
return new StatusOutputModel(sb.toString()); | ||
} | ||
|
||
private Map<Prize, Integer> getPrizeStat() { | ||
Map<Prize, Integer> prizeMap = Prize.getInitializedMap(); | ||
for (Lotto lotto : lottos) { | ||
Prize prize = lotto.comparePrize(winningLotto, bonus.getBonusNumber()); | ||
if (prize.isPrized()) | ||
prizeMap.put(prize, prizeMap.get(prize) + 1); | ||
} | ||
return prizeMap; | ||
} | ||
|
||
private int getTotalReward(Map<Prize, Integer> prizeMap) { | ||
int totalReward = 0; | ||
for (Prize prize : Prize.values()) { | ||
if (prizeMap.get(prize) != 0) | ||
totalReward += prize.getReward() * prizeMap.get(prize); | ||
} | ||
return totalReward; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package lotto.lotto; | ||
|
||
import lotto.lotto.lottoCreator.LottoCreator; | ||
import lotto.lotto.lottoCreator.ManualLottoCreator; | ||
import lotto.lotto.lottoCreator.RandomLottoCreator; | ||
import lotto.lotto.model.LottoOutputModel; | ||
import lotto.purchase.PurchaseService; | ||
import lotto.view.UserInput; | ||
import lotto.view.UserOutput; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
public class LottoService { | ||
|
||
public void run() { | ||
LottoBundle.Builder lottoBundleBuilder = new LottoBundle.Builder(); | ||
|
||
// 구입금액 입력받기 | ||
// todo : 구입금액 객체 관리 | ||
int lottoNum = PurchaseService.getLottoNum(getNum(UserInput.getCostInput())); | ||
int manualNum = getNum(UserInput.getManualNumInput()); | ||
if (lottoNum < manualNum) | ||
throw new IllegalArgumentException("[ERROR] 구입 가능한 로또 수를 초과하였습니다."); | ||
|
||
// 자동 로또 | ||
List<LottoCreator> creators = Stream.generate(RandomLottoCreator::from) | ||
.limit(lottoNum - manualNum) | ||
.collect(Collectors.toList()); | ||
Comment on lines
+30
to
+32
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. RandomLottoCreator가 2개 이상 생성되어야 할까요? |
||
// 수동 로또 | ||
if (manualNum != 0) { | ||
List<String> strList = UserInput.getManualLottoInput(manualNum); | ||
for (String input : strList) | ||
creators.add(ManualLottoCreator.from(getNumList(input))); | ||
} | ||
|
||
lottoBundleBuilder.createLottos(creators); | ||
LottoBundle bundle = lottoBundleBuilder.build(); | ||
|
||
// 로또 출력하기 | ||
UserOutput.printLottos( | ||
new LottoOutputModel( | ||
lottoNum - manualNum, manualNum, bundle.getLottosNumList() | ||
)); | ||
Comment on lines
+44
to
+47
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. 출력을 위한 값들을 담고 있는 객체가 정말 필요할까요? |
||
|
||
// 당첨번호 입력받기 | ||
lottoBundleBuilder.winningLotto( | ||
ManualLottoCreator.from(getNumList(UserInput.getLottoInput()))); | ||
|
||
// 보너스번호 입력받기 | ||
lottoBundleBuilder.bonus(getNum(UserInput.getBonusInput())); | ||
bundle = lottoBundleBuilder.build(); | ||
|
||
// 당첨 통계 출력하기 | ||
UserOutput.printResult(bundle.getResultStatus()); | ||
} | ||
|
||
|
||
public int getNum(String input) { | ||
try { | ||
return Integer.parseInt(input); | ||
} catch (NumberFormatException ne) { | ||
throw new IllegalArgumentException("[ERROR] 정수를 입력해주세요."); | ||
} | ||
} | ||
|
||
public List<Integer> getNumList(String input) { | ||
Comment on lines
+62
to
+70
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. 두 메소드는 LottoService 내부에서만 사용되는 것 같습니다. private로 선언해주세요! 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. 해당 메소드에 책임이 너무 많은 것 같아요. 메소드의 책임이 최소화되도록 하면 좋을 것 같아요! |
||
List<String> strList = new ArrayList<>( | ||
Arrays.asList( | ||
input.split(",") | ||
) | ||
); | ||
|
||
// "," 개수를 이용해서 배열의 길이가 올바르게 입력되었는지 확인한다. | ||
int commas = input.length() - input.replace(String.valueOf(","), "").length(); | ||
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.
|
||
if (commas + 1 != strList.size()) | ||
throw new IllegalArgumentException("[ERROR] 정수와 ,로 이루어진 배열을 입력해주세요."); | ||
Comment on lines
+78
to
+80
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. 구분자에 대한 검증같은데, 예외 메시지가 어색한 것 같습니다. |
||
|
||
List<Integer> numList = strList.stream() | ||
.map(s -> { | ||
try { | ||
return Integer.parseInt(s); | ||
} catch (NumberFormatException ne) { | ||
throw new IllegalArgumentException("[ERROR] 정수와 ,로 이루어진 배열을 입력해주세요."); | ||
} | ||
Comment on lines
+84
to
+88
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. 문자열을 정수로 바꿔주는 |
||
}).collect(Collectors.toList()); | ||
|
||
return numList; | ||
} | ||
|
||
} |
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.
41~43 라인을 하나의 메소드로 뽑으면 가독성도 좋아지고, 메소드 이름으로 어떤 조건인지 표현 가능할 것 같습니다!