0
0

ブラックジャックを実装したい!!

Last updated at Posted at 2024-07-30

はじめに

C++によるゲーム開発をいくつか行ってきました.次に開発を行いたいと考えたのがブラックジャックです.トランプカードゲームの代表例であるゲームですが,シンプルなルールなので作りやすかったです.ぜひプレイしてみてください.

ブラックジャックとは

ブラックジャックのルールは以下のようになっているそうです.
(参考:https://casinocafe.jp/casinovenus/game/blackjack/)

  1. カジノディーラーがカードを2枚ずつ配ります.
  2. カジノディーラーは順番に各プレイヤーに対してカードの追加を行うか(アクション)を聞いていきます.
    1. カードを追加(ヒット)する場合は、テーブルを軽く叩いてください.カードは何枚でもヒットできますが、21点を越えてしまうとその時点で失格(バスト)となります.
    2. 手持ちの点数が十分だと思ったら,手を横に振り,カードをいらないことを示し(スタンド),その点数のままでディーラーと勝負することになります.
  3. プレイヤー全員が選択を終えた後,最後にディーラーがカードをめくり,17点以上になるまでカードを引き続け,勝負となります.
  4. ディーラーよりも21点に近いプレイヤーは勝ち,逆にディーラーよりも21点に遠いプレイヤーは負けとなります.なお、同点の場合はプッシュといい、引き分けとなります.

追記:賭け金の制度を導入しました(2024/07/31)

実装してみた

header.h
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <thread>
#include <chrono>
using namespace std;

extern int deck[13]; //山札記録用変数

int initialization(void);
int betting(int);
int sum_card(vector<int> a);
int draw();
void show_card(vector<int>);
functions.cpp
#include"header.h"

int initialization(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    srand((unsigned int)time(NULL));
    for (int i = 0;i < 13;i++)
        deck[i] = 4; //山札生成
    cout << "コインを何枚購入しますか?";
    int coin;
    cin >> coin;
    return coin;
}

int betting(int coin) {
    int bet;
    while (true) {
        cout << "コインを何枚賭けますか?(所持:" << coin << "枚)";
        cin >> bet;
        if (bet > coin) {
            cout << "所持枚数より少ない数を入力してください.\n";
            continue;
        }
        return bet;
    }
}

int sum_card(vector<int> a) { //手札の合計を計算する.
    int sum = 0;
    for (int i = 0;i < a.size();i++) {
        if (a[i] > 10) sum += 10; //11~13も10として数えられる
        else sum += a[i];
    }
    if (find(a.begin(), a.end(), 1) != a.end() && sum <= 11)
        sum += 10; //1は1または11の都合の良い方で数えられる
    return sum;
}

int draw() { //カードを引く関数
    int r;
    while (true) {
        r = rand() % 13 + 1; //乱数生成
        if (deck[r - 1] > 0) { //山札に含まれるカードのみ処理
            deck[r - 1]--;
            break;
        }
    }
    return r;
}

void show_card(vector<int> a) {
    cout << "のカードは"; //カード出力
    for (int i : a)
        cout << i << " ";
    cout << "です.\n";
}
main.cpp
#include"header.h"

int deck[13];

int main(void) {
    int coin = initialization();
    int flag = 0;
    
    int count = 0;
    int sum_player = 0;

    while (coin > 0) {
        vector<vector<int>> card(2); //手札記録用変数
        count++;
        cout << "\n"<< count << "回目の勝負を開始します.\n";

        int bet;
        bet = betting(coin);
        for (int i = 0;i < 2;i++) {
            for (int j = 0;j < 2;j++)
                card[i].push_back(draw()); //初めにプレイヤー,ディーラーの両方に二枚配る
        }

        cout << "\nプレイヤー"; //プレイヤーのカード出力
        show_card(card[0]);
        sum_player = sum_card(card[0]);

        while (true) {
            cout << "もう一枚引きますか?(y or n)"; //引く場合はy,引かない場合はnを入力
            char s;
            cin >> s;
            if (s == 'n')
                break;
            card[0].push_back(draw());

            cout << "\nプレイヤー"; //プレイヤーのカード出力
            show_card(card[0]);

            sum_player = sum_card(card[0]);
            if (sum_player > 21) { //21を超えたらバストしてプレイヤーの負け
                cout << "バストしました.\n";
                coin -= bet;
                flag = 1;
                break;
            }
        }
        if (flag == 1)
            continue;;

        cout << "あなたのスコアは" << sum_player << "です.\n\n";

        cout << "ディーラー"; //ディーラーのカード出力
        show_card(card[1]);

        while (true) {
            int sum_dealer = sum_card(card[1]);
            if (sum_dealer <= 16) { //ディーラーはスコアが16以下のときはさらに引く
                card[1].push_back(draw());
                sum_dealer = sum_card(card[1]);
            }
            cout << "ディーラー"; //ディーラーのカード出力
            show_card(card[1]);

            if (sum_dealer > 21) { //21を超えたらバストしてディーラーの負け
                cout << "ディーラーのスコアは" << sum_dealer << "です." << "\n";
                cout << "ディーラーがバスト\nプレイヤーの勝利";
                coin += bet;
                break;
            }
            else if (sum_dealer >= 17) { //17を超えたら引くのをやめて勝敗判定
                cout << "ディーラーのスコアは" << sum_dealer << "です." << "\n";
                if (sum_dealer == sum_player)
                    cout << "ドロー\n";
                else if (sum_dealer > sum_player) {
                    cout << "ディーラーの勝利\n";
                    coin -= bet;
                }
                else {
                    cout << "プレイヤーの勝利\n";
                    coin += bet;
                }
                break;
            }
        }
    }
    cout << "所持金がなくなりました\n";
    return 0;
}
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0