티스토리 뷰

자바 로고

 

트럼프 카드

 

들어가기 전 설명

 

현재 구현한 코드들은 GitHub 에 있습니다. 글을 보다가 헷갈리시면 소스코드로 참고 해주시기 바랍니다.

또한, JAVA console으로 구현하였습니다.

 

 

 

게임 규칙

 

  • 게임 딜러와 플레이어 1대1로 진행합니다.
  • 딜러를 포함한 플레이어에게 카드 두 장을 나누어주고, 딜러의 카드 한 장은 게이머에게 보이지 않습니다.
  • 딜러는 카드의 합이 16 이하면 무조건 한 장을 더 받아야 하고, 17 이상의 경우에는 멈추어야 합니다.
  • 딜러의 카드와 합이 같으면 비깁니다.

 

  • 게이머는 먼저 받은 카드 두 장의 합이 21에 못 미치면 한 장씩 더 받을 수 있고, 멈출 수도 있습니다.
  • 게이머는 카드의 합이 딜러보다 먼저 21이 되거나 딜러보다 21에 가깝게 되면 이기고, 카드를 더 받았는데 21을 초과하면 집니다.

 

  • 카드 중에 에이스카드(A) 는 1이나 11으로 취급할 수 있고, 10, J, Q, K는 모두 10으로 계산합니다.
  • 카드 오픈을 했을 때 게이머의 카드 숫자합이 21미만이면 딜러와 게이머 카드 숫자합을 측정합니다.
    이 때, 딜러도 21을 넘으면 딜러가 게임에서 집니다.
  • 카드 합이 21이 되면 블랙잭(Blackjack)이 되고 즉시 승리합니다

 

 

https://ko.wikipedia.org/wiki/%EB%B8%94%EB%9E%99%EC%9E%AD

 

블랙잭 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 블랙잭 게임의 예 블랙잭(영어: Blackjack)은 트웬티원(영어: Twenty-one) 또는 벵테텅(프랑스어: Vingt-et-un)이라고도 하며, 세계의 카지노에서 가장 널리 행해지는 플

ko.wikipedia.org

 

 

 

 

코드 구현하기

 

  1. Game.java
  2. Main Thread 실행

이 순서로 보여드리겠습니다.

 

 

 

 

 

 

Game.java

 

이 게임 객체는 게임 시작, 카드 리셋, 게임 플레이, 카드 분배,  딜러 턴, 게이머 턴, 게임 승자 결정 메서드로 이루어져 있습니다.

 

이 메서드들을 사용하기 위해서는 카드덱(CardDeck), 게이머(Gamer), 딜러(Dealer), 규칙(Rule)을 필드 값으로 가지고 있습니다.

그래서 외부에서 주입받아서 사용하려고 합니다.

public class Game {
    private Rule rule;		// 규칙
    private Dealer dealer;	// 딜러
    private Gamer gamer;	// 게이머
    private CardDeck cardDeck;	// 카드덱

    // 생성자
    public Game(Rule rule, Dealer dealer, Gamer gamer, CardDeck cardDeck) {
        this.rule = rule;
        this.dealer = dealer;
        this.gamer = gamer;
        this.cardDeck = cardDeck;
    }
    
    // ~~ 메서드 우선 전부 생략
    
}

 

 

 

게임 시작 메서드 (start)

게임을 시작해주는 메서드입니다.

게임을 진행한 후 끝났을 때 다시 게임을 진행 할 것인지 끝낼 것인지를 담당하게 됩니다.

// 게임 시작
public void start() {
    Scanner scanner = new Scanner(System.in);
    String input = "";

    while (!input.equalsIgnoreCase("exit")) {
        play();
        System.out.print("게임을 계속하시겠습니까? (계속하려면 아무 키나 누르세요, 종료하려면 'exit' 입력): ");
        input = scanner.nextLine();
        reset();
    }
    System.out.println("게임을 종료합니다.");
}

 

 

