こんにちは
現在52枚のカードを使ったゲームを作成しています。
Sはスペード、Hはハート、Dはダイヤ、Cはクラブというようにアルファベット一文字を絵柄に見立てています。
下記のコードはまだ作成途中のコードなのですがカードの数値の初期化処理が冗長になってしまいROMとRAM上に大きなサイズを取ってしまいます。
*number[]配列宣言時に初期化を行ってしまっていることが原因なのですが、ビット演算を使用して初期化できればデータサイズは小さくできると思ったのですが
うまく格納する方法が浮かびません。
例えばinit_card関数内で*numberを初期化するとしてどのようにビット演算を使ってカードの数字を格納したらよいか思い浮かびません。
カードをどのように考えればビット演算を使用してうまく初期化できるかご教授願えないでしょうか。できればビット演算を使って下記コードと同じ処理が問題なくできるようにしたいです。
よろしくお願いいたします。
C
1#define _CRT_SECURE_NO_WARNINGS//scanf警告解除用 2#include <stdio.h> 3#include <stdlib.h> 4#include <time.h> 5 6#define CARD_MAX (52)//カード枚数 7#define SAME_SUIT (13)//同じ柄のカード枚数 8#define INIT_HAND (5)//初手 9 10/*構造体定義*/ 11typedef struct { 12 13 unsigned int hand_cnt;//手札カウンタ 14 unsigned char card_num[CARD_MAX];//カードの種類 15 16}PLAYER_DATA; 17 18/*変数宣言*/ 19unsigned char card_deck[CARD_MAX];//カードデッキ 20unsigned int rest_cnt;//デッキ残数カウンタ 21unsigned int turn_cnt;//ターンカウンタ 22 23char *number[] = { "1S", "2S", "3S", "4S", "5S", "6S", "7S", "8S", "9S", "10S", "11S", "12S", "13S",//スペード 24 "1C", "2C", "3C", "4C", "5C", "6C", "7C", "8C", "9C", "10C", "11C", "12C", "13C",//クラブ 25 "1D", "2D", "3D", "4D", "5D", "6D", "7D", "8D", "9D", "10D", "11D", "12D", "13D",//ダイヤ 26 "1H", "2H", "3H", "4H", "5H", "6H", "7H", "8H", "9H", "10H", "11H", "12H", "13H", };//ハート 27 28 29/*関数プロトタイプ宣言*/ 30void init_card(void); 31void draw_card(PLAYER_DATA *myhand); 32void output_hand(PLAYER_DATA *myhand); 33void cemetery_card(PLAYER_DATA* field, PLAYER_DATA* myhand, int *input_data); 34void delete_hand(PLAYER_DATA *myhand, int *input_data); 35 36/********************************/ 37/* メイン関数 */ 38/********************************/ 39int main(int argc, char*argv[]) 40{ 41 PLAYER_DATA myhand;//プレイヤーの手札構造体 42 PLAYER_DATA field_card;//場のカード構造体 43 44 int draw_cnt;//ドローカウンタ 45 int input;//プレイヤー入力 46 47 init_card();//デッキ初期化 48 myhand.hand_cnt = 0;//手札枚数初期化 49 field_card.hand_cnt = 0;//場のカード枚数初期化 50 turn_cnt = 1;//ターンカウンタ初期化(開始時を1ターン目とする) 51 52 /*カードを5枚ドロー*/ 53 for (draw_cnt = 0; draw_cnt < INIT_HAND; draw_cnt++) { 54 draw_card(&myhand); 55 } 56 /*場に出すカードをドロー*/ 57 draw_card(&field_card); 58 59 /*画面にカードを出力*/ 60 printf("******************************************************\n"); 61 printf("現在のターン:%dターン目\n", turn_cnt); 62 printf("******************************************************\n"); 63 printf("場のカード:\n"); 64 output_hand(&field_card); 65 printf("\nあなたの手札:\n"); 66 output_hand(&myhand); 67 68 while (1) { 69 /*************/ 70 /* 1ターン目 */ 71 /*************/ 72 printf("\n山札(残数) %d 枚\n", CARD_MAX - rest_cnt); 73 printf("\n【ルール】\n"); 74 printf("場のカードと同じ数字か同じスートの\n"); 75 printf("カードを捨てることができます。\n"); 76 printf("\n"); 77 printf("捨てるカード番号を入力してください:"); 78 scanf("%d", &input); 79 cemetery_card(&field_card, &myhand,&input);//card_dataの配列は[0~4]出力のため関数内で-1する 80 delete_hand(&myhand, &input); 81 turn_cnt++;//カードを捨てたら1ターン目終了 82 /****************/ 83 /*以下nターン目 */ 84 /****************/ 85 printf("******************************************************\n"); 86 printf("現在のターン:%dターン目\n", turn_cnt); 87 printf("******************************************************\n"); 88 printf("場のカード:\n"); 89 output_hand(&field_card); 90 printf("\nあなたの手札:\n"); 91 output_hand(&myhand); 92 printf("\n山札(残数) %d 枚\n", CARD_MAX - rest_cnt); 93 break; 94 } 95 96 printf("\nゲームクリアおめでとうございます。\n"); 97 printf("クリアするのに%dターンかかりました。\n", turn_cnt); 98 printf("このまま終了します。\n"); 99 100 /*デバッグ用*/ 101#if 1 102 int debag; 103 scanf("%d", &debag); 104#endif 105 return 0; 106} 107/********************************/ 108/* デッキシャッフル(初期化)関数 */ 109/********************************/ 110void init_card(void) { 111 112 int rnd;//ランダム値格納用変数 113 int tmp; 114 srand((unsigned)time(NULL)); 115 116 for (rest_cnt = 0; rest_cnt< CARD_MAX; rest_cnt++) {//デッキ初期化 117 118 card_deck[rest_cnt] = rest_cnt; 119 120 } 121 122 rest_cnt = 0;//初期残数0 123 124 for (rest_cnt = 0; rest_cnt < CARD_MAX; rest_cnt++) {//デッキシャッフル 125 126 rnd = rand() % (CARD_MAX); 127 tmp = card_deck[rest_cnt]; 128 card_deck[rest_cnt] = card_deck[rnd]; 129 card_deck[rnd] = tmp; 130 131 } 132 133 rest_cnt = 0; 134} 135 136/********************************/ 137/* ドローカード関数 */ 138/********************************/ 139void draw_card(PLAYER_DATA *myhand) { 140 141 myhand->card_num[myhand->hand_cnt] = card_deck[rest_cnt]; 142 143 myhand->hand_cnt++;//手札に一枚加える 144 rest_cnt++;//デッキから1枚カードを抜く 145 146} 147 148/********************************/ 149/* 手札表示関数 */ 150/********************************/ 151void output_hand(PLAYER_DATA *myhand) 152{ 153 unsigned int myhnd_cnt; 154 int select; 155 select = 0; 156 157 //ドローしたカード枚数分画面に表示 158 for (myhnd_cnt = 0; myhnd_cnt < myhand->hand_cnt; myhnd_cnt++) { 159 select++; 160 printf("(%d)%s", select, number[myhand->card_num[myhnd_cnt]]); 161 162 } 163 164 printf("\n"); 165} 166 167/********************************/ 168/* セメタリーカード関数 */ 169/********************************/ 170void cemetery_card(PLAYER_DATA *field, PLAYER_DATA *myhand,int *input_data) 171{ 172 //セメタリーのカードを選択された手札で更新 173 field->card_num[field->hand_cnt] = myhand->card_num[*input_data -1]; 174 field->hand_cnt++;//フィールドのカード列をずらす 175 176} 177 178/********************************/ 179/* 手札削除関数 */ 180/********************************/ 181void delete_hand(PLAYER_DATA *myhand, int *input_data) 182{ 183 unsigned int input_cnt; 184 185 //入力された選択肢のカードを起点に手札を一枚ずつずらす 186 for (input_cnt = *input_data-1; input_cnt < myhand->hand_cnt - 1; input_cnt++) { 187 myhand->card_num[input_cnt] = myhand->card_num[input_cnt + 1]; 188 } 189 myhand->hand_cnt--;//手札を一枚減らす 190}
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/02/07 11:10