図1●今回作成する神経衰弱ゲーム
図2●プレーヤが保有するカードを表示するフォーム。
メインのフォームのカード表示方法を流用した
図3●VS .NETのクラスビューで,プロパティの追加を選択したところ
図4●プロパティを設定するウィザードの画面
リスト1●Form から継承して作ったPlayerクラスのコード
図5●ゲームの初期設定に必要な部品を追加したフォーム
図6●プレーヤ名を入力してもらう画面。
ユーザー数を5にしたので五つのテキスト・ボックスが表示されている。ユーザー数を多くした場合はウィンドウの大きさを変更すれば入力できる
リスト2●OKボタンのクリック・イベント・ハンドラ
 プログラミングの勉強は,少しずつ段階を踏んで学んでいくのが上達のコツです。例えば,最初に言語仕様を学び,次の段階でコンピュータに処理させたいことをプログラムに置き換える方法を学ぶ,とステップを踏んで学ぶのです。“習うより慣れろ”的に学習する場合でも,自分がどの段階にいるのかを意識しながら学習すれば効率が上がります。初めて見たステートメントを覚えたり,その使い方を覚えることに重点を置くか,プログラムのロジックを覚えることを中心に学習するか――同じプログラムを見るにしても,段階が違えば見所も違ってくるでしょう。今回は前回作った“トランプ・ゲームの素”を発展させて,神経衰弱ゲームを完成させます(図1[拡大表示])。

ゲームのプレーヤを考える

 前回は,52枚のトランプのカードを画面上に並べるところまで作りました。カードとしては,Labelクラスを継承したCardクラス*1を作成して使っています。カードには,スペードやハートといったマーク,1から13までの数字,表と裏,クリックすると裏返る,といった性質があります。

 今回はこれらのカードを使って,神経衰弱ゲームを作ります。カードは,すでにフォーム上に裏返しに並べてあるので,プレーヤがルールを考えれば,そのままでも神経衰弱ゲームはできます。

 しかし,2枚めくって同じ数字かどうか,次の順番はどのプレーヤか,各プレーヤが何組のカードを持っているのか,などといったことは人間が判断しなくてはなりません。今回は,この部分をプログラムにやってもらいます。

 さてプレーヤという言葉が出てきたところで,必要なプレーヤの性質を考えましょう。オブジェクト指向について慣れてきた皆さんなら,プレーヤ(Player)クラスを作るのだなと,ピンときたかもしれません。その通りです。

 クラスを作るということを念頭において,考えてみましょう。まず,自分がどのようなカードを持っているのか,覚えて表示する必要があります。複数のプレーヤで遊ぶので,自分の順番が何番目なのかといった情報も必要になります。カードを取得するといった処理も実行できなくてはなりませんし,もちろんプレーヤの名前も知っておく必要があります。

 これらのことから,プレーヤ(Player)クラスは,次のようなフィールドとメソッドを持つと考えられるでしょう。

・CardCount(持っているカードの枚数)

・Index(自分の順番)

・PlayerName(名前)

・AddCardメソッド(カードを取得する)

・持っているカードの表示手段

 カードの表示方法については,前回のものをほぼそのまま流用しましょう。つまりフォームにCardオブジェクトを追加して表示させるのです。このことからPlayerクラスはフォームを持つ必要があります。

 フォームを使う場合は,Formクラスを継承すれば楽です。フォームのタイトルには,誰の持っているカードなのかをわかるように表示します(図2[拡大表示])。

クラスにプロパティを組み込む

 プレーヤのクラスの中身は,だいたい思い浮かんだのではないでしょうか。さて,ここで少し注意すべきことがあります。前回はクラスのフィールドをそのまま外部から参照したり,変更できるようにしていました。しかし,実はこれはあまり良いことではありません。本来なら変更できないはずの変数が外部から変更されてしまう可能性があるからです。そこで必要になってくるのが,オブジェクトの性質を外部に伝えたり,外部から設定を変更する「プロパティ」です。

 プロパティは,外部から値を取得するときはgetアクセサを,値を設定するときはsetアクセサの処理を実行するメンバーです。通常はここで値のチェックなどを行います。

 言葉ではわかりにくいでしょうから,具体的にプロパティを組み込んだコードを書いてみましょう。まずは以下の1行を,前回作成したプログラムの最後の“}”の前に書いて,PlayerクラスをFormから継承して作っておきましょう。