카드 리셋 (reset)

게임을 새로 시작할 때마다 새롭게 카드를 세팅하는 것을 담당하게 됩니다.

// 카드 리셋
private void reset() {
    // 게임 재설정을 위해 카드 덱과 플레이어의 카드 목록 초기화
    this.cardDeck = new CardDeck();
    dealer.getHaveCards().clear();
    gamer.getHaveCards().clear();
}

 

 

초기 카드 분배 (initialDeal)

처음에 딜러와 게이머가 2장씩 카드를 갖고 있어야 하므로 초반 세팅을 담당하게 됩니다.

// 초기 카드 분배
private void initialDeal() {
    // 딜러와 게이머에게 각각 두 장의 카드를 분배
    dealer.draw(cardDeck);
    dealer.draw(cardDeck);
    gamer.draw(cardDeck);
    gamer.draw(cardDeck);
}

 

 

딜러 턴 (dealerTurn)

딜러는 카드 숫자 합이 17이상으로 뽑아야 하기 때문에 초기세팅 이후로 카드 숫자합이 17이하라면 카드를 더 뽑는 것을 담당합니다.

// 딜러 턴
private void dealerTurn() {
    // 딜러는 점수가 17 이상이 될 때까지 카드를 받음
    while (rule.calculateScore(dealer.getHaveCards()) < 17) {
        dealer.draw(cardDeck);
    }
    System.out.println("딜러의 카드 한장은 : " + dealer.getHaveCards().get(0));
}

 

 

게이머 턴 (gamerTurn)

게이머는 자신이 카드숫자가 낮다고 생각하면 카드를 더 뽑아야 하고, 

딜러를 이길 것 같은 높은 숫자면 카드를 받지 말아야합니다.

그래서 카드를 더 뽑을 것인지 그만 뽑을 것인지 while 문으로 판별하게 됩니다.

// 플레이어 턴
private void gamerTurn() {
    Scanner scanner = new Scanner(System.in);
    boolean continueDrawing = true;

    while (continueDrawing && rule.calculateScore(gamer.getHaveCards()) <= rule.getBLACKJACK_SCORE()) {
        System.out.println("현재 나의 숫자는 : " + rule.calculateScore(gamer.getHaveCards()) +" 이며 " + gamer.getHaveCards().size() + "장 있습니다.");
        System.out.print("카드를 더 받으시겠습니까? (y/n): ");
        String input = scanner.nextLine();

        if (input.equalsIgnoreCase("y")) {
            gamer.draw(cardDeck);
        } else {
            continueDrawing = false;
        }
    }
}

 

 

승리자 판별 (gameFinish)

누가 카드 숫자 합이 더 높은지 판별 하는 담당을 하게 됩니다.

// 게임 승자 결정과 console 출력
private void gameFinish(Dealer dealer, Gamer gamer){
    String winner = rule.getWinner(dealer, gamer);
    String msg = dealer.getName() + "의 카드 점수는 " + rule.calculateScore(dealer.getHaveCards()) + "이고 " + gamer.getName() + "의 카드 점수는 " + rule.calculateScore(gamer.getHaveCards())+" 입니다.";

    System.out.println(msg);
    System.out.println("따라서 승리자는 " + winner);
    System.out.println("현재 나의 전적 : " + rule.getVICTORY_GAMER() + "승 , " + rule.getVICTORY_DEALER() + "패");
}

 

 

 

전체 코드

 

코드가 너무 길어 더보기 처리 하게 되었습니다.

더보기
import java.util.Scanner;


/**
 * Created by rius0918@gmail.com on 2024. 5. 26.
 * Blog : http://coasis.tistory.com
 * Github : https://github.com/Ssspil
 */
public class Game {
    private Rule rule;
    private Dealer dealer;
    private Gamer gamer;
    private CardDeck cardDeck;

