プロデルでライフゲームを楽しむ

プロデルでライフゲームを楽しめるプログラムを作ってみました。

ライフゲームは、セルオートマトンを再現したシミュレーションの一種です。世界のセル(区画)の状態をマウス操作で作ることができ、その状態から進歩していく状況を再現できます。

プログラムではプロデルのキャンバス部品でセルの様子を描画して再生できます。また区画の状態をテキストファイルで保存したり読み込んだりして、様々なパターンで遊べます。

ライフゲーム – Wikipedia

プログラム

キャンバス部品を使ってこのシミュレーション内容を描画します。

世界幅は50
世界高さは50
メイン画面を表示する
世界を創造する

//初期セルの設定
「
    ■    ■
   ■    ■
   ■■■  ■■■
」を世界に設定する

待機する

世界とは
	+マップ
	+キャンバス

	自分を創造する手順
		マップは{}
		【縦】を1から世界高さまで増やしながら繰り返す
			マップ(縦)は{}
			【横】を1から世界幅まで増やしながら繰り返す
				ある生命という区画(横,縦,世界)を作る
				ある生命を更新する
				マップ(縦)(横)は、ある生命
			そして
		そして
		キャンバスを更新する
	終わり

	自分を、次へ、進歩させる手順
		生存マップは{}
		【縦】。【横】
		縦を1から[マップの個数]まで増やしながら繰り返す
			生存マップ(縦)は{}
			横を1から[マップ(縦)の個数]まで増やしながら繰り返す
				生存マップ(縦)(横)は、マップ(縦)(横)の生存
			そして
		そして
		縦を1からマップの個数まで増やしながら繰り返す
			横を1から[マップ(縦)の個数]まで増やしながら繰り返す
				【ある生命】は、マップ(縦)(横)
				ある生命から生存マップで周囲生存数を取得して個数とする
				ある生命の生存なら
					個数が3より大きければ	 //過密
						ある生命の生存は×
					他で個数が2より小さければ //過疎
						ある生命の生存は×
					そして
					//それ以外は生存
				そうでなければ
					個数が3なら	//誕生
						ある生命の生存は○
					そして
				そして
				ある生命を更新する
			そして
		そして
		キャンバスを更新する
	終わり
	自分を更新する手順
		【縦】を1から世界高さまで増やしながら繰り返す
			【横】を1から世界幅まで増やしながら繰り返す
				【ある生命】は、マップ(縦)(横)
				ある生命を更新する
			そして
		そして
		キャンバスを更新する
	終わり
	自分を、取得する手順
		空間は「」
		【縦】を1から世界高さまで増やしながら繰り返す
			行空間は「」
			【横】を1から世界幅まで増やしながら繰り返す
				【ある生命】は、マップ(縦)(横)
				ある生命の生存なら
					行空間=行空間&「■」
				でなければ
					行空間=行空間&「 」
				そして
			そして
			空間=空間&[行空間から右スペースを消したもの]&改行
		そして
		空間を返す
	終わり
	自分に【空間】を、設定する手順
		縦=1
		横=1
		文字位置を1から空間の文字数まで増やしながら繰り返す
			セル値は、空間の[文字位置]文字目
			空間の[文字位置]文字目から2文字取り出したものが改行なら
				縦を増やす
				横=1
				文字位置を増やす
				繰り返しを続ける
			他でセル値が「 」なら
				マップ(縦)(横)の生存は、×
			でなければ
				マップ(縦)(横)の生存は、○
			そして
			横を増やす
		そして
		世界を更新する
	終わり

	自分をクリアする手順
		【縦】を1から世界高さまで増やしながら繰り返す
			【横】を1から世界幅まで増やしながら繰り返す
				【ある生命】は、マップ(縦)(横)
				ある生命の生存は×
				ある生命を更新する
			そして
		そして
		キャンバスを更新する
	終わり
終わり