class Player : Form{ }

 プロパティを追加するには,ウィザード機能を使います。慣れてくればウィザードは必要なくなりますが,書き方を覚えるまでウィザードを使えば,間違えることなくコードを作成できます。ウィザードを使うにはVisual Studio .NET(VS .NET)の,クラスビューを表示させます(図3[拡大表示])*2。ここでプレーヤ(Player)クラスを選択してマウスを右クリックし,ショートカット・メニューから[追加]-[プロパティの追加]を選択すると,「C#プロパティ ウィザード」が開きます(図4[拡大表示])。

 このウィザードでは,作成するプロパティの様々な性質を設定できます。ここでは,他のオブジェクトから参照できるようにするため「プロパティ アクセス」メニューで「Public」を,「プロパティの種類」は「int」(整数)を選んでください。「プロパティ名」は「Index」として,コメントに「プレーヤの順番(オブジェクト配列として使うときの配列番号)」などのメモを入力して「完了」ボタンをクリックします。すると,自動的にIndexの参照と設定のためのコードがCardクラス内に追加されます。

 getの後の{ }内には,このプロパティの値を取得しようとしたときに実行する処理を記述します。クラス内で使われるほかの変数を計算して値を返す場合などは,ここにその処理を書きます。setの後は,値を設定するときの処理を記述します*3

クラスのインタフェースとして複数のプロパティを組み込む

 ここでは,外部からはアクセスできないidという変数を作り,これをIndexプロパティとしましょう。Indexプロパティの中身は以下のようになります。

public int Index {
get{return id;}
set{id = value;}
}

idというのはクラス内で限定して使っている変数で,ここにプレーヤの順番を格納します。get内のreturnの後にidと記述して,外部にidの値を渡します。

 ところでset内ではvalueという変数を何も宣言しないで使っていますね。valueは,プロパティに設定された値が自動的に格納される特別な変数です。ここでは,この値をidに代入します。

 同様にして,プレーヤの名前やカードの枚数についてもプロパティを実装します。カードの枚数は,カードを取得したときに増加させて,オブジェクトの外部から値を変えられないようにgetアクセサだけを組み込みます。プレーヤの名前も,プレー中に変更することはないので,getアクセサだけを使います。フォームのタイトルと大きさは,オブジェクトの作成時に実行するコンストラクタに実装すればいいでしょう。なお,Playerオブジェクトのフォームを閉じられてしまうと,プログラムが正しく実行できなくなるので,閉じるボタンなどを表示しないようにしておく必要があります。そこで,PlayerオブジェクトのControlBoxプロパティをfalseにしておきます。以上をまとめると,Playerクラスはリスト1[拡大表示]のようになります。

ゲームの準備をプログラムする

 さて,複数のプレーヤでゲームをするには,プログラムに人数とそれぞれの名前を教えなくてはなりません。前回は,スタート・ボタンをクリックしていきなりフォーム上にカードを並べましたが,今回はカードを並べる前にプレーヤ名の取得などを行うようにします。この部分の手順を考えてみましょう。

 まず,プレーヤの人数を取得するために,テキスト・ボックスを表示します。次に,その人数ぶんだけプレーヤ名を設定できるようにします。最初の画面はテキストボックス,ボタン,人数の入力を促すためのラベルをそれぞれ一つずつ,次の画面は人数ぶんのテキストボックスとラベル,それにボタンが一つ必要です。

 とりあえず最初の画面で必要になる部品をフォーム上に追加しましょう。デザイン・ビューに切り替えて,それぞれの部品をツールボックスからドラッグアンドドロップし,大きさや位置を整えます(図5[拡大表示])。ボタンのTextを「OK」にし,テキストボックスのTextには“2”と書き込んでおきます。前回作成したスタート・ボタンは,ゲーム開始時には見えないようにプロパティ・ウィンドウでVisibleプロパティをFalseにしておいてください。人数や名前の入力を終えたときに見えるようにするわけです。

 次の画面では,プレーヤ名を入力してもらいます。プレーヤ名は,人数ぶん必要ですから,テキスト・ボックスも人数ぶん表示させます(図6[拡大表示])。

 最初の画面(図5)から,次のプレーヤ名入力の画面(図6)に移る処理は,図5のOKボタンのクリック・イベント・ハンドラに記述します。クリック・イベント・ハンドラは,デザイン・ビューでボタンをダブルクリックすると自動的に作成されます。

 プレーヤ名を記入してもらうテキストボックスは,Playerクラスのフォームに複数のCardオブジェクトを追加したときと同様に実装します。まずテキストボックスで配列を作り,個々のテキストボックスをFormに追加する処理を行って,適当な位置に配置します。ラベルも同様に実装します。ラベルの場合は,表示内容も設定します。

 先に設計したPlayerクラスのオブジェクトは,人数ぶん必要ですから,配列として利用できるように宣言しておいて,人数が決まった時点で要素数を宣言します。以上のことを整理して,初期設定用の処理を実装したのがリスト2[拡大表示]です*4