テトリスを作るの3
今日もテトリス。
全く知らなかったのだが、Wikipedia によると、テトリスには構成要素や色のガイドラインがあるんだそうだ。 それによると、昨日まで俺がパターンと言ってたのは、公式にはテトリミノというらしい。 何にでも名前があるもんだな。 その他、仕様面では
- 四角は回転しても変わらない
- 次のテトリミノを表示する
あたりが俺が考えてたのと違うところ。 四角の回転はもう昨日のでいいとしよう。 次に出てくるテトリミノの表示は、言われてみればあったような…。 ま、いいか。 こっちも、とりあえず無しで作って、後で気が向いたら実装してみよう。
で、昨日の続き。
移動/回転が出来るかどうかを、移動/回転したテトリミノがフィールドに存在できるかどうかで判断する。 これはつまり、テトリミノに該当するフィールド上の画素が空白かどうかで判断するってことだ。 この判断が出来るために、誰が何を知っていて何が出来ればいいかを考える。 登場人物それぞれの知っていることを最小限にすることを原則に考えると、
- 画素
-
空白なのか、埋まっているのか。 埋まっているとしたら何色か。 これらを状態と定義して、画素は、
- 自分の状態を知っている。
- 指定された状態に、自分を変えることが出来る。
- 自分の状態を問われて、答えることが出来る。
- テトリミノ
-
画素の集まりではなくて、フィールド上にテトリミノを表示するための情報とする。
- 自分のローカル座標群とオフセットと色を知っている。
- 自分の座標群を問われて、ローカル座標とオフセットから計算したフィールド座標群を答えることが出来る。
- 移動した結果のフィールド座標群を答えることが出来る。
- 回転した結果のフィールド座標群を答えることが出来る。
「フィールド座標群を答えることができる」 ってのが、微妙に違うレベルで出てくるのが気になるな。 移動と回転に対しては、移動/回転した結果のテトリミノを返すことにするか。 そうすれば、座標群を返す処理は一つで済むし。
- 自分のローカル座標群とオフセットと色を知っている。
- 自分の座標群を問われて、ローカル座標とオフセットから計算したフィールド座標群を答えることが出来る。
- 移動した結果のテトリミノを作ることが出来る。
- 回転した結果のテトリミノを作ることが出来る。
- フィールド
-
テトリミノから得た情報をもとに画素に指示を出す、テトリミノと画素の仲介役。
- フィールドを構成する画素を知っている。
- 現在のテトリミノを知っている。
- 現在のテトリミノを新しいテトリミノで置き換えることが出来る。
基本はこれだけ。 画素とテトリミノを知っていることで、以下が出来るようになる。
- テトリミノが存在できるかどうかの判断。
- テトリミノの表示/消去/固定ブロック化。
- テトリミノの移動/回転。
- テトリミノの落下。 特別なことをしなくても、出来なくなるまで下移動を繰り返せばいいだろう。
- 固定ブロックで行が埋まったかどうかの判断。
フィールドとテトリミノのやり取りをもう少し細かく言うと、存在可否の判断はこんな感じ。
- テトリミノからそのフィールド座標群と色を教えてもらい
- フィールド座標群の各画素に状態を問い合わせ、全てが固定ブロックでないことを確認する。
表示や消去も同様。
- テトリミノからそのフィールド座標群と色を教えてもらい
- フィールド座標群の各画素に、状態変更(色表示/空白/固定ブロック化)の指示を出す。
移動や回転はこんな感じ。
- まず現在のテトリミノに、移動/回転後のテトリミノを教えてもらう。
- 移動/回転後のテトリミノが存在可能かどうか判定し、存在可能なら以降の処理を進める。
- 現在のテトリミノを消す。
- 移動/回転後のテトリミノを現在のテトリミノとし、表示する。
ゲームとして必要なものもついでに考えよう。
- コントローラー
-
ゲームの進行役。
- ゲームを開始する。
- ゲームの時間を管理する。 だんだん速くするとか。
- プレーヤーの入力を受けて、フィールドに指示を出す。 テトリミノの移動とか回転とか落下とか。
- 時間の経過に従って、フィールドに状況変化の指示を出す。 具体的には、テトリミノの下移動。
- フィールドから消した行数の報告を受けて、スコアに連絡する。
- フィールドから新しいテトリミノの作成失敗の報告を受けて、ゲームを終了する。
- フィールド
-
次のテトリミノを誰が表示させるかでちょっと悩んだが、結局、フィールドに任せることにした。
- コントローラーの指示を受けて、フィールドを初期化する。 初期化とは、全ての画素を空白にし、最初のテトリミノを表示すること。
- コントローラーの指示を受けて、テトリミノを移動/回転/落下する。
- テトリミノを下移動して、移動できなかったら固定ブロック化する。
- テトリミノを固定ブロック化したら、新しいテトリミノをつくる。
- 新しいテトリミノを作れなかったら、そのことをコントローラーに報告する。
- 固定ブロックで行が埋まった場合は、その行を消し、上全体を一つ下にずらす。
- 行を消した場合は、消した行数をコントローラーに報告する。
- スコア
-
得点表示役。 採点方法は採点者だけが知っていればいいってことで、同時に消した行数による得点計算もこいつの仕事とする。
- 現在の得点を保持する。
- 消した行数を教えてもらい、保持している得点を更新する。
- 得点を表示する。
考えるだけってのも飽きてきたので、そろそろ実際のコードを書くか。 続きはまた明日。