テトリスでプログラミングを試そう(12)
こんにちは。
新年度ということもあり、バタバタ忙しいかもしれませんが、少しずつ進めるのを楽しんでもらえると嬉しいです。
今日は、ミノの種類を増やしてみましょう。
回転させる前のミノの初期形状を覚えておきたいので、class Mino が記録する情報を1つ増やします。
各 class が記録する情報のことを メンバ変数 と呼びます。
class Mino のメンバ変数は、これで4つになりました。
(後々の都合のため、class Mino に public を指定しておいて下さい。)
メンバ変数に readonly と付いているものがありますが、これは、一度設定したらもう変更しないよ、という印を付けているだけです。
readonly を書かなくてもプログラムは正しく動作します。
例えば、Tミノを生成したならば、それは常に紫色となるので、ミノを一度生成したらその色の変更はしないよ、ということを宣言してるだけです。
どこかで間違えて _color を変更してしまって、バグが発生することを予防しているだけです。
また、プログラムを読むときにも、「_color は変更されないもの」と分かるので、プログラムが読みやすくなります。
readonly である _color や _init_8int は、Mino を生成すると同時に設定しなければなりません。生成した以降は変更できなくなりますので。
そのような特殊なメンバ変数のために、コンストラクタ というものがあります。前にも一度言いましたが、class 名と「同じ名前の関数」 のことです。
class Mino に、以下の5行を追加してください。
このとき、Set() の中に、エラー表示が出ていることに注目して下さい。
これは、_color が readonly であるため、ここで変更できない、ということを示しています。
では、Set() を書き換えて、回転したり落下したミノを初期状態に戻す Init() に作り変えましょう。
では、コンストラクタ を実際に利用してみましょう。
class MainPage の中の3行だけ変更します。
ここで F5 キーで実行してみて、エラーが発生せずに実行できることを確認しておいてください。
では、T ミノ以外のミノも追加しましょう。
今は、回転操作がまだ対応できていない I と O 以外の、T, J, L, S, Z の5種類のミノを扱うことにします。
そして、その5種類のミノは class Game で管理する ことにします。
class Game からミノを1つ取り出せるように GetNextMino() という関数も用意しておきましょう。
GetNextMino() は、呼び出されたら T, J, L, S, Z からランダムに1つ Mino を返すため、「戻り値 が Mino の関数である」と言われます。
また、その場合、プログラム中では「Mino GetNextMino()」と書いて定義します。
class Game は以下のようになります。
Iミノ と Oミノがないので、_mino[5] と _mino[6] には一時的な値を設定しておきます。
また、C# においては、上のように _rand.Next(0, 7) とすると、0から6まで の整数が得られます。
_rand.Next(a, b) とすると、a 以上 b 未満 の整数が得られるという仕様みたいです。なんだか間違えやすそうですので注意ですね。
public class Game
{
public const int Px_BLOCK = 25;
public const int Px_INNER_BLOCK = Px_BLOCK - 2;
readonly Mino[] _minos = new Mino[7];
readonly Random _rand = new Random();
public Game()
{
_minos[0] = new Mino(Colors.Violet, new int[] {1, 0, 0, 1, 1, 1, 2, 1});
_minos[1] = new Mino(Colors.Blue, new int[] {0, 0, 0, 1, 1, 1, 2, 1});
_minos[2] = new Mino(Colors.Orange, new int[] {0, 1, 1, 1, 2, 1, 2, 0});
_minos[3] = new Mino(Colors.Green, new int[] {0, 1, 1, 0, 1, 1, 2, 0});
_minos[4] = new Mino(Colors.Red, new int[] {0, 0, 1, 0, 1, 1, 2, 1});
_minos[5] = _minos[0];
_minos[6] = _minos[1];
}
public Mino GetNextMino()
{
Mino ret_mino = _minos[_rand.Next(0, 7)];
ret_mino.Init();
return ret_mino;
}
}
せっかくここまで来たので、T ミノ以外のミノを表示させてみましょう。
もう一度、class MainPage に手を入れます。
以下のように3行変更します。
さらに、「Down to Bottom」ボタンを押したらミノが変更されるようにしてみます。
class MainPage に以下の5行を追加します。
xaml ファイルに以下の1行を追加します。
これで F5 キーを押すと、「Click to Down」ボタンを押すたびに新しいミノが表示され、移動や回転ができるようになります。
是非試してみてほしいです!
少しずつプログラムが複雑になってきましたが、オブジェクト指向で書いていると、ブロック毎に考えれば良いので、考えがまとまりやすいと思います。
「class の間でメッセージを渡しながら、プログラムの実行が進む」という感じでしょうか。
それでは、またよろしくお願いします!