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


手札の交換の後半です。

作る前にゲームの流れをもう一度書いておきます。


<ゲームの流れ>

デッキを初期化する
 ↓
デッキをシャッフルする
 ↓
手札としてデッキの先頭から5枚配る
 ↓
変更するカードを選択する
 ↓
カードを変更する
 ↓
手役を判定する
 ↓
終了

 変更するカードを選択する

は前回完成しましたので、

 カードを変更する

という部分を作りましょう。


カードの変更は最大5枚ですので、5回繰り返すループを作り、手札を1枚ずつ調べていきます。

手札が選択させていたら、新しくデッキからカードを配ります。

まずは、手札を調べるループを作成しましょう。

<sample program 107-01>

#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;          /* カード選択用 */

    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;
            }
        }
    }

    /* 手札の表示 */

    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");
            }
        }
    }

    /* 手札の交換 */

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

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

            /* デッキから新しいカードを配る */
        }
    }

    return 0;
}

デッキは乱数でシャッフルされており、すでに5枚は手札として配られている状態です。

新しいカードはデッキの6枚目(添え字は5)から配り始めなければなりません。

しかも、手札を何枚変えるかによって配る枚数にも変化があります。

上で作ったループの変数iはhandの添え字として使いますので、デッキ用の添え字が必要になります。


カードの交換


デッキ用の添え字dealCountを作り、初期値を5にしておく。

新しいカードを配る必要が生じたら、dealCountが指すデッキの中身を手札にコピーし、dealCountを1増やす。

<sample program 107-02>

#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;       /* デッキ用 */

    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;
            }
        }
    }

    /* 手札の表示 */

    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++;
        }
    }

    return 0;
}

<実行結果>

ハ ー ト: 1
ク ラ ブ: 2
ダ イ ヤ: 4
ハ ー ト:10
スペード:10
0
ハ ー ト: 1 *
ク ラ ブ: 2
ダ イ ヤ: 4
ハ ー ト:10
スペード:10
1
ハ ー ト: 1 *
ク ラ ブ: 2 *
ダ イ ヤ: 4
ハ ー ト:10
スペード:10
5
続行するには何かキーを押してください・・・

実行結果は特に変化はありませんので、交換出来たかどうか不明です。

交換した後は、再度手札を表示して、中身を確認しましょう。

表示するプログラムは前に作っていますので、コピー&ペーストで作成します。

<sample program 107-03>

#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;       /* デッキ用 */

    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;
            }
        }
    }

    /* 手札の表示 */

    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; 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);
    }

    return 0;
}

<実行結果1>

ハ ー ト: 1
スペード: 1
ク ラ ブ: 3
ク ラ ブ: 5
スペード: 6
2
ハ ー ト: 1
スペード: 1
ク ラ ブ: 3 *
ク ラ ブ: 5
スペード: 6
3
ハ ー ト: 1
スペード: 1
ク ラ ブ: 3 *
ク ラ ブ: 5 *
スペード: 6
5
ハ ー ト: 1
スペード: 1
ク ラ ブ: 2
ク ラ ブ: 9
スペード: 6
続行するには何かキーを押してください・・・

カードの交換は上手くいっているようですが、ソートが崩れています。

新しくカードを配ったので、再度ソートをしなければなりません。

ソートもすでに作ってありますので、コピー&ペーストしてください。

<sample program 107-04>

#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;       /* デッキ用 */

    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;
            }
        }
    }

    /* 手札の表示 */

    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;
            }
        }
    }

    /* 手札の表示 */

    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);
    }

    return 0;
}

<実行結果>

ク ラ ブ: 1
ハ ー ト: 4
ハ ー ト: 5
ハ ー ト: 7
ダ イ ヤ: 7
1
ク ラ ブ: 1
ハ ー ト: 4 *
ハ ー ト: 5
ハ ー ト: 7
ダ イ ヤ: 7
2
ク ラ ブ: 1
ハ ー ト: 4 *
ハ ー ト: 5 *
ハ ー ト: 7
ダ イ ヤ: 7
5
ク ラ ブ: 1
スペード: 1
ハ ー ト: 7
ダ イ ヤ: 7
スペード: 9
続行するには何かキーを押してください・・・

結果はソートされ、見やすくなりました。

次回は役の判定を行います。


次へ

戻る

目次へ