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
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
# java-blackjack

블랙잭 미션 저장소

## 참가자 입력
- [ ] 쉼표 기준으로 분리

## 카드 배분
- [ ] 카드는 52장을 사용
- 숫자 계산은 카드 숫자를 기본
- Ace는 1 or 11로 계산 가능
- King, Queen, Jack은 각각 10으로 계산
- [ ] 카드는 게임이 시작되기 전에 순서를 섞는다.
- [ ] 참가자에게 카드를 2장씩 분배
- [ ] 각 참가자에게 분배된 카드 출력

## 게임 진행
- [ ] 딜러를 제외한 참가자에게 Hit/Stand 여부 확인
- 참가자의 카드 합이 21을 넘지 않는지 Bust 검증
- draw 할 카드가 존재하는지 확인
- [ ] 딜러 Hit/Stand 여부 확인
- 16 이하라면 카드를 draw, 아니라면 멈춘다.

## 게임 종료
- [ ] 참가자의 카드 패와 결과 출력
- [ ] 결과를 바탕으로 각 참가자들의 승패 출력
- 점수가 같을 때를 고려
10 changes: 10 additions & 0 deletions src/main/java/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import controller.GameController;
import ui.InputView;
import ui.ResultView;

public class Application {
public static void main(String[] args){
GameController gameController = new GameController(new ResultView(), new InputView());
gameController.run();
}
}
119 changes: 119 additions & 0 deletions src/main/java/controller/GameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package controller;

import domain.deck.Deck;
import domain.participant.Dealer;
import domain.participant.Participant;
import domain.participant.Player;
import domain.result.ResultJudge;
import ui.InputView;
import ui.ResultView;

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

public class GameController {
private final ResultView resultView;
private final InputView inputView;

public GameController(ResultView resultView, InputView inputView){
this.resultView = resultView;
this.inputView = inputView;
}

public void run(){
Deck deck = new Deck();
ResultJudge judge = new ResultJudge();
// 참가자 입력
List<Participant> participants = joinParticipant();

// 초기 패 설정
initialAllPlayersHand(participants, deck);

// 플레이어마다 Hit/Stand 여부 확인
askHitOrStand(participants, deck);

// 참가자 패와 점수 공개
resultView.printScores(participants);

// 참가자 승/패 공개
resultView.printGameResult(participants, judge);

}

/***
* 1. 모든 플레이어들에게 Hit/Stand 여부를 묻기 위한 함수 실행
* 2. 딜러 draw 여부 확인 (16점 이하인지)
*/
private void askHitOrStand(List<Participant> participants, Deck deck){
Participant dealer = participants.getFirst();
for(Participant player : participants.subList(1, participants.size())){
askPlayerHit(player, deck);
}

while(dealer.canReceiveCard()){
dealer.receive(deck.draw());
resultView.printDealerDraw();
}
}

/***
* 플레이어에게 Hit/Stand 여부 확인
*/
private void askPlayerHit(Participant player, Deck deck){
while(inputView.askHit(player.getName())){
canHit(player, deck);
}
}

/***
* Hit 선택시 실제로 플레이어가 Bust가 아닌지 확인 후 카드 지급
*/
private void canHit(Participant player, Deck deck){
if(player.canReceiveCard()){
player.receive(deck.draw());
resultView.printHand(player);
return;
}
resultView.printIsBust();
}

/***
* 딜러와 입력 받은 플레이어 추가
*/
private List<Participant> joinParticipant(){
Participant dealer = new Dealer("딜러");
List<String> playerNames;
List<Participant> participants = new ArrayList<>();

participants.add(dealer);

playerNames = inputView.inputPlayers();

for(String playerName : playerNames){
Participant player = new Player(playerName);
participants.add(player);
}

return participants;
}

/***
* 모든 참가자에게 2장의 카드를 분배하기 위한 함수 호출 및 패 공개
*/
private void initialAllPlayersHand(List<Participant> participants, Deck deck){
for(Participant participant : participants){
initialHand(participant, deck);
}
resultView.printInitialDeal(participants);
resultView.printAllHands(participants);
}

/**
* 카드를 2장씩 분배
*/
private void initialHand(Participant participant, Deck deck){
for(int i = 0; i < 2; i++){
participant.receive(deck.draw());
}
}
}
26 changes: 26 additions & 0 deletions src/main/java/domain/card/Card.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package domain.card;

import domain.card.enums.Rank;
import domain.card.enums.Suit;

public class Card {
private Rank rank;
private Suit suit;

public Card(Rank rank, Suit suit){
this.rank = rank;
this.suit = suit;
}

public boolean isAce() {
return this.rank == Rank.ACE;
}

public int score(){
return this.rank.getScore();
}

public String displayName(){
return rank.getName() + suit.getName();
}
}
34 changes: 34 additions & 0 deletions src/main/java/domain/card/enums/Rank.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package domain.card.enums;

public enum Rank {
ACE("A", 1),
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("J", 10),
QUEEN("Q", 10),
KING("K", 10);

private final String name;
private final int score;

Rank(String name, int score) {
this.name = name;
this.score = score;
}

public int getScore() {
return score;
}

public String getName() {
return name;
}

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

public enum Suit {
CLUB("클로버"),
HEART("하트"),
SPADE("스페이드"),
DIAMOND("다이아몬드");

private final String name;

Suit(String name){
this.name = name;
}

public String getName(){
return name;
}
}
50 changes: 50 additions & 0 deletions src/main/java/domain/deck/Deck.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package domain.deck;

import domain.card.Card;
import domain.card.enums.Rank;
import domain.card.enums.Suit;

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

public class Deck {
private final List<Card> cards = new ArrayList<>();

public Deck() {
createdDeck();
shuffle();
}

private void createdDeck(){
for (Suit suit : Suit.values()){
addCardsBySuit(suit);
}
}

private void addCardsBySuit(Suit suit) {
for(Rank rank : Rank.values()){
this.cards.add(new Card(rank, suit));
}
}

public Card firstCard(){
return cards.get(0);
}

public Card draw(){
if(cards.isEmpty()){
createdDeck();
this.shuffle();
}
return cards.removeFirst();
}

public void shuffle(){
Collections.shuffle(cards);
}

public List<Card> cards(){
return List.copyOf(cards);
}
}
56 changes: 56 additions & 0 deletions src/main/java/domain/hand/Hand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package domain.hand;

import domain.card.Card;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Hand {
private final List<Card> cards = new ArrayList<>();

public void add(Card card) {
cards.add(card);
}

public int score() {
int score = basicScore();
int aceCount = aceCount();

return bestScore(score, aceCount);
}

public boolean isBust() {
return score() > 21;
}

public String displayCards(){
return cards.stream()
.map(Card::displayName)
.collect(Collectors.joining(", "));
}

public String displayFirstCard(){
return cards.getFirst().displayName();
}

private int basicScore() {
int score = 0;
for (Card card : cards) {
score += card.score();
}
return score;
}

private int aceCount() {
return (int) cards.stream().filter(Card::isAce).count();
}

private int bestScore(int score, int aceCount) {
while (aceCount > 0 && score + 10 <= 21) {
score += 10;
aceCount--;
}
return score;
}
}
12 changes: 12 additions & 0 deletions src/main/java/domain/participant/Dealer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package domain.participant;

public class Dealer extends Participant{
public Dealer(String name){
super(name);
}

@Override
public boolean canReceiveCard(){
return checkScore() <= 16;
}
}
Loading