ライフゲーム
Conwayのライフゲーム(セルオートマトン)をVue 3 + Vuetifyで実装したシミュレーターです。グリッドサイズやシミュレーション速度を自由に調整できます。
ライフゲームを試すライフゲームとは
ライフゲーム(Conway's Game of Life)は、イギリスの数学者ジョン・コンウェイが1970年に考案した、生命の誕生と死を単純なルールで表すシミュレーションです。マス目(セル)の1つ1つが「生きている」か「死んでいる」かのどちらかの状態を持ち、周りのセルの状態によって次の世代の状態が決まります。
プレイヤーが操作するのは最初の配置だけで、あとはルールに従って自動で世代が進みます。それでも、配置によっては形を保ったまま動き続けたり、点滅を繰り返したり、やがてすべて消えたりと、さまざまな動きが生まれます。単純なルールから複雑な振る舞いが生まれる例として、数学や計算機科学の分野でよく取り上げられます。
ルール
各セルは、上下左右と斜めの合わせて8つの隣のセルのうち、生きているセルがいくつあるかで次の世代の状態が決まります。
- 誕生:死んでいるセルの周りに、生きているセルがちょうど3つあると、次の世代で生まれます。
- 生存:生きているセルの周りに、生きているセルが2つか3つあると、次の世代でも生き残ります。
- 過疎:生きているセルの周りに、生きているセルが1つ以下だと、次の世代で死にます。
- 過密:生きているセルの周りに、生きているセルが4つ以上あると、次の世代で死にます。
このシミュレーターでは、マス目の外側はすべて死んでいるセルとして扱います(端と反対側の端はつながっていません)。
使い方
- マス目をクリック(タップ)して、生きているセル(青)と死んでいるセル(白)を切り替え、最初の配置を作ります。
- 「Height」「Width」で、マス目の縦と横の数を1〜100の範囲で変えられます。
- 「Generation Interval」のスライダーで、世代が進む間隔を0.1秒〜1.0秒の間で調整します。
- 「start」を押すとシミュレーションが始まり、「stop」で止まります。画面の下に、今が何世代目かが表示されます。
- 「Random」は約半分のセルをランダムに生きている状態にし、「Clear」はすべてのセルを消します。
試してみたい配置
グライダー
最初に表示されている、5つのセルでできた形が「グライダー」です。4世代ごとに同じ形に戻りながら、斜め下に1マスずつ進んでいきます。このシミュレーターでは端が壁になっているので、グライダーは右下の隅にぶつかると、動かない4つのセルの塊(ブロック)に変わって止まります。
ブリンカー
横に3つ並べたセルは、次の世代で縦3つに、その次でまた横3つに戻り、点滅を繰り返します。周期2の「振動子」と呼ばれる形の、最も小さな例です。
ブロック
2×2の正方形に並べた4つのセルは、どのセルも周りに生きているセルがちょうど3つあるので、何世代たっても形が変わりません。このような形を「固定物体」と呼びます。
ランダムな配置
「Random」でマス目を埋めてから始めると、最初は激しく変化しますが、しばらくすると多くのセルが消え、ブロックやブリンカーのような安定した形だけが残ることがよくあります。マス目を大きくして、何世代目で落ち着くかを見てみるのもおすすめです。
作った理由
Vue 3 の Composition API と TypeScript を使ってみる題材として作りました。ライフゲームは、ルールは数行で書けるのに、マス目の表示、クリックでの編集、タイマーによる自動更新、設定の変更といった、画面を作るうえでの基本的な要素がひととおり含まれているので、フレームワークを学ぶのにちょうどよい大きさです。
工夫した点
ルールを画面から切り離してテストする
次の世代を求める処理は、画面の部品から切り離し、マス目を受け取って新しいマス目を返すだけの関数にしています。元のマス目を書き換えないので、ブロック・ブリンカー・グライダーといった動きの分かっている配置を入力して、結果が正しいかを自動テストで確かめられます。
速さの変更と連打に強いタイマー
世代を進めるたびに、次の更新を予約する作りにしています。一定間隔で呼び出し続ける方式と比べて、途中で速さを変えてもすぐに反映されます。また、開始と停止をすばやく繰り返したときに更新が二重に走らないよう、予約を必ず取り消してから始め直すようにしています。
おかしな入力から守る
マス目の大きさに負の数やとても大きな数を入れると、エラーになったり画面が固まったりします。そこで、入力された大きさを1〜100の範囲に収めてから反映するようにしました。
使用技術
- フレームワーク:Vue 3(Composition API)+ Vuetify
- 言語:TypeScript
- ビルド:Vite
- テスト:Vitest(ルールと画面の単体テスト)、Cypress(ブラウザを使ったE2Eテスト)
ソースコードは GitHub で公開しています。