/* 一人で遊ぶポーカーのプログラムである。 ジョーカーは使わない。最初にコインを何枚か賭ける。五枚のカードが配られ、そのうちの零枚から五枚を選んで、一度だけ 交換すると、交換後の役に応じた枚数のコインがもらえる。これのくり返し。 トランプカードは、0 から 51 の数で表す。0 から 12 がスペードの A から K, 13 から 25 がハートの A から K, 26 から 38 がクラブの A から K, 39 から 51 がダイヤモンドの A から K である。 ここまでで習ったことだけを使って書いてある。C言語の全貌を学べばもっとうまく書ける部分を含んでいる。 */ #include #include /* rand() */ #include /* time() */ int card[52]; /* ジョーカーは使わないので 52 枚 */ int hand[5]; /* 手札 */ int a[6]; /* どの札を交換するかをユーザが入力したあと、その解析に使う */ main() { int i, j, x, y; int coins, bet, get; int samerank, sequence, sequence2, flush; for (coins = 100; coins > 0; ) { /* 100 は最初に持っているコインの数 */ printf("--------------------\n"); for (bet = -1; bet == -1; ) { printf("%d 枚のコインを持っています.\n", coins); printf("何枚賭けますか? (0 を入力すれば終了)>"); scanf("%d", &bet); if (bet > coins) { printf("そんなに持っていませんよ.\n"); bet = -1; /* これでやり直し */ } } if (bet == 0) { coins = 0; /* これでプログラムを終了 */ } else { { /* この中カッコの中(乱数の種の設定)はわからなくてもよい */ unsigned seed = (unsigned)time(NULL); /* 現在時刻を取得して */ printf("乱数の種は %u です.\n", seed); srand(seed); /* それを乱数の種に */ } for (i = 0; i < 52; i++) { /* card[ ](カード)を初期化 */ card[i] = i; } for (i = 0; i < 5; i++) { /* ここでカードを五枚ひく */ for (hand[i] = -1; hand[i] == -1; ) { j = rand() % 52; if (card[j] != -1) { hand[i] = card[j]; card[j] = -1; /* -1 はカードをとってしまった印。同じカードを次に選ばないため */ } } } for (i = 0; i < 5; i++) { /* カードの数(ランク)を表示 */ y = hand[i] % 13; /* これがカードの数(ランク)を示す */ if (y == 0) { /* 数(ランク)の表示 */ printf(" A "); } else if (y == 10) { printf(" J "); } else if (y == 11) { printf(" Q "); } else if (y == 12) { printf(" K "); } else { printf("%2d ", y+1); } } printf("\n"); for (i = 0; i < 5; i++) { /* カードのマーク(スート)を表示 */ y = hand[i] / 13; /* これがカードのマーク(スート)を示す */ if (y == 0) { printf(" ! "); /* スペード(のつもり) */ } else if (y == 1) { printf(" & "); /* ハート(のつもり) */ } else if (y == 2) { printf(" %% "); /* クラブ(のつもり)。% 自身を出力させるときは %% と書くことに注意 */ } else { printf(" @ "); /* ダイヤモンド(のつもり) */ } } printf("\n"); /* これでカードの表示が終わった */ printf("どれを交換しますか? --- 例:1, 2, 5 枚目なら 125 と入力。一枚も変えないなら 0 と入力\n"); scanf("%d", &x); for (i = 1; i <= 5; i++) { /* 以下、配列 a[ ] を使って、ユーザが x に入力した値を分析する。*/ a[i] = 0; /* 125 と入力されたら、a[1], a[2], a[5] が 1 で a[3], a[4] は 0 としたい。*/ } for ( ; x != 0; ) { /* これでそうなっているんだけど、どうしてかは自分で考えて。*/ y = x % 10; if (y >= 1 && y <= 5) { a[y] = 1; } x = x / 10; } for (i = 0; i < 5; i++) { /* カードの交換。本質的に、前のカードをひくところと同じ */ if (a[i+1] == 1) { for (hand[i] = -1; hand[i] == -1; ) { j = rand() % 52; if (card[j] != -1) { hand[i] = card[j]; card[j] = -1; } } } } for (i = 0; i < 5; i++) { /* カードの表示。上と全く同じ。関数を学んだあとなら関数にすべきところ。 */ y = hand[i] % 13; if (y == 0) { printf(" A "); } else if (y == 10) { printf(" J "); } else if (y == 11) { printf(" Q "); } else if (y == 12) { printf(" K "); } else { printf("%2d ", y+1); } } printf("\n"); for (i = 0; i < 5; i++) { y = hand[i] / 13; if (y == 0) { printf(" ! "); } else if (y == 1) { printf(" & "); } else if (y == 2) { printf(" %% "); } else { printf(" @ "); } } printf("\n"); /* 以下、手札の役の解析を行なう。 */ /* まずは、数(ランク)が一致する組(ペア)の数を数える */ samerank = 0; for (i = 0; i < 5; i++) { for (j = i+1; j < 5; j++) { if (hand[i] % 13 == hand[j] % 13) { samerank++; } } } /* 次に、ランクが一致するペアがない場合に限り、隣り合ったランクのペアの数を数える。*/ /* これはストレートかどうかを判定するためなので、ランクが一致するペアがある場合は 0 とする。 */ sequence = sequence2 = 0; if (samerank == 0) { for (i = 0; i < 5; i++) { for (j = i+1; j < 5; j++) { if (hand[i] % 13 == hand[j] % 13 + 1 || hand[i] % 13 + 1 == hand[j] % 13) { sequence++; } } } /* ここで sequence が 4 ならストレート(10-J-Q-K-A 以外)*/ for (i = 0; i < 5; i++) { for (j = i+1; j < 5; j++) { if (hand[i] % 13 == 0) { /* A は 13 と置き換えてから */ x = 13; } else { x = hand[i] % 13; } if (hand[j] % 13 == 0) { y = 13; } else { y = hand[j] % 13; } if (x == y + 1 || x + 1 == y) { /* 上と同じことを行なう */ sequence2++; } } } /* ここで sequence2 が 4 ならストレート(A-2-3-4-5 以外) */ } /* 次に、マーク(スート)がすべて同じかどうかの判定を行なう */ if (hand[0] / 13 == hand[1] / 13 && hand[0] / 13 == hand[2] / 13 && hand[0] / 13 == hand[3] / 13 && hand[0] / 13 == hand[4] / 13) { flush = 1; /* YES */ } else { flush = 0; /* NO */ } /* 以上で、解析の材料はそろった。あとは判定するのみ。get は倍率。*/ if (samerank == 1) { printf("ワンペアです.\n"); get = 1; } else if (samerank == 2) { printf("ツーペアです.\n"); get = 2; } else if (samerank == 3) { printf("スリーカードです.\n"); get = 3; } else if ((sequence == 4 || sequence2 == 4) && flush == 0) { printf("ストレートです!\n"); get = 4; } else if (sequence != 4 && sequence2 != 4 && flush == 1) { printf("フラッシュです!\n"); get = 5; } else if (samerank == 4) { printf("フルハウスです!\n"); get = 10; } else if (samerank == 6) { printf("フォーカードです!!\n"); get = 20; } else if (sequence == 4 && flush == 1) { printf("ストレートフラッシュです!!\n"); get = 50; } else if (sequence != 4 && sequence2 == 4 && flush == 1) { printf("ロイヤルストレートフラッシュです!!!\n"); get = 500; } else { get = 0; } if (get > 0) { printf("%d 枚のコインが当たりました.\n", get * bet); } else { printf("残念でした.\n"); } coins = coins + (get - 1) * bet; if (coins == 0) { printf("あなたは破産しました....\n"); } } } }