ドロー・ポーカーの C 言語プログラム
以下は、C 言語によるドロー・ポーカーのプログラムの一例です。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* 定数 */
#define IMAX 52/* 1 組 52 枚のカード */
#define NDECK 1 /* 実際のカジノでは、6 デックを 1 スタックとすることが多い
(ブラックジャックの場合) */
#define M 5 /* 手札の枚数 */
#define N 5 /* 交換可能な枚数 */
/* グローバル変数 */
/* なし */
/* 関数プロトタイプ宣言 */
void shuffle(int *stack);
void calc(int index, int *s, int *n);
void display(int player[M]);
void change(int player[M], int *stack, int *next);
int check(int player[M]);
/* カードを混ぜる */
void shuffle(int *stack) {
int i;
int *flag;/* フラグ(0:未使用 1: 使用済) */
/* 動的領域を確保する */
flag = (int *)malloc(sizeof(int) * IMAX * NDECK);
if (flag == NULL) {
printf("Memory Allocation Error!\n");
exit(1);/* 異常終了 */
}
/* 配列を初期化する */
for (i = 0; i < IMAX * NDECK; i++) flag[i] = 0;
/* time 関数により擬似乱数を初期化する */
srand((unsigned)time(NULL));
/* カードを混ぜる */
for (i = 0; i < IMAX * NDECK; i++) {
int index;/* カード番号 */
/* 未使用カードを探す */
do {
/* rand は 0 以上 RAND_MAX 以下の整数を返す */
index = (int)((float)IMAX * NDECK * rand() / (RAND_MAX + 1.0));
} while (flag[index] != 0);
/* カードを設定する */
stack[i] = index;
/* フラグを使用済にする */
flag[index] = 1;
}
/* 動的領域を解放する */
free(flag);
}
/* 番号をカードに換算する */
void calc(int index, int *s, int *n) {
*s = (int)((index % IMAX) / 13);
*n = (index % IMAX) % 13;
}
/* カードを画面に表示する */
void display(int player[M]) {
int i;
char *suits[] = {/* カードの印 */
"S",/* spade */
"H",/* heart */
"D",/* diamond */
"C" /* club */
};
for (i = 0; i < M; i++) {
int s, n;/* カードの印と数字 */
/* 番号をカードに換算する */
calc(player[i], &s, &n);
/* カードを画面に表示する */
printf("%s%02d", suits[s], n + 1);
if (i != M - 1) printf(" ");
}
printf("\n");
}
/* カードを交換する */
void change(int player[M], int *stack, int *next) {
int i;
int nflag; /* 真の flag の数 */
int flag[M];/* カードの交換フラグ */
/* 配列を初期化する */
nflag = 0;
for (i = 0; i < M; i++) flag[i] = 0;
/* 交換するカードを決定する */
while (1) {
char str[2];/* 入力文字列 */
printf("Please select the card(s) you want to change (1 - 5). ");
printf("To finish, input 0.\n");
str[0] = (char)getchar();/* getchar の戻り値は int */
/* バッファの最後に移動(2 文字目以降や改行文字を無視) */
fseek(stdin, 0, SEEK_END);/* rewind(stdin) は、コンパイラによっては先頭に戻る */
if (('0' <= str[0]) && (str[0] <= '5')) {/* 文字コードで比較 */
str[1] = '\0';
i = atoi(str);
if ((1 <= i) && (i <= 5)) {
if (flag[i - 1]) continue;
else flag[i - 1] = 1;
if (++nflag == N) break;
} else if (i == 0) {
break;
}
} else {
printf("Input Error!\n");
}
}
/* カードを交換する */
for (i = 0; i < M; i++) if (flag[i]) player[i] = stack[++(*next)];;
}
/* 役を確認する */
int check(int player[M]) {
int i;
int npair; /* ペアの数 */
int flag_f;/* フラッシュの確認フラグ */
int flag_s;/* ストレートの確認フラグ */
int flag_3;/* スリーカードの確認フラグ */
int s[4]; /* 印毎の枚数 */
int n[13]; /* 数字毎の枚数 */
/* 配列を初期化する */
for (i = 0; i < 4; i++) s[i] = 0;
for (i = 0; i < 13; i++) n[i] = 0;
for (i = 0; i < M; i++) {
int s0, n0;/* カードの印と数字 */
/* 番号をカードに換算する */
calc(player[i], &s0, &n0);
/* 換算したカードの印と数字の枚数を追加する */
s[s0]++;
n[n0]++;
}
/* フラッシュ系 */
flag_f = 0;
for (i = 0; i < 4; i++) {
if (s[i] == M) {
flag_f = 1;
break;
}
}
/* ストレート系 */
for (i = 0; i < 10; i++) {/* ストレートの低位の数字は 1 から 10 まで */
int j;
flag_s = 1;
for (j = 0; j < M; j++) {
if (n[(i + j) % 13] != 1) {/* 13 は 1 と連なる */
flag_s = 0;
break;
}
}
if (flag_s) {
if (flag_f) {
if (i == 9) {
return(9);/* ロイヤル・ストレート・フラッシュ */
} else {
return(8);/* ストレート・フラッシュ */
}
} else {
return(4);/* ストレート */
}
break;
}
}
if (flag_f) return(5);/* フラッシュ */
/* ペア系 */
flag_3 = 0;
npair = 0;
for (i = 0; i < 13; i++) {
if (n[i] == 4) return(7);/* フォーカード */
else if (n[i] == 3) flag_3 = 1;
else if (n[i] == 2) npair++;
}
if (flag_3) {
if (npair == 1) return(6);/* フルハウス */
else return(3);/* スリーカード */
} else {
if (npair == 2) return(2);/* ツーペア */
else if (npair == 1) return(1);/* ワンペア */
}
return(0);/* ノーペア */
}
main () {
int *next; /* 次に配るカード */
int *stack; /* カードの山 */
int player[M]; /* プレーヤーの手札 */
char *hands[] = {/* 役の種類 */
"No Pair",
"One Pair",
"Two Pair",
"Three of a Kind",
"Straight",
"Flush",
"Full House",
"Four of a Kind",
"Straight Flush",
"Royal Straight Flush"
};
/* 動的領域を確保する */
stack = (int *)malloc(sizeof(int) * IMAX * NDECK);
if (stack == NULL) {
printf("Memory Allocation Error!\n");
exit(1);/* 異常終了 */
}
/* カードを混ぜる */
shuffle(stack);
/* カードを配る */
for (*next = 0; *next < M; (*next)++) player[*next] = stack[*next];
/* カードを画面に表示する */
display(player);
/* カードを交換する */
change(player, stack, next);
/* カードを画面に表示する */
display(player);
/* 役を確認する */
printf("%s\n", hands[check(player)]);
/* 動的領域を解放する */
free(stack);
exit(0);/* 正常終了 */
}
各関数について、以下に説明します。
- トランプ・ポーカー
- トランプ・ブラックジャック
- ギャンブルから株式為替まで役立つ資金管理
- 株式投資や為替取引のリスクマネジメント
- カード被害が預金者保護法で補償された体験
- アニメで英会話/台詞逆輸入
- 右脳と左脳を鍛える開発トレーニング