見出し画像

テトリスでプログラミングを試そう(12)

こんにちは。
新年度ということもあり、バタバタ忙しいかもしれませんが、少しずつ進めるのを楽しんでもらえると嬉しいです。


今日は、ミノの種類を増やしてみましょう。
回転させる前のミノの初期形状を覚えておきたいので、class Mino が記録する情報を1つ増やします。
各 class が記録する情報のことを メンバ変数 と呼びます。
class Mino のメンバ変数は、これで4つになりました。
(後々の都合のため、class Mino に public を指定しておいて下さい。)

_init_8int という メンバ変数 を1つ追加しました。

メンバ変数に readonly と付いているものがありますが、これは、一度設定したらもう変更しないよ、という印を付けているだけです。
readonly を書かなくてもプログラムは正しく動作します。
例えば、Tミノを生成したならば、それは常に紫色となるので、ミノを一度生成したらその色の変更はしないよ、ということを宣言してるだけです。
どこかで間違えて _color を変更してしまって、バグが発生することを予防しているだけです。
また、プログラムを読むときにも、「_color は変更されないもの」と分かるので、プログラムが読みやすくなります。

readonly である _color や _init_8int は、Mino を生成すると同時に設定しなければなりません。生成した以降は変更できなくなりますので。
そのような特殊なメンバ変数のために、コンストラクタ というものがあります。前にも一度言いましたが、class 名と「同じ名前の関数」 のことです。
class Mino に、以下の5行を追加してください。

class Mino の コンストラクタ となります。

このとき、Set() の中に、エラー表示が出ていることに注目して下さい。

L146 にエラーを表す赤色の波線が出ています。

これは、_color が readonly であるため、ここで変更できない、ということを示しています。
では、Set() を書き換えて、回転したり落下したミノを初期状態に戻す Init() に作り変えましょう。

Set を Init に書き換えて、L146 を削除して、L149, L150 を少し変更しました。

では、コンストラクタ を実際に利用してみましょう。
class MainPage の中の3行だけ変更します。

L6, L18, L19 が変更点です。

ここで 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行変更します。

L6, L19, L21 が変更点です。

さらに、「Down to Bottom」ボタンを押したらミノが変更されるようにしてみます。
class MainPage に以下の5行を追加します。

class MainPage に追加します。

xaml ファイルに以下の1行を追加します。

MainPage.xaml に L56 の1行を追加します。

これで F5 キーを押すと、「Click to Down」ボタンを押すたびに新しいミノが表示され、移動や回転ができるようになります。
是非試してみてほしいです!

T ミノ以外のものを動かしてみてくださいね。

少しずつプログラムが複雑になってきましたが、オブジェクト指向で書いていると、ブロック毎に考えれば良いので、考えがまとまりやすいと思います。
「class の間でメッセージを渡しながら、プログラムの実行が進む」という感じでしょうか。
それでは、またよろしくお願いします!


この記事が気に入ったらサポートをしてみませんか?