区画とは
	+横位置
	+縦位置
	+生存
	+世界
	+図形

	はじめ(X,Y,世界)の手順
		横位置=X
		縦位置=Y
		世界のキャンバスに四角形を描いて図形とする
		図形の位置と大きさは{(X-1)*10,(Y-1)*10,10,10}
		自分の世界は、世界
	終わり
	自分を、更新する手順
		生存なら
			図形の背景色は、黄緑
		でなければ
			図形の背景色は、黒
		そして
	終わり

	【生存マップ】で、自分から、周囲生存数を、取得する手順
		【個体数】は、0
		【Y】を(縦位置-1)から(縦位置+1)まで増やしながら繰り返す
			Yが0以下なら
				縦=生存マップの個数+Y
			他でYが生存マップの個数より大きければ
				縦=Y-生存マップの個数
			でなければ
				縦=Y
			そして
			【X】を横位置-1から横位置+1まで増やしながら繰り返す
				Yが縦位置かつXが横位置なら繰り返しを続ける
				Xが0以下なら
					横=生存マップ(縦)の個数+X
				他でXが生存マップ(縦)の個数より大きければ
					横=X-生存マップ(縦)の個数
				でなければ
					横=X
				そして
				生存マップ(縦)(横)なら
					個体数を増やす
				そして
			そして
		そして
		個体数を返す
	終わり
終わり

メイン画面とは
ウィンドウを継承する

はじめ手順
	初期化する
	世界のキャンバスは、キャンバス1
	タイマー1というタイマーを作る
	タイマー1の間隔は50
終わり

初期化する手順
		ーー自動生成された手順です。ここに書き加えたプログラムは消える可能性があります
		初期化開始する
		この実質大きさは{663,501}
		この初期位置は「中央」
		この内容は「ライフゲーム」
		このドラッグドロップは○
		この文字色は「標準の文字」
		キャンバス1というキャンバスを作る
			その位置と大きさは{0,0,663,441}
			その自動更新は×
			その移動順は3
			その文字色は「標準の文字」
			そのドッキング方向は「全体」
		パネル1というパネルを作る
			その位置と大きさは{0,441,663,60}
			その移動順は4
			その文字色は「標準の文字」
			そのドッキング方向は「下」
			開くボタンというボタンをパネル1へ作る
				その位置と大きさは{435,6,83,48}
				その内容は「開く」
				その移動順は2
				その文字色は「標準の文字」
			保存ボタンというボタンをパネル1へ作る
				その位置と大きさは{346,6,83,48}
				その内容は「保存」
				その移動順は2
				その文字色は「標準の文字」
			クリアボタンというボタンをパネル1へ作る
				その位置と大きさは{187,6,126,48}
				その内容は「クリア」
				その移動順は1
				その文字色は「標準の文字」
			進歩ボタンというボタンをパネル1へ作る
				その位置と大きさは{31,6,126,48}
				その内容は「再生する」
				その移動順は1
				その文字色は「標準の文字」
		初期化終了する
		この設計スケール比率は{144,144}
	終わり

	進歩ボタンがクリックされた時の手順
		タイマー1が動作中なら
			タイマー1を停止する
			進歩ボタンの内容は「再生する」
		そうでなければ
			タイマー1を開始する
			進歩ボタンの内容は「停止する」
		そして
	終わり
	タイマー1が時間になった時の手順
		世界を次へ進歩させる
	終わり

	キャンバス1のマウスのボタンが押された時の手順
		座標は、この時の座標
		【横:整数】は(座標の横/10)+1
		【縦:整数】は(座標の縦/10)+1
		横が世界幅より大きいまたは縦が世界高さより大きければ返す
		【ある生命】は、世界のマップ(縦)(横)
		ある生命の生存は、ある生命の生存でない
		ある生命を更新する
		キャンバス1を更新する
	終わり
	クリアボタンがクリックされた時の手順
		世界をクリアする
	終わり
	保存ボタンがクリックされた時の手順
		保存画面のフィルタは「テキストファイル|*.txt|すべてのファイル|*.*」
		保存するファイルを選択して、ファイル名とする
		ファイル名が無でなければ
			世界を取得したものをファイル名へ保存する
		そして
	終わり
	開くボタンがクリックされた時の手順
		開く画面のフィルタは「テキストファイル|*.txt|すべてのファイル|*.*」
		開くファイルを選択して、ファイル名とする
		ファイル名が無でなければ
			ファイル名から読み込んで世界に設定する
		そして
	終わり
