ブラックジャックの C 言語プログラム
以下は、C 言語によるブラックジャックのプログラムの一例です。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* 関数プロトタイプ宣言 */
void shuffle(char stack[52][4]);
int calc(int nHands, char Hands[21][4]);
void display(int flag,
int nPlayerHands, char PlayerHands[21][4], int PlayerPoint,
int nDealerHands, char DealerHands[21][4], int DealerPoint);
void player(int *next, char stack[52][4],
int *nPlayerHands, char PlayerHands[21][4], int *PlayerPoint,
int nDealerHands, char DealerHands[21][4], int DealerPoint);
void dealer(int *next, char stack[52][4], int PlayerPoint,
int *nDealerHands, char DealerHands[21][4], int *DealerPoint);
/* カードを混ぜる */
void shuffle(char stack[52][4]) {
int i, imax;
int index; /* カード番号 */
char deck[52][4] = {/* 1 組 52 枚のカード */
"S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10",
"S11", "S12", "S13",
"H1", "H2", "H3", "H4", "H5", "H6", "H7", "H8", "H9", "H10",
"H11", "H12", "H13",
"D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "D10",
"D11", "D12", "D13",
"C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "C10",
"C11", "C12", "C13"
};
/* time 関数により擬似乱数を初期化する */
srand((unsigned)time(NULL));
imax = 52;/* 1 組 52 枚のカード */
/* deck から 1 枚ずつ stack に移動する */
for (i = 0; i < imax; i++) {
/* 未使用カードを探す */
do {
index = (int)((float)imax * rand() / (RAND_MAX + 1.0));
} while (deck[index][0] == '\0');
/* カードを設定する */
strcpy(stack[i], deck[index]);
/* 使用済にする */
deck[index][0] = '\0';
}
};
/* 合計点数を計算する */
int calc(int nHands, char Hands[21][4]) {
int i, n;
int point; /* 合計点数 */
int na; /* A の枚数 */
int numbers[21];
char tmp[3];
point = na = 0;
/* 数字を取出す */
for (n = 0; n < nHands; n++) {
for (i = 0; i < 3; i++) tmp[i] = Hands[n][i + 1];
numbers[n] = atoi(tmp);
}
for (n = 0; n < nHands; n++) {
if (numbers[n] <= 10) {
point += numbers[n];
if (numbers[n] == 1) na++;/* A の枚数を数える */
} else {/* 絵札は 10 点 */
point += 10;
}
}
if (point <= 11) {/* A は 1 点としても 11 点としてもよい */
if (na) point += 10;
} else if (point >= 22) {/* 合計点数が 21 点を超えていたら 0 点にする */
point = 0;
}
return(point);
}
/* カードを画面に表示する */
void display(int flag,
int nPlayerHands, char PlayerHands[21][4], int PlayerPoint,
int nDealerHands, char DealerHands[21][4], int DealerPoint) {
int n;
printf("PlayerHands : ");
for (n = 0; n < nPlayerHands; n++) {
printf("%s", PlayerHands[n]);
if (n != nPlayerHands - 1) printf(", ");
}
printf(" [%d]\n", PlayerPoint);
if (flag == 0) {
printf("DealerHands : %s, ?\n", DealerHands[0]);
} else if (flag == 1) {
printf("DealerHands : ");
for (n = 0; n < nDealerHands; n++) {
printf("%s", DealerHands[n]);
if (n != nDealerHands - 1) printf(", ");
}
printf(" [%d]\n", DealerPoint);
if (PlayerPoint == 0) {
printf("Player Busted.\n");
} else if (DealerPoint == 0) {
printf("Dealer Busted.\n");
} else if (PlayerPoint > DealerPoint) {
printf("Player Won.\n");
} else if (PlayerPoint < DealerPoint) {
printf("Dealer Won.\n");
} else if (PlayerPoint == DealerPoint) {
printf("Push.\n");
}
}
}
/* プレーヤーの処理を行う */
void player(int *next, char stack[52][4],
int *nPlayerHands, char PlayerHands[21][4], int *PlayerPoint,
int nDealerHands, char DealerHands[21][4], int DealerPoint) {
int i;
while (1) {
/* カードを画面に表示する */
display(0, *nPlayerHands, PlayerHands, *PlayerPoint,
nDealerHands, DealerHands, DealerPoint);
/* プレーヤーの処理を行う */
printf(" Draw(1) or Stand(2) or Quit(0)? : ");
scanf("%d", &i);
if (i == 1) {/* カードを引く */
printf(" Draw\n");
strcpy(PlayerHands[(*nPlayerHands)++], stack[(*next)++]);
*PlayerPoint = calc(*nPlayerHands, PlayerHands);
if (*PlayerPoint == 0) break;
} else if (i == 2) {/* カードを引かない */
printf(" Stand\n");
break;
} else if (i == 0) {/* 終了する */
exit(0);
} else {
printf("Input Error!\n");
}
}
}
/* ディーラーの処理を行う */
void dealer(int *next, char stack[52][4], int PlayerPoint,
int *nDealerHands, char DealerHands[21][4], int *DealerPoint) {
while (PlayerPoint) {
if (*DealerPoint >= 17) break;/* 16 でドロー(ヒット)/17 でスタンド(ステイ) */
strcpy(DealerHands[(*nDealerHands)++], stack[(*next)++]);
*DealerPoint = calc(*nDealerHands, DealerHands);
if (*DealerPoint == 0) break;
}
}
main () {
int n;
int nround; /* ラウンド数 */
int next; /* 次に配るカード */
int nPlayerHands, /* プレーヤーの手札の枚数 */
nDealerHands; /* ディーラーの手札の枚数 */
int PlayerPoint, /* プレーヤーの合計点数 */
DealerPoint; /* ディーラーの合計点数 */
char PlayerHands[21][4],/* プレーヤーの手札 */
DealerHands[21][4];/* ディーラーの手札 */
char stack[52][4]; /* 1 組 52 枚のカード */
/* カードを混ぜる */
shuffle(stack);
nround = next = 0;
while (52 - next > 10) {
printf("--- Round %d ---\n", ++nround);
/* カードを配る */
nPlayerHands = nDealerHands = 2;
for (n = 0; n < nPlayerHands; n++) strcpy(PlayerHands[n], stack[next++]);
for (n = 0; n < nDealerHands; n++) strcpy(DealerHands[n], stack[next++]);
/* 合計点数を計算する */
PlayerPoint = calc(nPlayerHands, PlayerHands);
DealerPoint = calc(nDealerHands, DealerHands);
/* プレーヤーの処理を行う */
player(&next, stack, &nPlayerHands, PlayerHands, &PlayerPoint,
nDealerHands, DealerHands, DealerPoint);
/* ディーラーの処理を行う */
dealer(&next, stack, PlayerPoint, &nDealerHands, DealerHands, &DealerPoint);
/* カードを画面に表示する */
display(1, nPlayerHands, PlayerHands, PlayerPoint,
nDealerHands, DealerHands, DealerPoint);
}
printf("--- Dealer doesn't have enough cards to continue. ---\n");
}
各関数について、以下に説明します。







