手札の交換の後半です。
作る前にゲームの流れをもう一度書いておきます。
<ゲームの流れ>
デッキを初期化する ↓ デッキをシャッフルする ↓ 手札としてデッキの先頭から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 続行するには何かキーを押してください・・・
結果はソートされ、見やすくなりました。
次回は役の判定を行います。