終わり

遊び方

実行すると格子状の黒い画面が表示されます。マウスでクリックすると、区画(セル)の色が切り替わります。

[再生]ボタンをクリックすると、区画の色が変化してセルオートマトンが動き始めます。

[クリア]で区画をクリアできます。また[保存]ボタンで世界をテキストファイルとして保存でき、[開く]ボタンで保存した世界を読み込むことができます。

ライフゲームのアルゴリズム

ライフゲームのアルゴリズムで重要な部分は、プログラム中の「世界」種類と「区画」種類に定義しています。

ライフゲームの「世界」には、格子状の「区画」があり、それぞれの区画に「生」と「死」のどちらかの状態を持っています。世界が進歩する時には、最初の区画の状態から次の区画の状態が決まります。それぞれの区画の状態は、その区画の上下左右の隣接する8つの区画の生存数によって決まります。

ライフゲームの法則は、次の4つです。

  • 過疎・・・生きている区画に隣接する生きた区画が1つ以下ならば、過疎により死滅する。
  • 過密・・・生きている区画に隣接する生きた区画が4つ以上ならば、過密により死滅する。
  • 生存・・・生きている区画が過疎か過密でなければ、そのまま生存する。
  • 誕生・・・生きていない区画に隣接する生きた区画がちょうど3つあれば、次の世代が誕生する。

生死は「世界」種類の「次へ進歩させる」手順で判定します。

また区画に隣接する生きた区画の数は、「区画」種類の「周囲生存数を取得する」手順で数えます。

世界が進歩する度に、上記の法則で区画が増殖したり減ったりします。このプログラムでは[再生]ボタンをクリックすると、タイマーによって一定間隔で世界が進歩します。

面白いパターン

有名なパターンを挙げましたのでテキストファイルとして保存して、ライフゲームで開いて再生して動きを見てみましょう。

グライダー

特定の方向に移動していくパターンです。




    ■    ■
   ■    ■
   ■■■  ■■■

ペンタデカスロン(振動子)

特定の法則でパターンがループします。

ペンタデカスロン – Wikipedia





                           ■  ■    ■  ■  
                         ■■■  ■■■■■■  ■■■
                           ■  ■    ■  ■  
                                         
  ■  ■    ■  ■                           
■■■  ■■■■■■  ■■■  ■                      
  ■  ■    ■  ■   ■                       
                 ■■■                     

ゴスパーのグライダー銃

グライダーを無限に生成するパターンです。

なおこのプログラムでは世界の四方が繋がっている仕様のため、しばらく実行すると、パターンが破壊されてしまいます。


                           ■
                         ■ ■
               ■■      ■■            ■■
              ■   ■    ■■            ■■
   ■■        ■     ■   ■■
   ■■        ■   ■ ■■    ■ ■
             ■     ■       ■
              ■   ■
               ■■

まとめ

ここで挙げたパターン以外にも、LifeWiki (conwaylife.com)には、ライフゲームの様々なパターンが掲載されています。紹介されているパターンをマウスで設定したり、あらかじめテキストファイルに入力したものを開いたりすることで、このプログラムでも再現できます。色々なセルオートマトンの動きを楽しんでみてください。

プロデルは、このようにアルゴリズムを実装したプログラムを日本語で作れるだけでなく、ファイルの読み書きや文字列操作など実用的なツールとして必要な機能も日本語で用意されています。ぜひこのプログラムを改造したり、さらに有名なアルゴリズムを日本語でプログラミングしたりしてみてください。

  • いいね (2)
  • 続編を読みたい (0)

“プロデルでライフゲームを楽しむ” への1件の返信

  1. こんにちは。アークです。

    ライフゲームという名前は勿論知ってはいるのですが、
    これまで一度も触った事が有りません。
    今回、初めてどのようなものかを知りました。
    これはゲームでは無いようですね。
    シミュレーションして何かを発見するプログラムのようですが、
    想像していたものと違ったのでどの様にしたら良いものか…。

    ところでこのプログラムは1.9シリーズでは動きますが、
    2.0シリーズでは「続ける」がエラーになります。

コメントを残す