ライフゲームを作る
ライフゲームというのは、画面上にパターンを表示させて、ルールに従ってパターンが変化していくというシミュレーションで、ちっともゲーム性は無いのですが、見た目が不思議なのと、如何に高速に実行するかチャレンジが楽しめるので、パソコン初期には随分と流行りました。
Apple][で最初に書いたのが、このライフゲームと潜水艦ゲームでした。どんな風に書いていったのかを記憶を辿ってみることにします。
ライフゲームのルールは
ライフゲーム
を読んでもらうとして、実際に見ることができるサイトがあったので、少し遊んでみてください。
ライフゲーム
使ったのは6K BASICです。本当は初期状態の設定から作ったほうが良いのでしょうが、そこはあっさりとランダムのみで、配置する数だけを入力してもらうようにしました。6K BASICではローレゾのみしか扱えないので、対象の大きさは40✕40です。端の処理はいろいろな流儀があった気がしますが、上下左右は繋がっているモデルにした覚えがあります。色も最初は白黒のみでした。
変数は奇数世代用と偶数世代用の2つを用意します。これを世代ごとに切り替えて使います。6K BASICは2次元配列が使えないので、配列添字はY✕40+Xとします。最初に乱数で初期状態を作るのですが、乱数系列の初期化がないので、念のためキー入力待ちをして、その間、乱数を生成し続けます。待ち時間が微妙に一定にならないので、これで乱数系列は掻き混ざります。
最初に初期化された配列の状態を読み出してグラフィック上に描画します。ここから次の世代の計算に入ります。二重FORループの内側で、今の世代のそれぞれの点の周囲8点の状態を調べて、次の世代の状態を書き込みます。周囲8点はXもYもラップアラウンドがあるので、ちょっとだけ面倒です。これですべての点を調べて次の世代のデータが揃ったところで、描画に戻ります。
基本はこれで全てです。条件判断をIFでやりがちですが、これを式で表現できると少しだけ速くなることが多いです。頭を捻って、ひとつ上の位置を調べるために添字が負の数になるような場合は+(40✕40)して(40✕40)で剰余(MOD)を取ると、うまくいくとか考えるわけです。
最初は世代数も何も気にしていなかったのですが、つけっぱなしだと32767を超えてエラーで止まったので、こういうところはシレッと0に戻してしまう処理を入れるとかしておきます。
配列変数に状態を持つのは汎用的で移植とかもし易いのですが、どうせ表示するのですから、表示されている物自身をデータとして使う手もあります。6K BASICは2ページ目の画面を扱えないので、今の世代の分は画面上のデータを使いますが、次の世代は配列のママが妥当な選択でした。こちらの方が少し速かったような気がしますが、どのくらいかはもう記憶の彼方です。
対象となるサイズが40✕40なのでBASICで動かすにはちょうど良い感じでした。ライフゲームは生存ルールをカスタマイズしたり、自分で色のルールを付け加えたりして、どのような違いが出るかを楽しむものです。その後10KBASICでハイレゾ版も作ってみましたが、対象が280✕180と、ぐっと広くなるので、1世代分の計算時間がかなりかかってしまい、見た目で楽しむどころではありませんでした。あっさりとBASICは諦めて、いくつかのコンパイラ言語でベンチマーク的に楽しんでいました。
ひとつの状態を記憶するのに普通は数バイト使うのですが、ここを1バイトに詰めたり、さらに1ビットまでにすると、どのくらい遅くなるかとか、条件で分岐するのか式で表すのかが影響するのかなど、処理系の癖を知るには丁度よい素材です。
最近は3Dバージョンも出ているようなので、ゴーグルでも手に入れたら作ってみようかな。
3次元ライフゲーム
ヘッダ画像は、
「未来と芸術展:AI、ロボット、都市、生命――人は明日どう生きるのか」
に出展されていたリアルとヴァーチャルのライフゲーム。これが何故か惹かれるんですよ。