★ゲームを作ろう5(ポーカー5)★


それでは残りの役の判定を考えましょう。

残りは、

<手役>

ストレート
フラッシュ
ストレートフラッシュ

です。


フラッシュは同じスートをチェックするだけなので簡単そうに見えます。

が、ストレートと組み合わせてストレートフラッシュという役になることを考慮しなければなりません。

フラッシュとストレートは同時に成り立つので、少し工夫をします。


フラグの追加


フラッシュ用にflushFlag、ストレート用にstraightFlagを用意します。

乱数の種をセットする直前に↓のプログラムを追加します。

<sample program 109-01>

int flushFlag;       /* フラッシュ成立フラグ */

int straightFlag;    /* ストレート成立フラグ */

フラッシュ


ワンペアのチェックの後に、フラッシュをチェックするプログラムを書きます。

全部のスートが同じでなければフラッシュになりませんので、次のように書いてみます。

<sample program 109-02>

flushFlag = 1;

for (i = 0; i < HAND_NUM - 1; i++) {
    if (hand[i].suit != hand[i + 1].suit) {
        flushFlag = 0;
        break;
    }
}

フラッシュ成立フラグを1にしておきます。

繰り返しの中で、隣同士のスートを比べ、異なっていた場合はフラッシュ成立フラグを0にしてbreakします。

全部のスートが同じであればフラッシュ成立フラグは1のままです。

ただし、まだここでは「フラッシュ」の文字は表示しません。

ストレートフラッシュの可能性がありますので、次はストレートを判定します。


ストレート


ストレートは数値が連続していれば成立しますが、どのようにプログラムでチェックすれば良いでしょうか?

色々な方法がありますので、その1つを書いてみます。

↓はストレートの手札です。

   0 1 2 3 4
  +−+−+−+−+−+
手札|4|5|6|7|8|
  +−+−+−+−+−+
  0番目と1番目を比較した場合、数値の差は1です。

  1番目と2番目の差も1です。

  2番目と3番目も、3番目と4番目の差も1です。

↓はストレートではありません。

   0 1 2 3 4
  +−+−+−+−+−+
手札|4|6|7|9|10|
  +−+−+−+−+−+
  0番目と1番目を比較した場合、数値の差は2です。

  1番目と2番目の差は1です。

  2番目と3番目の差は2です。

  3番目と4番目の差は1です。

この場合、最初の差が「2」という時点でストレートでないことが分かります。

これを踏まえてプログラムを作ってみます。

<sample program 109-03>

straightFlag = 1;

for (i = 0; i < HAND_NUM - 1; i++) {
    if (hand[i + 1].number - hand[i].number != 1) {
        straightFlag = 0;
        break;
    }
}

これでフラッシュとストレートの判定が出来ました。

後はフラグを見て、役を表示するだけです。

※最後に「ノーペア」も追加します。

<sample program 109-04>

if (flushFlag == 1 && straightFlag == 1) {
    printf("ストレートフラッシュ\n");
    break;
}

if (flushFlag == 1) {
    printf("フラッシュ\n");
    break;
}

if (straightFlag == 1) {
    printf("ストレート\n");
    break;
}

printf("ノーペア\n");

デバッグコードにスートも追加して試しましょう。

/* デバッグ用コード */
hand[0].number = 1;
hand[1].number = 2;
hand[2].number = 3;
hand[3].number = 4;
hand[4].number = 5;

hand[0].suit = 1;
hand[1].suit = 1;
hand[2].suit = 1;
hand[3].suit = 1;
hand[4].suit = 1;

<実行結果>

スペード: 1
ハ ー ト: 1
ハ ー ト: 4
ハ ー ト: 9
ク ラ ブ:10
5
ハ ー ト: 1
ハ ー ト: 2
ハ ー ト: 3
ハ ー ト: 4
ハ ー ト: 5
ストレートフラッシュ
続行するには何かキーを押してください・・・

最後にプログラム全文を載せておきます。

※デバッグコードは消しました。

※手札の表示の前に「system("cls");」を追加し、画面をクリアするようにしました。

<sample program 109-05>

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define NUMBER 13
#define MARK    4
#define CARD_NUM (NUMBER * MARK)

#define SHUFFLE_TIME 2000 /* 入れ替え回数 */

#define HAND_NUM 5 /* 手札の枚数 */

/* カード構造体 */
typedef struct
{
    int number;
    int suit;
    int selectFlag;
} Card;

