はじめに
ライフゲームについて書きます。なんだか申し訳ない気持ちでいっぱいなのはなぜなんでしょう。。。
経緯
メモを整理していたところ、ライフゲームの実装メモを見つけました。今回はライフゲームについて書きたいと思います。
これは2009年1月ごろに実装したものです。当時の私はWindows XPを使っていました。プログラミングに不慣れで、開発環境を構築することもむずかしかったと記憶しています。
そのため、Excel 2003のマクロで実装しました。この理由はExcel 2003を使うと、むずかしそうなGUIの実装を省略できそうだと見込んだことと、Excelのマクロなら開発環境を構築する必要がなかったからです。つまり、お手軽だったからです。
きっかけは戸田盛和さんの「ソリトン,カオス,フラクタル」です。この本にライフゲームのことが書かれてあり、これなら実装できるかもしれないと思ったからです。
仕様
ライフゲームを参照しました。これを自分なりに意訳すると次のようになりました。
- 碁盤のような格子があり、一つの格子をセルとみなす。
- 各セルには「生」と「死」の2つの状態がある。
- 各セルのまわりには8つのセルがある。(ムーア近傍)
- あるセルの次のステップ(世代)の状態は、ムーア近傍によって決定される。
- 初期状態のみでその後の状態が決定される。
状態遷移のルールは次のようになります。
- 誕生: 死んでいるセルに隣接する生きたセルがちょうど3つあれば、次の世代が誕生する。
- 生存: 生きているセルに隣接する生きたセルが2つか3つならば、次の世代でも生存する。
- 過疎: 生きているセルに隣接する生きたセルが1つ以下ならば、過疎により死滅する。
- 過密: 生きているセルに隣接する生きたセルが4つ以上ならば、過密により死滅する。
実装
この仕様を実装すると、次のような実装になりました。ポイントは生きたセルが2と3のときです。
lifegame.vba
' マクロオプションでショートカットキーを設定することを推奨します。
' 条件付き書式の設定を推奨します。
' 次のようなパターンの場合、有限個のパターンが周期的にあらわれます。
' 0 0 0 0 0 0 0 0
' 0 0 0 0 1 0 0 0
' 0 0 0 1 0 0 0 0
' 0 0 1 0 0 0 0 0
' 0 0 0 1 0 0 0 0
' 0 0 0 0 1 0 0 0
' 0 0 0 0 0 0 0 0
Sub lifegame()
' set table size
Dim l As Integer
l = 30
ReDim table(l + 2, l + 2) As Integer
ReDim dummytable(l, l) As Integer
' set upper left
Dim xs As Integer
Dim ys As Integer
xs = 2
ys = 2
' copy a cell value on worksheet to an element of table variable
For i = 1 to l
For j = 1 to l
table(i, j) = Cells(ys + i - 1, xs + j - 1).Value
Next
Next
' set boundary condition
table(0, 0) = 0
table(0, l + 1) = 0
table(l + 1, 0) = 0
table(l + 1, l + 1) = 0
For i = 1 to l
table(i, 0) = 0
table(i, l + 1) = 0
Next
For j = 1 to l
table(0, j) = 0
table(l + 1, j) = 0
Next
' here is logic in this program.
' relate table(i, j) to dummytable(i-1, j-1)
For i = 1 to l
For j = 1 to l
dummytable(i - 1, j - 1) = table(i - 1, j - 1) _
+ table(i , j - 1) _
+ table(i + 1, j - 1) _
+ table(i - 1, j) _
+ table(i + 1, j) _
+ table(i - 1, j + 1) _
+ table(i , j + 1) _
+ table(i + 1, j + 1)
Next
Next
' classify the result of evaluation
For i = 1 to l
For j = 1 to l
Select Case dummytable(i - 1, j - 1)
Case 2
dummytable(i - 1, j - 1) = table(i, j)
Case 3
dummytable(i - 1, j - 1) = 1
Case Else
dummytable(i - 1, j - 1) = 0
End Select
Next
Next
' copy a result of classification to a cell value on worksheet
For i = 1 to l
For j = 1 to l
Cells(ys + i - 1, xs + j - 1) = dummytable(i - 1, j - 1)
Next
Next
End Sub
実行環境
- Windows XP
- Excel 2003