#ifndef PLAYER_H #define PLAYER_H #include "card.h" #define MAX_NAME_LEN 11 #define MAX_DRAW_CARD 11 #define MAX_CHIPS 999999999 /** * @brief ゲーム結果の状態 * * 1回のゲームで起こりうる結果を表す列挙型。 */ typedef enum { GameWin = 1, /**< プレイヤーの勝ち */ GameDraw = 2, /**< ディーラーとの引き分け */ GameLose = 3, /**< プレイヤーの負け */ GameBlackJack = 4, /**< ブラックジャックでの勝ち */ GameSurrender = 5, /**< サレンダー(降り)*/ GameNone = 0 /**< ゲーム未終了 */ } GameStatus; /** * @brief プレイヤー構造体 * * プレイヤーの手札、賭け金、ゲームの状態など全ての情報を保持する。 * 通常の手札とスプリット(分割)手札の両方に対応。 */ typedef struct { char name[MAX_NAME_LEN]; /**< プレイヤーの表示名 */ long chips; /**< 現在のチップ数 */ int isBot; /**< コンピュータプレイヤーかどうか */ int surrendered; /**< サレンダーしたかどうか */ Card hand[MAX_DRAW_CARD]; /**< メインの手札 */ int handSize; /**< メイン手札のカード枚数 */ int handValue; /**< メイン手札の合計値 */ long bet; /**< メイン手札への賭け金 */ GameStatus lastGame; /**< メイン手札の結果 */ Card splitHand[MAX_DRAW_CARD]; /**< スプリット手札 */ int splitHandSize; /**< スプリット手札のカード枚数 */ int splitHandValue; /**< スプリット手札の合計値 */ long splitBet; /**< スプリット手札への賭け金 */ GameStatus splitLastGame; /**< スプリット手札の結果 */ int hasSplit; /**< スプリットしたかどうか */ } Player; /** * @brief ボット用のランダムな名前を選択 * * @return const char* 定義済みリストからランダムに選んだ名前 */ const char *chooseRandomName(); /** * @brief ディーラーの初期化 * * ディーラーの初期状態を設定し、名前を"Dealer"に設定する。 * * @param player ディーラーとして初期化するプレイヤー構造体 */ void initDealer(Player *player); /** * @brief ボットプレイヤーの初期化 * * コンピュータ制御のプレイヤーをランダムな名前と初期チップで設定する。 * * @param player 初期化するプレイヤー構造体 * @param initChips 初期チップ数 */ void initBot(Player *player, const int initChips); /** * @brief 人間プレイヤーの初期化 * * 人間プレイヤーを指定された名前と初期チップで設定する。 * * @param player 初期化するプレイヤー構造体 * @param initChips 初期チップ数 * @param name プレイヤーの表示名 */ void initPlayer(Player *player, const int initChips, const char *name); /** * @brief ダブルダウン可能か確認 * * プレイヤーが十分なチップを持っており、手札が適切な状態か確認する。 * * @param player 確認するプレイヤー * @param split スプリット手札を確認するかどうか * @return int 可能なら1、不可能なら0 */ int canDoubleDown(const Player *player, const int split); /** * @brief サレンダー可能か確認 * * プレイヤーが最初のターンで2枚の手札を持っているか確認する。 * * @param player 確認するプレイヤー * @return int 可能なら1、不可能なら0 */ int canSurrender(const Player *player); /** * @brief サレンダーの処理 * * 賭け金の半額を返却し、プレイヤーをサレンダー状態にする。 * * @param player サレンダーするプレイヤー */ void processSurrender(Player *player); /** * @brief 賭け金の設定 * * プレイヤーからチップを差し引き、賭け金として設定する。 * * @param player 賭けを行うプレイヤー * @param amount 賭け金額 * @param split スプリット手札への賭けかどうか * @return int 成功なら1、チップ不足なら0 */ int placeBet(Player *player, const long amount, const int split); /** * @brief メイン手札にカードを追加 * * カードを追加し、手札の合計値を更新する。 * * @param player カードを受け取るプレイヤー * @param card 追加するカード */ void addCardToHand(Player *player, const Card card); /** * @brief スプリット手札にカードを追加 * * カードを追加し、スプリット手札の合計値を更新する。 * * @param player カードを受け取るプレイヤー * @param card 追加するカード */ void addCardToSplitHand(Player *player, const Card card); /** * @brief スプリット可能か確認 * * プレイヤーが十分なチップを持っており、同じランクの2枚のカードを * 持っているか確認する。 * * @param player 確認するプレイヤー * @return int 可能なら1、不可能なら0 */ int canSplit(const Player *player); /** * @brief スプリットの処理 * * 手札を2つに分け、それぞれに同額の賭け金を設定する。 * * @param player スプリットを行うプレイヤー */ void processSplit(Player *player); /** * @brief 手札の価値を計算 * * ブラックジャックのルールに従って手札の合計値を計算する。 * エースを1または11として適切に扱う。 * * @param hand カードの配列 * @param handSize カードの枚数 * @return int 手札の合計値 */ int calculateHandValue(const Card hand[MAX_DRAW_CARD], const int handSize); /** * @brief ゲーム結果の表示 * * 勝敗結果を適切な形式で表示する。 * * @param player 結果を表示するプレイヤー * @param split スプリット手札の結果を表示するかどうか */ void printLastGame(const Player *player, const int split); #endif