int main(void)
{
    Card deck[CARD_NUM]; /* デッキ */

    Card hand[HAND_NUM]; /* 手札 */

    int i, j;

    int index1, index2;  /* シャッフル用添え字 */

    Card work;           /* 入れ替え用 */

    int select;          /* カード選択用 */

    int dealCount;       /* デッキ用 */

    int flushFlag;       /* フラッシュ成立フラグ */

    int straightFlag;    /* ストレート成立フラグ */

    srand((unsigned int)time(NULL));

    /* デッキの初期化 */

    for (i = 0; i < CARD_NUM; i++) {

        deck[i].suit = i / NUMBER;

        deck[i].number = i % NUMBER + 1;

        deck[i].selectFlag = 0;
    }

    /* デッキのシャッフル */

    for (i = 0; i < SHUFFLE_TIME; i++) {

        index1 = rand() % CARD_NUM;

        index2 = rand() % CARD_NUM;

        work = deck[index1];
        deck[index1] = deck[index2];
        deck[index2] = work;
    }

    /* 手札を配る */

    for (i = 0; i < HAND_NUM; i++) {

        hand[i] = deck[i];
    }

    /* 手札のソート */

    for (i = 0; i < HAND_NUM - 1; i++) {
        for (j = 0; j < HAND_NUM - 1; j++) {

            if (hand[j].number > hand[j + 1].number) {
                work = hand[j];
                hand[j] = hand[j + 1];
                hand[j + 1] = work;
            }
        }
    }

    /* 手札の表示 */

    system("cls");

    for (i = 0; i < HAND_NUM; i++) {

        switch (hand[i].suit) {
        case 0:
            printf("スペード:");
            break;
        case 1:
            printf("ハ ー ト:");
            break;
        case 2:
            printf("ダ イ ヤ:");
            break;
        case 3:
            printf("ク ラ ブ:");
            break;
        }

        printf("%2d\n", hand[i].number);
    }

    for (;;) {

        /* 入れ替えるカードの選択 */

        do {

            scanf("%d", &select);

        } while (select < 0 || select > HAND_NUM);

        if (select == HAND_NUM) {
            break;
        }

        if (hand[select].selectFlag == 0) {
            hand[select].selectFlag = 1;
        }
        else {
            hand[select].selectFlag = 0;
        }

        /* 選択した手札の表示 */

        for (i = 0; i < HAND_NUM; i++) {

            switch (hand[i].suit) {
            case 0:
                printf("スペード:");
                break;
            case 1:
                printf("ハ ー ト:");
                break;
            case 2:
                printf("ダ イ ヤ:");
                break;
            case 3:
                printf("ク ラ ブ:");
                break;
            }

            printf("%2d", hand[i].number);

            if (hand[i].selectFlag == 1) {
                printf(" *\n");
            }
            else {
                printf("\n");
            }
        }
    }

    /* 手札の交換 */

    dealCount = HAND_NUM;

    for (i = 0; i < HAND_NUM; i++) {

        if (hand[i].selectFlag == 1) {

            hand[i] = deck[dealCount];

            dealCount++;
        }
    }

    /* 手札のソート */

    for (i = 0; i < HAND_NUM - 1; i++) {
        for (j = 0; j < HAND_NUM - 1; j++) {

            if (hand[j].number > hand[j + 1].number) {
                work = hand[j];
                hand[j] = hand[j + 1];
                hand[j + 1] = work;
            }
        }
    }

    /* 手札の表示 */

    system("cls");

    for (i = 0; i < HAND_NUM; i++) {

        switch (hand[i].suit) {
        case 0:
            printf("スペード:");
            break;
        case 1:
            printf("ハ ー ト:");
            break;
        case 2:
            printf("ダ イ ヤ:");
            break;
        case 3:
            printf("ク ラ ブ:");
            break;
        }

        printf("%2d\n", hand[i].number);
    }

    /* 手役の判定 */

    for (;;) {

        if (hand[0].number == hand[1].number &&
            hand[1].number == hand[2].number &&
            hand[2].number == hand[3].number) {
            printf("フォーカード\n");
            break;
        }

        if (hand[1].number == hand[2].number &&
            hand[2].number == hand[3].number &&
            hand[3].number == hand[4].number) {
            printf("フォーカード\n");
            break;
        }

        if (hand[0].number == hand[1].number &&
            hand[1].number == hand[2].number) {
            if (hand[3].number == hand[4].number) {
                printf("フルハウス\n");
            }
            else{
                printf("スリーカード\n");
            }
            break;
        }

        if (hand[1].number == hand[2].number &&
            hand[2].number == hand[3].number) {
            printf("スリーカード\n");
            break;
        }

        if (hand[2].number == hand[3].number &&
            hand[3].number == hand[4].number) {
            if (hand[0].number == hand[1].number) {
                printf("フルハウス\n");
            }
            else{
                printf("スリーカード\n");
            }
            break;
        }

        if (hand[0].number == hand[1].number &&
            hand[2].number == hand[3].number) {
            printf("ツーペア\n");
            break;
        }

        if (hand[0].number == hand[1].number &&
            hand[3].number == hand[4].number) {
            printf("ツーペア\n");
            break;
        }

        if (hand[1].number == hand[2].number &&
            hand[3].number == hand[4].number) {
            printf("ツーペア\n");
            break;
        }

        if (hand[0].number == hand[1].number ||
            hand[1].number == hand[2].number ||
            hand[2].number == hand[3].number ||
            hand[3].number == hand[4].number) {
            printf("ワンペア\n");
            break;
        }

        flushFlag = 1;

        for (i = 0; i < HAND_NUM - 1; i++) {
            if (hand[i].suit != hand[i + 1].suit) {
                flushFlag = 0;
                break;
            }
        }

        straightFlag = 1;

        for (i = 0; i < HAND_NUM - 1; i++) {
            if (hand[i + 1].number - hand[i].number != 1) {
                straightFlag = 0;
                break;
            }
        }

        if (flushFlag == 1 && straightFlag == 1) {
            printf("ストレートフラッシュ\n");
            break;
        }

        if (flushFlag == 1) {
            printf("フラッシュ\n");
            break;
        }

        if (straightFlag == 1) {
            printf("ストレート\n");
            break;
        }

        printf("ノーペア\n");

        break;
    }


    return 0;
}

長かったですが、やっと完成しました。

これでも1回しかプレイできないですし、ベット(掛け金)などもありません。

ここから遊べるゲームにするには、まだまだ改良が必要です。

ここから先は皆さんで機能の追加などを試してみてください。


次へ

戻る

目次へ