-
Notifications
You must be signed in to change notification settings - Fork 389
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
[스티치] 블랙잭 1단계 미션 코드리뷰 제출합니다 #26
Changes from all commits
e8dba5f
370dc4c
8c679ad
7c3b189
97c5212
557148b
2e25261
45e8ff6
89c0b31
bf5e0bf
7bf52b0
b8198b3
a127551
1596767
c60f13d
3fe3055
b5f8eee
5974bf7
fcef622
577558a
625ee56
c4b112f
6cbf3ef
c2581d2
f8397a4
a2d19cd
18742a3
4a9d635
4dc08f7
aa986da
709cee4
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 |
---|---|---|
|
@@ -18,4 +18,4 @@ bin/ | |
.idea | ||
*.iws | ||
*.iml | ||
*.ipr | ||
*.iprtest\ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,47 @@ | ||
# java-blackjack | ||
|
||
블랙잭 게임 미션 저장소 | ||
|
||
<br> | ||
|
||
## 구현 기능 목록 | ||
|
||
- 참여할 플레이어들의 이름을 입력받는 기능 | ||
|
||
- 이름을 쉼표를 기준으로 나누는 기능 | ||
|
||
- 유저(딜러, 플레이어)들에게 카드를 2장씩 나누어줬다는 메시지를 출력하는 기능 | ||
|
||
- 유저들이 받은 카드를 출력하는 기능 | ||
|
||
- 딜러는 1장, 플레이어는 2장을 출력하는 기능 | ||
|
||
- 각각의 플레이어에 대한 점수를 계산하는 기능 | ||
|
||
- 각각의 플레이어에게 카드를 더 받을지 여부를 입력받는 기능 | ||
|
||
- 카드를 받은 후, 현재 보유한 카드를 출력하는 기능 | ||
|
||
- 점수가 21이 초과하는지 확인하는 기능 | ||
|
||
- Ace의 경우 1점 또는 11점으로 계산이 가능한 기능 | ||
|
||
- King, Queen, Jack의 경우 10점으로 계산하는 기능 | ||
|
||
- 딜러에 대한 점수를 계산하는 기능 | ||
|
||
- 딜러의 점수가 16점 이하이면 한장의 카드를 추가로 받는 기능 | ||
|
||
- 딜러의 점수가 17점 이상이면 카드를 추가로 받지 못하는 기능 | ||
|
||
- 유저(딜러, 플레이어)들의 최종 카드 상태와 점수를 출력하는 기능 | ||
|
||
- 유저(딜러, 플레이어)들의 최종 결과를 출력하는 기능 | ||
|
||
- 딜러보다 플레이어가 점수가 높으면 승, 낮으면 패로 계산하는 기능 | ||
|
||
<br> | ||
|
||
## 우아한테크코스 코드리뷰 | ||
|
||
* [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package blackjack; | ||
|
||
import static blackjack.util.StringUtil.*; | ||
|
||
import java.util.List; | ||
|
||
import blackjack.controller.BlackjackController; | ||
import blackjack.domain.BlackjackTable; | ||
import blackjack.domain.card.CardFactory; | ||
import blackjack.domain.card.Deck; | ||
import blackjack.domain.user.Dealer; | ||
import blackjack.domain.user.Player; | ||
import blackjack.domain.user.PlayerFactory; | ||
import blackjack.view.InputView; | ||
|
||
public class Application { | ||
public static void main(String[] args) { | ||
Deck deck = new Deck(CardFactory.create()); | ||
Dealer dealer = new Dealer(Dealer.NAME); | ||
List<Player> players = PlayerFactory.create(parsingPlayerNames(InputView.inputPlayerNames())); | ||
BlackjackTable blackjackTable = new BlackjackTable(deck); | ||
|
||
BlackjackController blackjackController = new BlackjackController(blackjackTable); | ||
blackjackController.playGame(dealer, players); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,67 @@ | ||||||||
package blackjack.controller; | ||||||||
|
||||||||
import static blackjack.view.InputView.*; | ||||||||
import static blackjack.view.OutputView.*; | ||||||||
|
||||||||
import java.util.List; | ||||||||
|
||||||||
import blackjack.domain.BlackjackTable; | ||||||||
import blackjack.domain.DrawOpinion; | ||||||||
import blackjack.domain.result.Report; | ||||||||
import blackjack.domain.user.Dealer; | ||||||||
import blackjack.domain.user.Player; | ||||||||
import blackjack.domain.user.User; | ||||||||
|
||||||||
public class BlackjackController { | ||||||||
private final BlackjackTable blackjackTable; | ||||||||
|
||||||||
public BlackjackController(BlackjackTable blackjackTable) { | ||||||||
this.blackjackTable = blackjackTable; | ||||||||
} | ||||||||
|
||||||||
public void playGame(Dealer dealer, List<Player> players) { | ||||||||
List<User> users = blackjackTable.collectToUsersFrom(dealer, players); | ||||||||
|
||||||||
drawInitialCardsFrom(users); | ||||||||
continueDrawCardsEach(dealer, players); | ||||||||
|
||||||||
printUsersCardsAndScore(users); | ||||||||
|
||||||||
Report blackJackReport = Report.from(dealer, players); | ||||||||
printBlackjackReport(blackJackReport); | ||||||||
} | ||||||||
|
||||||||
private void drawInitialCardsFrom(List<User> users) { | ||||||||
blackjackTable.drawInitialCards(users); | ||||||||
printUsersInitialDraw(BlackjackTable.INITIAL_DRAW_NUMBER, users); | ||||||||
} | ||||||||
|
||||||||
private void continueDrawCardsEach(Dealer dealer, List<Player> players) { | ||||||||
for (Player player : players) { | ||||||||
drawCardsFrom(player); | ||||||||
} | ||||||||
drawCardsFrom(dealer); | ||||||||
} | ||||||||
|
||||||||
private void drawCardsFrom(Player player) { | ||||||||
while (canDraw(player) && wantDraw(player)) { | ||||||||
blackjackTable.drawCardFrom(player); | ||||||||
printUserHand(player, player.getHand()); | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
private boolean canDraw(User user) { | ||||||||
return user.canDraw(); | ||||||||
} | ||||||||
|
||||||||
private boolean wantDraw(Player player) { | ||||||||
return DrawOpinion.of(inputDrawOpinion(player)).isYes(); | ||||||||
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.
Suggested change
보통 한 줄에 점 하나만 찍혀야 읽기 좋아요 |
||||||||
} | ||||||||
|
||||||||
private void drawCardsFrom(Dealer dealer) { | ||||||||
while (canDraw(dealer)) { | ||||||||
blackjackTable.drawCardFrom(dealer); | ||||||||
printDealerDrawCard(); | ||||||||
} | ||||||||
} | ||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package blackjack.domain; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import blackjack.domain.card.Deck; | ||
import blackjack.domain.user.Dealer; | ||
import blackjack.domain.user.Player; | ||
import blackjack.domain.user.User; | ||
|
||
public class BlackjackTable { | ||
public static final int INITIAL_DRAW_NUMBER = 2; | ||
|
||
private final Deck deck; | ||
|
||
public BlackjackTable(Deck deck) { | ||
this.deck = deck; | ||
} | ||
|
||
public List<User> collectToUsersFrom(Dealer dealer, List<Player> 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. BlackjackTable 클래스가 딜러, 플레이어를 인스턴스 변수로 갖는 것도 괜찮겠네요 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<User> users = new ArrayList<>(); | ||
users.add(dealer); | ||
users.addAll(players); | ||
return users; | ||
} | ||
|
||
public void drawInitialCards(List<User> users) { | ||
for (User user : users) { | ||
user.draw(deck, INITIAL_DRAW_NUMBER); | ||
} | ||
} | ||
|
||
public void drawCardFrom(User user) { | ||
user.draw(deck); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package blackjack.domain; | ||
|
||
import java.util.Arrays; | ||
|
||
public enum DrawOpinion { | ||
YES("y"), | ||
NO("n"); | ||
|
||
private final String opinion; | ||
|
||
DrawOpinion(String opinion) { | ||
this.opinion = opinion; | ||
} | ||
|
||
public static DrawOpinion of(String opinion) { | ||
return Arrays.stream(values()) | ||
.filter(drawOpinion -> drawOpinion.opinion.equals(opinion)) | ||
.findAny() | ||
.orElseThrow(() -> new InvalidDrawOpinionException(InvalidDrawOpinionException.INVALID)); | ||
} | ||
|
||
public boolean isYes() { | ||
return this.equals(YES); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package blackjack.domain; | ||
|
||
public class InvalidDrawOpinionException extends IllegalArgumentException { | ||
public static final String INVALID = "y 또는 n만 입력 가능합니다."; | ||
|
||
public InvalidDrawOpinionException(String s) { | ||
super(s); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package blackjack.domain.card; | ||
|
||
import java.util.Objects; | ||
|
||
public class Card { | ||
private final Symbol symbol; | ||
private final Type type; | ||
|
||
public Card(Symbol symbol, Type type) { | ||
this.symbol = symbol; | ||
this.type = type; | ||
} | ||
|
||
public boolean isAce() { | ||
return symbol.isAce(); | ||
} | ||
|
||
public int getScore() { | ||
return symbol.getScore(); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object object) { | ||
if (this == object) { | ||
return true; | ||
} | ||
if (object == null || getClass() != object.getClass()) { | ||
return false; | ||
} | ||
Card card = (Card)object; | ||
return symbol == card.symbol && | ||
type == card.type; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(symbol, type); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return symbol.getSymbol() + type.getType(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package blackjack.domain.card; | ||
|
||
import static java.util.stream.Collectors.*; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.stream.Stream; | ||
|
||
public class CardFactory { | ||
private static final List<Card> CARDS; | ||
|
||
static { | ||
CARDS = Arrays.stream(Symbol.values()) | ||
.flatMap(CardFactory::createBy) | ||
.collect(collectingAndThen(toList(), Collections::unmodifiableList)); | ||
} | ||
|
||
private static Stream<Card> createBy(Symbol symbol) { | ||
return Arrays.stream(Type.values()) | ||
.map(type -> new Card(symbol, type)); | ||
} | ||
|
||
public static List<Card> create() { | ||
return new ArrayList<>(CARDS); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package blackjack.domain.card; | ||
|
||
import java.util.Collections; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
|
||
public class Deck { | ||
private static final int TOP = 0; | ||
|
||
private final List<Card> cards; | ||
|
||
public Deck(List<Card> cards) { | ||
validate(cards); | ||
Collections.shuffle(cards); | ||
this.cards = cards; | ||
} | ||
|
||
private void validate(List<Card> cards) { | ||
long distinctCardSize = new HashSet<>(cards).size(); | ||
|
||
if (cards.size() != distinctCardSize) { | ||
throw new InvalidDeckException(InvalidDeckException.INVALID); | ||
} | ||
} | ||
|
||
public Card draw() { | ||
if (cards.isEmpty()) { | ||
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. 저도 이 부분에 대해 고민을 했는데, 실제 블랙잭 규칙은 사용자가 8명이란 제한이 있어서 한 카드 팩으로 게임이 가능한 것 같았습니다. 그래도 혹시나 사용자의 제한이 없다면 추가적인 카드팩이 필요하다고 생각이 들어서 해당 경우를 만들어줬는데 한 카드팩이 소진되면 예외를 발생시켜 게임이 종료되도록 수정하겠습니다!! |
||
throw new InvalidDeckException(InvalidDeckException.DECK_EMPTY); | ||
} | ||
return cards.remove(TOP); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package blackjack.domain.card; | ||
|
||
public class InvalidDeckException extends IllegalArgumentException { | ||
public static final String INVALID = "카드 덱에 중복이 존재합니다."; | ||
public static final String DECK_EMPTY = "덱의 모든 카드를 소진하였습니다."; | ||
public static final String NULL = "덱이 존재하지 않습니다."; | ||
|
||
public InvalidDeckException(String s) { | ||
super(s); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package blackjack.domain.card; | ||
|
||
public enum Symbol { | ||
ACE(1, "A"), | ||
TWO(2, "2"), | ||
THREE(3, "3"), | ||
FOUR(4, "4"), | ||
FIVE(5, "5"), | ||
SIX(6, "6"), | ||
SEVEN(7, "7"), | ||
EIGHT(8, "8"), | ||
NINE(9, "9"), | ||
TEN(10, "10"), | ||
JACK(10, "J"), | ||
QUEEN(10, "Q"), | ||
KING(10, "K"); | ||
|
||
private final int score; | ||
private final String symbol; | ||
|
||
Symbol(int score, String symbol) { | ||
this.score = score; | ||
this.symbol = symbol; | ||
} | ||
|
||
public boolean isAce() { | ||
return this.equals(ACE); | ||
} | ||
|
||
public int getScore() { | ||
return score; | ||
} | ||
|
||
public String getSymbol() { | ||
return symbol; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package blackjack.domain.card; | ||
|
||
public enum Type { | ||
SPADE("스페이드"), | ||
HEART("하트"), | ||
CLUB("클럽"), | ||
DIAMOND("다이아몬드"); | ||
|
||
private final String type; | ||
|
||
Type(String type) { | ||
this.type = type; | ||
} | ||
|
||
public String getType() { | ||
return type; | ||
} | ||
} |
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.
이 메서드는 없어도 되지 않을까요?
dealer.canDraw()나 player.canDraw()로 써도 충분하지 않을까요?
메서드로 한 번 더 감싸면 추가적인 어떤 기능이 있나? 라는 생각이 들어서 이 메서드가 어떻게 구현됐는지 파악해야되요
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.
조건문의 형식을 맞추기 위해서 한번 더 분리를 진행했는데 특별한 기능이 없는 메서드인 만큼 다시 원래대로 돌려두겠습니다!!