とりあえず構造体に慣れてもらうことから始めましょう。
まずは次の構造体を作ってみてください。
タグ名 Card メンバ変数 int型でnumberとsuit 実体名 card
宣言を書いて、main関数で実体を作りましょう。
解答例です。
<sample program 101-01>
#include <stdio.h> struct Card { int number; int suit; }; int main(void) { struct Card card; return 0; } |
ここから、値を代入して単純に中身を表示するプログラムにしてみます。
numberを1に、suitを2に設定し表示します。
<sample program 101-02>
#include <stdio.h> struct Card { int number; int suit; }; int main(void) { struct Card card; card.number = 1; card.suit = 2; printf("number = %d\n", card.number); printf("suit = %d\n", card.suit); return 0; } |
<実行結果>
number = 1 suit = 2 続行するには何かキーを押してください・・・
変数や配列の場合、実体の作成時に初期値が代入できました。
<変数>
int a = 3;
<一次元配列>
int a[2] = { 1, 2 };
<二次元配列>
int a[3][2] = { { 1, 2 }, { 3, 4 }, { 5, 6 }, };
構造体も同じように初期値を代入できます。
<sample program 101-03>
#include <stdio.h> struct Card { int number; int suit; }; int main(void) { struct Card card = { 1, 2 }; printf("number = %d\n", card.number); printf("suit = %d\n", card.suit); return 0; } |
<実行結果>
number = 1 suit = 2 続行するには何かキーを押してください・・・
宣言時に書いたメンバ変数の順番に数値を入れておけば良いです。
さて、この構造体はカード1枚分のデータを入れることが出来ます。
このカードが52枚あればトランプのデッキが作れそうです。
そこで、Card構造体を配列にしてみます。
初期値や表示も変更しなければならないので、まずは実体を作るところまで書きましょう。
トランプの枚数52は#defineで定義したいところですが、コラム「#defineの罠」で書いたように定義してみましょう。
#include <stdio.h> #define NUMBER 13 #define SUIT 4 #define CARD (NUMBER * SUIT) struct Card { int number; int suit; }; int main(void) { struct Card deck[CARD]; return 0; } |
一種類のスートにつき1から13までの数がありますから52枚としています。
deckは配列ですから、メンバ変数にアクセスするには、
deck[0].number
や
deck[5].suit
などと指定します。
さて、初期値を代入してカードのデッキを作ってみましょう。
numberには1から13をsuitには0から3を入れることにします。
<suit> 0 スペード 1 ハート 2 ダイヤ 3 クラブ
上でやったような初期値の代入は厳しそうですね。
一応、実体の作成と同時に初期値を入れる方法を書いておきますが、あまり良くない方法だと思います。
<sample program 101-05>
#include <stdio.h> #define NUMBER 13 #define SUIT 4 #define CARD (NUMBER * SUIT) struct Card { int number; int suit; }; int main(void) { struct Card deck[CARD] = { { 1, 0 }, { 2, 0 }, { 3, 0 }, { 4, 0 }, { 5, 0 }, { 6, 0 }, { 7, 0 }, { 8, 0 }, { 9, 0 }, { 10, 0 }, { 11, 0 }, { 12, 0 }, { 13, 0 }, { 1, 1 }, { 2, 1 }, { 3, 1 }, { 4, 1 }, { 5, 1 }, { 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 10, 1 }, { 11, 1 }, { 12, 1 }, { 13, 1 }, { 1, 2 }, { 2, 2 }, { 3, 2 }, { 4, 2 }, { 5, 2 }, { 6, 2 }, { 7, 2 }, { 8, 2 }, { 9, 2 }, { 10, 2 }, { 11, 2 }, { 12, 2 }, { 13, 2 }, { 1, 3 }, { 2, 3 }, { 3, 3 }, { 4, 3 }, { 5, 3 }, { 6, 3 }, { 7, 3 }, { 8, 3 }, { 9, 3 }, { 10, 3 }, { 11, 3 }, { 12, 3 }, { 13, 3 }, }; return 0; } |
二次元配列の初期化と似ています。
ただ、こんな風に書きたくは無いですよね。
よく見ると一定の法則で数字が並んでいますので、プログラムを使ってスマートに設定したいところです。
分かった方は自分で作ってみてください。
まずは簡単そうなスートの方を考えてみましょう。
52枚のトランプを順番にみると、最初の13枚は0、次の13枚は1という具合に13ごとに1増えています。
方法は色々ありますが、52枚のカードの設定をするため、52回繰り返すプログラムを追加してみます。
<sample program 101-06>
#include <stdio.h> #define NUMBER 13 #define SUIT 4 #define CARD (NUMBER * SUIT) struct Card { int number; int suit; }; int main(void) { struct Card deck[CARD]; int i; for (i = 0; i < CARD; i++) { } return 0; } |
変数iが0から51まで変化しますので、それを利用してスートを初期化します。
対応させなければならない数値は以下のようになります。
※法則を見て、式を考えるという癖を身につけてください。
i suit 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 10 0 11 0 12 0 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 2 27 2 28 2 29 2 30 2 31 2 32 2 33 2 34 2 35 2 36 2 37 2 38 2 39 3 40 3 41 3 42 3 43 3 44 3 45 3 46 3 47 3 48 3 49 3 50 3 51 3
iの値が、
0〜12までの場合 suitは0 13〜25までの場合 suitは1 26〜38までの場合 suitは2 39〜51までの場合 suitは3
さて、どういった式を作ればiの値からsuitが導き出せるでしょうか?
考えてください。
解答例です。
i / 13 (小数点以下切り捨て)
i 0 / 13 = 0.000 1 / 13 = 0.077 2 / 13 = 0.154 3 / 13 = 0.231 4 / 13 = 0.308 5 / 13 = 0.385 6 / 13 = 0.462 7 / 13 = 0.538 8 / 13 = 0.615 9 / 13 = 0.692 10 / 13 = 0.769 11 / 13 = 0.846 12 / 13 = 0.923 13 / 13 = 1.000 14 / 13 = 1.077 15 / 13 = 1.154 16 / 13 = 1.231 17 / 13 = 1.308 18 / 13 = 1.385 19 / 13 = 1.462 20 / 13 = 1.538 21 / 13 = 1.615 22 / 13 = 1.692 23 / 13 = 1.769 24 / 13 = 1.846 25 / 13 = 1.923 26 / 13 = 2.000 27 / 13 = 2.077 28 / 13 = 2.154 29 / 13 = 2.231 30 / 13 = 2.308 31 / 13 = 2.385 32 / 13 = 2.462 33 / 13 = 2.538 34 / 13 = 2.615 35 / 13 = 2.692 36 / 13 = 2.769 37 / 13 = 2.846 38 / 13 = 2.923 39 / 13 = 3.000 40 / 13 = 3.077 41 / 13 = 3.154 42 / 13 = 3.231 43 / 13 = 3.308 44 / 13 = 3.385 45 / 13 = 3.462 46 / 13 = 3.538 47 / 13 = 3.615 48 / 13 = 3.692 49 / 13 = 3.769 50 / 13 = 3.846 51 / 13 = 3.923
何度も説明していますが、int型の割り算は小数点以下切り捨てです。
整数部分だけを見ると、ちゃんとスートの数字になっています。
それでは、この式を使ってスートの初期値設定をしましょう。
13は#defineでNUMBERと定義されていますよね。
<sample program 101-07>
#include <stdio.h> #define NUMBER 13 #define SUIT 4 #define CARD (NUMBER * SUIT) struct Card { int number; int suit; }; int main(void) { struct Card deck[CARD]; int i; for (i = 0; i < CARD; i++) { deck[i].suit = i / NUMBER; } return 0; } |
最後にnumberの設定をします。
分かった方は早速作ってください。
numberも同じループの中で設定します。
変数iと必要な数字の組み合わせは以下の通りです。
i number 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 1 14 2 15 3 16 4 17 5 18 6 19 7 20 8 21 9 22 10 23 11 24 12 25 13 26 1 27 2 28 3 29 4 30 5 31 6 32 7 33 8 34 9 35 10 36 11 37 12 38 13 39 1 40 2 41 3 42 4 43 5 44 6 45 7 46 8 47 9 48 10 49 11 50 12 51 13
iの値が、
0、13、26、39の場合 numberは1 1、14、27、40の場合 numberは2 2、15、28、41の場合 numberは3 ・ ・ ・ 12、25、38、51の場合 numberは13
さて、どういった式を作ればiの値からnumberが導き出せるでしょうか?
考えてください。
解答例です。
i % 13 + 1
i 0 % 13 = 0 + 1 = 1 1 % 13 = 1 + 1 = 2 2 % 13 = 2 + 1 = 3 3 % 13 = 3 + 1 = 4 4 % 13 = 4 + 1 = 5 5 % 13 = 5 + 1 = 6 6 % 13 = 6 + 1 = 7 7 % 13 = 7 + 1 = 8 8 % 13 = 8 + 1 = 9 9 % 13 = 9 + 1 = 10 10 % 13 = 10 + 1 = 11 11 % 13 = 11 + 1 = 12 12 % 13 = 12 + 1 = 13 13 % 13 = 0 + 1 = 1 14 % 13 = 1 + 1 = 2 15 % 13 = 2 + 1 = 3 16 % 13 = 3 + 1 = 4 17 % 13 = 4 + 1 = 5 18 % 13 = 5 + 1 = 6 19 % 13 = 6 + 1 = 7 20 % 13 = 7 + 1 = 8 21 % 13 = 8 + 1 = 9 22 % 13 = 9 + 1 = 10 23 % 13 = 10 + 1 = 11 24 % 13 = 11 + 1 = 12 25 % 13 = 12 + 1 = 13 26 % 13 = 0 + 1 = 1 27 % 13 = 1 + 1 = 2 28 % 13 = 2 + 1 = 3 29 % 13 = 3 + 1 = 4 30 % 13 = 4 + 1 = 5 31 % 13 = 5 + 1 = 6 32 % 13 = 6 + 1 = 7 33 % 13 = 7 + 1 = 8 34 % 13 = 8 + 1 = 9 35 % 13 = 9 + 1 = 10 36 % 13 = 10 + 1 = 11 37 % 13 = 11 + 1 = 12 38 % 13 = 12 + 1 = 13 39 % 13 = 0 + 1 = 1 40 % 13 = 1 + 1 = 2 41 % 13 = 2 + 1 = 3 42 % 13 = 3 + 1 = 4 43 % 13 = 4 + 1 = 5 44 % 13 = 5 + 1 = 6 45 % 13 = 6 + 1 = 7 46 % 13 = 7 + 1 = 8 47 % 13 = 8 + 1 = 9 48 % 13 = 9 + 1 = 10 49 % 13 = 10 + 1 = 11 50 % 13 = 11 + 1 = 12 51 % 13 = 12 + 1 = 13
13で割った余りは0〜12ですから、それに1を加えることで1〜13になります。
では、numberの設定をしましょう。
#include <stdio.h> #define NUMBER 13 #define SUIT 4 #define CARD (NUMBER * SUIT) struct Card { int number; int suit; }; int main(void) { struct Card deck[CARD]; int i; for (i = 0; i < CARD; i++) { deck[i].suit = i / NUMBER; deck[i].number = i % NUMBER + 1; } return 0; } |
トランプの初期値を設定するプログラムを題材にしてみましたが、後々トランプのゲームも作ってみましょう。