#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "player.h"
#include "game.h"
static const char *NAMES[20] = {
"Alice", "Alex", "Bob", "Charlie", "David", "Eve",
"Frank", "Grace", "Jack", "Karen", "Mia", "Noah",
"Thomas", "Wendy", "Daniel", "Henry", "Amelia",
"Lily", "Emma", "James"};
const char *chooseRandomName()
{
return NAMES[rand() % 20];
}
void initDealer(Player *player)
{
strncpy(player->name, "Dealer", MAX_NAME_LEN - 1);
player->name[MAX_NAME_LEN - 1] = '\0';
player->chips = 0;
player->isBot = 1;
player->bet = 0;
player->handSize = 0;
player->handValue = 0;
player->lastGame = GameNone;
}
void initBot(Player *player, const int initChips)
{
strncpy(player->name, chooseRandomName(), MAX_NAME_LEN - 1);
player->name[MAX_NAME_LEN - 1] = '\0';
player->chips = initChips;
player->isBot = 1;
player->surrendered = 0;
player->bet = 0;
player->handSize = 0;
player->handValue = 0;
player->lastGame = GameNone;
}
void initPlayer(Player *player, const int initChips, const char *name)
{
strncpy(player->name, name, MAX_NAME_LEN - 1);
player->name[MAX_NAME_LEN - 1] = '\0';
player->chips = initChips;
player->isBot = 0;
player->surrendered = 0;
player->bet = 0;
player->handSize = 0;
player->handValue = 0;
player->lastGame = GameNone;
player->splitBet = 0;
player->splitHandSize = 0;
player->splitHandValue = 0;
player->splitLastGame = GameNone;
}
int canDoubleDown(const Player *player, const int split)
{
if (split)
{
return player->splitBet <= player->chips && player->splitHandSize == 2;
}
return player->bet <= player->chips && player->handSize == 2;
}
int canSurrender(const Player *player)
{
return !player->hasSplit && player->handSize == 2;
}
void processSurrender(Player *player)
{
player->surrendered = 1;
player->chips += player->bet / 2;
player->bet = 0;
}
int placeBet(Player *player, const long amount, const int split)
{
if (amount > player->chips)
{
return 0;
}
if (split)
{
player->splitBet += amount;
}
else
{
player->bet += amount;
}
player->chips -= amount;
// チップが上限を超えないように調整
if (player->chips > MAX_CHIPS)
{
player->chips = MAX_CHIPS;
}
return 1;
}
void addCardToHand(Player *player, const Card card)
{
player->hand[player->handSize++] = card;
player->handValue = calculateHandValue(player->hand, player->handSize);
}
void addCardToSplitHand(Player *player, const Card card)
{
player->splitHand[player->splitHandSize++] = card;
player->splitHandValue = calculateHandValue(player->splitHand, player->splitHandSize);
}
int canSplit(const Player *player)
{
return !player->hasSplit && player->bet <= player->chips && player->handSize == 2 &&
(player->hand[0].rank == player->hand[1].rank || (player->hand[0].rank >= 10 && player->hand[1].rank >= 10));
}
void processSplit(Player *player)
{
player->hasSplit = 1;
player->splitBet = player->bet;
player->chips -= player->bet;
// 2枚目のカードをスプリット手札に移動
player->splitHand[0] = player->hand[1];
player->splitHandSize = 1;
player->splitHandValue = calculateHandValue(player->splitHand, player->splitHandSize);
// 元の手札を1枚にする
player->handSize = 1;
player->handValue = calculateHandValue(player->hand, player->handSize);
}
int calculateHandValue(const Card hand[MAX_DRAW_CARD], const int handSize)
{
// 手札の合計値を計算
int value = 0;
// エースの枚数をカウント(後で1か11の判定に使用)
int aces = 0;
// まずエースを11として計算
for (int i = 0; i < handSize; i++)
{
int rank = hand[i].rank;
if (rank == 1)
{
aces++;
value += 11;
}
else if (rank > 10)
{
value += 10;
}
else
{
value += rank;
}
}
// バーストしている場合、エースを1として再計算
while (value > 21 && aces > 0)
{
value -= 10; // エースを11から1に変更(-10)
aces--;
}
return value;
}
void printLastGame(const Player *player, const int split)
{
const GameStatus *gs = split ? &player->splitLastGame : &player->lastGame;
switch (*gs)
{
case GameBlackJack:
printf("\033[47m\033[31mB\033[30mJ\033[39m\033[49m");
break;
case GameWin:
printf("Win");
break;
case GameDraw:
printf("Draw");
break;
case GameLose:
printf("Lose");
break;
case GameSurrender:
printf("Surr");
break;
default:
break;
}
}