-
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
[Lev1][미션3] 블랙잭 1단계 누누 #4
base: main
Are you sure you want to change the base?
Changes from 51 commits
3e14a55
34967de
3229c65
ca9d522
712e585
0568cd9
ce6262d
4caf176
50d04d4
8d1eb0c
ce1da35
1bb7e5c
7ab51e7
7a32bdd
1988ae4
56cc008
14a6b65
b3a5c0a
f7bb0df
5fe1153
88d03cb
ec2321a
021977d
471b570
b395c23
5f69d94
79ca7fb
d1538e2
c0524c2
190e64d
6fe316c
f1e962e
5756fe4
efbd27b
8bab4ba
d59c109
7ea7726
83422e7
fc63956
b4c7d49
6c0d203
2655498
35df4c6
76257bd
51446dd
f46b378
941cfb0
5504da4
909b264
f8adcb0
186197e
f4b57fe
4764a15
2ac0fa0
5bb124d
a9220a3
044ec19
c9a0d41
41503ae
72130a7
1594d05
2fe6d38
eff7295
6c2a105
0cd0732
ad763ee
6243a34
cf67ed5
a3f6ac2
be6dfaa
8982d6b
8323c9c
a1ee961
3da8a8d
bdb25bf
6cbc719
cf77fdf
4e903c7
52b23ca
a9bfb31
2a2c35e
9b7182e
ea05169
8021c0a
420321d
60f5105
6528777
9907bc6
c68cb0d
c56db90
9dbe90f
c769a1e
11c1db1
23c3493
62326fc
dfba760
d1f62ef
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 |
---|---|---|
|
@@ -5,3 +5,79 @@ | |
## 우아한테크코스 코드리뷰 | ||
|
||
- [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) | ||
|
||
```mermaid | ||
graph TD | ||
의존성그래프 | ||
BlackJackGame --> Players | ||
BlackJackGame --> Deck | ||
BlackJackGame --> Dealer | ||
|
||
Players --> Dealer | ||
Dealer --> Player | ||
|
||
Participant --> CardPocket | ||
Dealer --> Participant | ||
Player --> Participant | ||
|
||
Players --> Player | ||
Player --> Name | ||
CardPocket --> Card | ||
|
||
Deck --> Card | ||
Card --> Shape | ||
Card --> Symbol | ||
``` | ||
|
||
# 기능구현 목록 | ||
|
||
## UI | ||
|
||
1. 입력 | ||
|
||
- 참여할 사람을 입력한다 | ||
- List<String>으로 변환 및 반환한다 | ||
- | ||
|
||
## 도메인 | ||
|
||
1. Deck | ||
- [x] 카드를 생성한다 | ||
- [x] 총 52장 | ||
- [x] Shape마다 13장을 출력 | ||
- [x] 카드를 나눠준다 | ||
|
||
2. BlackJack | ||
- 딜러와 플레이어에게 카드를 2장씩 나눠준다. | ||
-- 카드를 나눠준다 | ||
3. Participant | ||
- [x] 21 이상인지 확인하고 | ||
- [x] 21 이상이라면, | ||
- [x] 블랙잭인지 확인한다 = 받을 수 없음 | ||
- [x] BURST인지 확인한다 = 받을 수 없음4 | ||
- [x] 현재 점수를 숫자 형태로 반환한다 | ||
- [x] 현재 카드를 반환한다 | ||
4. Player | ||
- [x] 21 미만이면, 받을 수 있다는 boolean | ||
Comment on lines
+42
to
+61
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. 도메인 하나 하나에 대해 세세하게 README가 잘 작성 되어있네 👍 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. 더 열심히 적는다...? |
||
5. Dealer | ||
- [x] 16 이하이면, 받을 수 있따는 boolean | ||
6. CardPocket | ||
- [x] 카드의 Symbol 점수를 계산한다.(ScoreCalculator 역할) | ||
- 카드반환 한다 | ||
- [x] 카드 계산 총합 반환 | ||
7. Shape | ||
- [x] enum 형태로 하트, 스페이스, 클로버, 다이아를 저장한다 | ||
8. Symbol | ||
- [x] a=1 2-9, j,q,k =10 | ||
- [x] value는 int 형으로 저장한다 | ||
9. Card | ||
- [x] Shape와 Symbol을 저장하는 자료구조 | ||
|
||
10. Players | ||
- [x] 플레이어 이름 중복 | ||
- [x] 플레이어 수 1명이상, 5명 이하 | ||
- [x] 플레이어에게 카드 나눠주기 | ||
- [x] 플레이어의 draw여부 알기 | ||
11. Name | ||
- [x] isBlank 체크 | ||
- [x] 100자 이하 체크 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package blackjack; | ||
|
||
import blackjack.controller.BlackJackController; | ||
import blackjack.domain.ShuffledDeckFactory; | ||
import blackjack.view.InputView; | ||
import blackjack.view.OutputView; | ||
|
||
public class Application { | ||
|
||
public static void main(final String[] args) { | ||
final BlackJackController blackJackController = new BlackJackController(new InputView(), new OutputView()); | ||
blackJackController.play(new ShuffledDeckFactory()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package blackjack.controller; | ||
|
||
import static blackjack.controller.Repeater.repeatUntilNoException; | ||
|
||
import blackjack.domain.Dealer; | ||
import blackjack.domain.Deck; | ||
import blackjack.domain.DeckFactory; | ||
import blackjack.domain.Players; | ||
import blackjack.dto.CardsScoreDto; | ||
import blackjack.dto.FinalResultDto; | ||
import blackjack.dto.InitialCardDto; | ||
import blackjack.dto.PlayerCardDto; | ||
import blackjack.dto.PlayerCardsScoreDto; | ||
import blackjack.view.DrawCommand; | ||
import blackjack.view.InputView; | ||
import blackjack.view.OutputView; | ||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
|
||
public class BlackJackController { | ||
|
||
private final InputView inputView; | ||
private final OutputView outputView; | ||
|
||
public BlackJackController(final InputView inputView, final OutputView outputView) { | ||
this.inputView = inputView; | ||
this.outputView = outputView; | ||
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. inputView와 outputVIew를 controller외부에서 주입시켜주는 이유가 따로 있나요?? (순수한 궁금증) |
||
} | ||
|
||
public void play(final DeckFactory deckFactory) { | ||
final Players players = createPlayers(); | ||
final Dealer dealer = new Dealer(); | ||
final Deck deck = deckFactory.generate(); | ||
|
||
distributeInitialCard(players, dealer, deck); | ||
printInitialCards(players, dealer); | ||
drawPlayersCards(players, deck); | ||
drawDealerCards(dealer, deck); | ||
players.calculateResult(dealer); | ||
printResult(players, dealer); | ||
} | ||
|
||
private Players createPlayers() { | ||
return repeatUntilNoException( | ||
() -> Players.from(inputView.inputPlayerNames()), outputView::printError); | ||
} | ||
|
||
private void distributeInitialCard(final Players players, final Dealer dealer, final Deck deck) { | ||
players.distributeInitialCards(deck); | ||
dealer.drawCard(deck.removeCard()); | ||
dealer.drawCard(deck.removeCard()); | ||
} | ||
|
||
|
||
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. 필요없는 개행인 것 같아! 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 void printInitialCards(final Players players, final Dealer dealer) { | ||
final InitialCardDto initialCardDto = new InitialCardDto( | ||
dealer.getCards() | ||
.get(0), | ||
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을 상수로 빼는건 어떨까요? |
||
players.findPlayerNameToCards()); | ||
outputView.printInitialCards(initialCardDto); | ||
} | ||
|
||
private void drawPlayersCards(final Players players, final Deck deck) { | ||
for (final String playerName : players.getPlayerNames()) { | ||
drawPlayerCard(playerName, deck, players); | ||
} | ||
} | ||
|
||
private void drawPlayerCard(final String playerName, final Deck deck, final Players players) { | ||
DrawCommand playerInput = DrawCommand.DRAW; | ||
while (players.isDrawable(playerName) && playerInput != DrawCommand.STAY) { | ||
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. 재입력 받는 부분 언제나 고민이 많았는데, |
||
playerInput = repeatUntilNoException( | ||
() -> inputView.inputCommand(playerName), outputView::printError); | ||
drawCard(playerName, deck, players, playerInput); | ||
printPlayerResult(playerName, players); | ||
} | ||
} | ||
|
||
private void drawCard(final String playerName, final Deck deck, final Players players, | ||
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. 근데 파라미터가 4개인게 조금 걸리네요.. 하나만 줄여볼 수 없을까ㅎㅎㅎ |
||
final DrawCommand playerInput) { | ||
if (playerInput == DrawCommand.DRAW) { | ||
players.draw(playerName, deck); | ||
} | ||
} | ||
|
||
private void printPlayerResult(final String playerName, final Players players) { | ||
final PlayerCardDto playerCardDto = new PlayerCardDto(playerName, | ||
players.findCardsByPlayerName(playerName)); | ||
outputView.printCardStatusOfPlayer(playerCardDto); | ||
} | ||
|
||
|
||
private void drawDealerCards(final Dealer dealer, final Deck deck) { | ||
while (dealer.isDrawable()) { | ||
dealer.drawCard(deck.removeCard()); | ||
outputView.printDealerCardDrawMessage(); | ||
} | ||
} | ||
|
||
private void printResult(final Players players, final Dealer dealer) { | ||
printStatusOfGame(dealer, players); | ||
outputView.printFinalResult(new FinalResultDto(dealer.getResult())); | ||
} | ||
|
||
private void printStatusOfGame(final Dealer dealer, final Players players) { | ||
outputView.printFinalStatusOfDealer( | ||
new CardsScoreDto(dealer.getCards(), dealer.currentScore())); | ||
outputView.printFinalStatusOfPlayers(createPlayerCardDto(players)); | ||
} | ||
|
||
private PlayerCardsScoreDto createPlayerCardDto(final Players players) { | ||
final Map<String, CardsScoreDto> playerNameToResult = new LinkedHashMap<>(); | ||
|
||
for (final String playerName : players.getPlayerNames()) { | ||
final CardsScoreDto playerCardDto = new CardsScoreDto( | ||
players.findCardsByPlayerName(playerName), | ||
players.getPlayerScoreByName(playerName) | ||
); | ||
playerNameToResult.put(playerName, playerCardDto); | ||
} | ||
|
||
return new PlayerCardsScoreDto(playerNameToResult); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package blackjack.controller; | ||
|
||
import java.util.function.Consumer; | ||
import java.util.function.Supplier; | ||
|
||
class Repeater { | ||
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. 너무 신기해요 멋지다!!! 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 Repeater() { | ||
} | ||
|
||
static <T> T repeatUntilNoException(final Supplier<T> supplier, | ||
final Consumer<Exception> exceptionHandler) { | ||
T result = null; | ||
while (result == null) { | ||
result = createOutputOrNull(supplier, exceptionHandler); | ||
} | ||
return result; | ||
} | ||
|
||
private static <T> T createOutputOrNull(final Supplier<T> inputSupplier, | ||
final Consumer<Exception> exceptionHandler) { | ||
try { | ||
return inputSupplier.get(); | ||
} catch (final IllegalArgumentException e) { | ||
exceptionHandler.accept(e); | ||
return null; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package blackjack.domain; | ||
|
||
/** | ||
* 도메인 로직상 여러곳에서 사용되는 상수를 관리하기 위한 책임을 가지고 있습니다 | ||
* <p/> | ||
* 많은 클래스가 블랙잭이라는 숫자에 대한 정보를 필요로 하기에 제작되었습니다 | ||
*/ | ||
class BlackJackConstant { | ||
|
||
static final int BLACKJACK = 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. package-private의 적절한 사용 👍 |
||
|
||
private BlackJackConstant() { | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package blackjack.domain; | ||
|
||
/** | ||
* 하나의 카드에 대한 정보를 가지고 있는 자료구조입니다 | ||
*/ | ||
public class Card { | ||
|
||
private final Shape shape; | ||
private final Symbol symbol; | ||
|
||
public Card(final Shape shape, final Symbol symbol) { | ||
this.shape = shape; | ||
this.symbol = symbol; | ||
} | ||
|
||
public boolean isAce() { | ||
return symbol.isAce(); | ||
} | ||
|
||
public int getScore() { | ||
return symbol.getScore(); | ||
} | ||
|
||
public Symbol getSymbol() { | ||
return symbol; | ||
} | ||
|
||
public Shape getShape() { | ||
return shape; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package blackjack.domain; | ||
|
||
import static blackjack.domain.BlackJackConstant.BLACKJACK; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class CardPocket { | ||
|
||
private static final int VALUE_ACE = 10; | ||
private final List<Card> cards; | ||
|
||
private CardPocket(final List<Card> cards) { | ||
validateCardPocket(cards); | ||
this.cards = new ArrayList<>(cards); | ||
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 CardPocket empty() { | ||
return new CardPocket(new ArrayList<>()); | ||
} | ||
|
||
private void validateCardPocket(final List<Card> cards) { | ||
if (cards == null) { | ||
throw new IllegalArgumentException("카드를 입력하지 않았습니다"); | ||
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. 도메인의 관점에서 입력이라는 용어가 어색해보이는데 다른 괜찮은 메시지가 있을까요🤔 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. 고마워! 그냥 null 하지 말라고 적었어 |
||
} | ||
} | ||
|
||
void addCard(final Card card) { | ||
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. package-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. @be-student 알려주세요 제발 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. 내일 말해주는 걸로 ㅋㅋㅋ |
||
cards.add(card); | ||
} | ||
|
||
int calculateScore() { | ||
final int countOfAce = countAce(); | ||
int scoreOfCards = calculateMinimumScore(); | ||
for (int i = 0; i < countOfAce; i++) { | ||
scoreOfCards = calculateAceScore(scoreOfCards); | ||
} | ||
return scoreOfCards; | ||
} | ||
|
||
private int countAce() { | ||
return (int) cards.stream() | ||
.filter(Card::isAce) | ||
.count(); | ||
} | ||
|
||
private int calculateMinimumScore() { | ||
return cards.stream() | ||
.mapToInt(Card::getScore) | ||
.sum(); | ||
} | ||
|
||
private int calculateAceScore(final int score) { | ||
if (score + VALUE_ACE > BLACKJACK) { | ||
return score; | ||
} | ||
return score + VALUE_ACE; | ||
} | ||
|
||
List<Card> getCards() { | ||
return List.copyOf(cards); | ||
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. 생성자 부분에서는 new ArrayList(cards)를 사용하고 해당 부분에서는 List.copyOf를 사용했는데 차이를 둔 이유가 있을까요? 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. 도메인 객체를 넘기면서, 변경되면 안될것 같아서 일부러 저렇게 방어적 복사를 한 느낌? |
||
} | ||
} |
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.
graph TD위에 title 구문을 사용한다면 제목을 붙일 수 있어~
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.
까먹었네 고마워
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.
의존성 그래프 그리기 신기해요!! 좋은거 배워갑니다 ><
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.
mermaid 좋은데요?