C++によるコンソール版博餅ゲームの実装

コンソールにおけるサイコロの描画処理

C++のコンソールアプリケーションでは、GUIのように自由に図形を配置することはできませんが、文字と色を組み合わせることでサイコロを視覚的に表現できます。Windows APIのSetConsoleTextAttributeを利用して、出力の文字色を動的に変更する関数を定義します。4の目は赤色、それ以外は青色で描画し、枠線は白色とすることで、伝統的な博餅のサイコロを再現します。

#include <iostream>
#include <string>
#include <random>
#include <windows.h>
#include <ctime>

void setConsoleColor(int textColor, int bgColor = 0) {
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), (bgColor << 4) | textColor);
}

void drawDie(int pips) {
    bool isRed = (pips == 4);
    
    auto printDot = [&]() {
        setConsoleColor(isRed ? 12 : 9);
        std::cout << "●";
        setConsoleColor(15);
    };

    std::cout << "--------\n|";
    
    switch (pips) {
        case 1:
            std::cout << "      |\n|  "; printDot(); std::cout << "  |\n|      |\n";
            break;
        case 2:
            std::cout << "  "; printDot(); std::cout << "  |\n|      |\n|  "; printDot(); std::cout << "  |\n";
            break;
        case 3:
            printDot(); std::cout << "    |\n|  "; printDot(); std::cout << "  |\n|    "; printDot(); std::cout << "|\n";
            break;
        case 4:
            printDot(); std::cout << "  "; printDot(); std::cout << "|\n|      |\n|"; printDot(); std::cout << "  "; printDot(); std::cout << "|\n";
            break;
        case 5:
            printDot(); std::cout << "  "; printDot(); std::cout << "|\n|  "; printDot(); std::cout << "  |\n|"; printDot(); std::cout << "  "; printDot(); std::cout << "|\n";
            break;
        case 6:
            printDot(); std::cout << "  "; printDot(); std::cout << "|\n|"; printDot(); std::cout << "  "; printDot(); std::cout << "|\n|"; printDot(); std::cout << "  "; printDot(); std::cout << "|\n";
            break;
    }
    std::cout << "--------\n";
}

階級判定ロジックの実装

博餅では、6つのサイコロを振った結果に基づいて階級が決まります。特に4の目(赤)の数が重要な役割を果たします。出目のカウント配列を受け取り、優先度の高い階級から順に条件分岐で判定処理を行う関数を実装します。

std::string checkRank(const int counts[7]) {
    if (counts[4] == 4 && counts[1] == 2) return "★插金花★";
    if (counts[4] == 6) return "★红六勃★";
    if (counts[1] == 6) return "★遍地锦★";
    if (counts[2] == 6 || counts[3] == 6 || counts[5] == 6 || counts[6] == 6) return "★黑六勃★";
    if (counts[4] == 5) return "★五红★";
    if (counts[1] == 5 || counts[2] == 5 || counts[3] == 5 || counts[5] == 5 || counts[6] == 5) return "★五子登科★";
    if (counts[4] == 4) return "★四红★";
    if (counts[1] == 1 && counts[2] == 1 && counts[3] == 1 && counts[4] == 1 && counts[5] == 1 && counts[6] == 1) return "对堂";
    if (counts[4] == 3) return "三红";
    if (counts[1] == 4 || counts[2] == 4 || counts[3] == 4 || counts[5] == 4 || counts[6] == 4) return "四进";
    if (counts[4] == 2) return "二举";
    if (counts[4] == 1) return "一秀";
    return "无";
}

完全な実装コード

これまでの描画と判定のロジックを統合し、乱数生成には現代的なC++のstd::mt19937を採用したメインループを構築します。ユーザーの入力をトリガーとして画面をクリアし、6つのサイコロを連続で描画した後に結果を表示します。

int main() {
    std::mt19937 gen(static_cast<unsigned>(time(nullptr)));
    std::uniform_int_distribution<int> dist(1, 6);

    char cmd;
    while (true) {
        std::cout << "文字を入力してサイコロを振る: ";
        std::cin >> cmd;
        system("cls");

        int counts[7] = {0};
        for (int i = 0; i < 6; ++i) {
            int roll = dist(gen);
            drawDie(roll);
            counts[roll]++;
            Sleep(15);
        }

        std::string result = checkRank(counts);
        if (result.find("★") != std::string::npos) {
            setConsoleColor(14);
        }
        std::cout << result << std::endl;
        setConsoleColor(15);
    }
    return 0;
}

タグ: C++ WindowsAPI コンソールアプリケーション 博餅

6月28日 20:00 投稿