    public Game(Rule rule, Dealer dealer, Gamer gamer, CardDeck cardDeck) {
        this.rule = rule;
        this.dealer = dealer;
        this.gamer = gamer;
        this.cardDeck = cardDeck;
    }

    // 게임 시작
    public void start() {
        Scanner scanner = new Scanner(System.in);
        String input = "";

        while (!input.equalsIgnoreCase("exit")) {
            play();
            System.out.print("게임을 계속하시겠습니까? (계속하려면 아무 키나 누르세요, 종료하려면 'exit' 입력): ");
            input = scanner.nextLine();
            reset();
        }
        System.out.println("게임을 종료합니다.");
    }

    // 카드 리셋
    private void reset() {
        // 게임 재설정을 위해 카드 덱과 플레이어의 카드 목록 초기화
        this.cardDeck = new CardDeck();
        dealer.getHaveCards().clear();
        gamer.getHaveCards().clear();
    }

    // 게임 플레이
    public void play() {
        System.out.println("================ Blackjack Game START ================");

        // 초기 카드 분배
        initialDeal();

        // 딜러 턴
        dealerTurn();

        // 게이머 턴
        gamerTurn();

        // 승자 결정과 카드 점수 출력
        gameFinish(dealer, gamer);

    }

    // 초기 카드 분배
    private void initialDeal() {
        // 딜러와 게이머에게 각각 두 장의 카드를 분배
        dealer.draw(cardDeck);
        dealer.draw(cardDeck);
        gamer.draw(cardDeck);
        gamer.draw(cardDeck);
    }

    // 딜러 턴
    private void dealerTurn() {
        // 딜러는 점수가 17 이상이 될 때까지 카드를 받음
        while (rule.calculateScore(dealer.getHaveCards()) < 17) {
            dealer.draw(cardDeck);
        }
        System.out.println("딜러의 카드 한장은 : " + dealer.getHaveCards().get(0));
    }

    // 플레이어 턴
    private void gamerTurn() {
        Scanner scanner = new Scanner(System.in);
        boolean continueDrawing = true;

        while (continueDrawing && rule.calculateScore(gamer.getHaveCards()) <= rule.getBLACKJACK_SCORE()) {
            System.out.println("현재 나의 숫자는 : " + rule.calculateScore(gamer.getHaveCards()) +" 이며 " + gamer.getHaveCards().size() + "장 있습니다.");
            System.out.print("카드를 더 받으시겠습니까? (y/n): ");
            String input = scanner.nextLine();

            if (input.equalsIgnoreCase("y")) {
                gamer.draw(cardDeck);
            } else {
                continueDrawing = false;
            }
        }
    }

    // 게임 승자 결정과 console 출력
    private void gameFinish(Dealer dealer, Gamer gamer){
        String winner = rule.getWinner(dealer, gamer);
        String msg = dealer.getName() + "의 카드 점수는 " + rule.calculateScore(dealer.getHaveCards()) + "이고 " + gamer.getName() + "의 카드 점수는 " + rule.calculateScore(gamer.getHaveCards())+" 입니다.";

        System.out.println(msg);
        System.out.println("따라서 승리자는 " + winner);
        System.out.println("현재 나의 전적 : " + rule.getVICTORY_GAMER() + "승 , " + rule.getVICTORY_DEALER() + "패");
    }
}

 

 

 

Main Thred 실행

 

Game 객체에 제가 필요한 객체들을 생성하여 주입해주고 start() 메서드로 게임을 시작해 줍니다.

public class BlackjackApplication {
	public static void main(String[] args) {

		// 객체 주입
		Game game = new Game(new Rule(), new Dealer(), new Gamer("송파의 타짜"), new CardDeck());
		// 게임 시작
		game.start();
	}
}

 

 

게임 콘솔 로그
그림1 블랙잭 게임 실행

 

 

 

 

 

다음 이야기

 

다음 시간에는 리팩토링을 진행해보도록 하겠습니다.

 

감사합니다.

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함