Elmでテトリスを作った話

Elmでテトリスを作った。この記事では実装にあたって考えたポイントをメモしておく。 コードは説明のために断片的に載せる。 製作物 ここで遊べる. Repositryはこちら。 実装しなければいけない処理 大まかに作らなければいけないのは以下の処理. ボード・テトリミノのデータ構造 テトリミノの出現・回転・落下・固定 テトリミノの衝突判定 ラインがそろった時に消滅する処理 ゲームオーバー処理 キー操作 画面描画 この中からいくつかの項目について説明する。 ボードのデータ構造 ボードの落とす場は10x20のブロックで構成されている。 壁をボードに含めるかどうか、上部にマージンを設けるかどうかで、実際のボードサイズは変わる。 まず、ボードのブロックをセルと呼ぶことにする。セルを次のように定義する。Colorは適当に定義しておく。 1 2 3 type Cell = Block Color | Empty このセルを使ってボードを定義したいが、悩ましい選択が現れる。 セルを要素に持つList。セルの座標はリストの添字で判断する。 (座標, セル)を要素に持つList。 キーを座標、値をセルとしたDict。 ListをArrayにした実装も考えられる。参考までに、3つは以下のように定義できる。 1 2 3 4 5 6 7 8 type alias Board = List Cell type alias Board = List { pos : Vec Int , cell : Cell } type alias Board = Dict (Vec Int) Cell ボードのデータ構造によって諸々の関数の実装方法が大きく変わってくるので、どれを選ぶか慎重になる必要がある。 2つ目と3つ目のデータ構造はelm-gamesのRepositoryに載っているテトリスのコードから発見した。 それらのコードを見つけた時にはすでに1番目で作ってしまっていたので、現状の自分の実装は1番目のものである。 TEAのView関数としての扱いやすさを考えるなら、2番目の実装が一番良いと思う。例えばセルの描画関数をviewCellとして、viewBoardは次のように書ける。 1 2 3 4 5 6 7 import Svg viewBoard : Board -> Svg Msg viewBoard board = Svg.g [] (List.map viewCell board) 他のデータ構造で実装する場合でも、viewBoardに渡す前に一旦{ pos, cell }のデータ構造に変換しておいた方が書きやすい。 ...

2021-08-10 · (updated 2021-08-10) · 8 min · 1571 words