game of life 7

212 行 × 212 列:


-- 世代番号の初期値
local n = 1
 
-- セルの一辺の長さを決める。
local sideLen = 1

-- ここに初代行列を入れる。
local mat_now = 
-- 例:
--[[
{{1,1,1}, 
 {1,1,1},
 {1,1,1}}
--]]

--行数、列数を取得する。
local rdim, cdim = #mat_now, #mat_now[1]

-- 同じサイズの空行列を作る。
local mat_void = {}
for r = 1, rdim do
   mat_void[r] = {}
   for c = 1, cdim do
      mat_void[r][c] = 0
   end
end

-- 現世代行列を描画する。
function on.paint(gc)    
   -- 世代数を表示する。
   gc:drawString(n, 1, 1, "top")
   
   -- 行列を描画する。
   for r = 1, #mat_now do
      for c = 1, #mat_now[1] do
         if mat_now[r][c] == 1 then
            gc:fillRect((c - 1) * sideLen, (r - 1) * sideLen, sideLen, sideLen)
         end
      end
   end
end

-- タイマーが動いたら
function on.timer()
   n = n + 1 -- 世代番号を 1 進める。
   mat_now = game_of_life(mat_now) -- 現世代行列を game_of_life 函数に読み込んで次世代行列を計算する。
   platform.window:invalidate()
end

-- enter キーでタイマーを開始する。 
function on.enterKey() 
   timer.start(0.01)
end

-- esc キーでタイマーを停止する。
function on.escapeKey() 
   timer.stop()
   platform.window:invalidate()
end

-- 現世代行列から次世代行列を求める部分プログラム
function game_of_life(mat_now)
   local mat_moore = mat_void

   -- ルール表を定義する。
   local mat_rule = {{0,0,0,1,0,0,0,0,0},  
                     {0,0,1,1,0,0,0,0,0}}
   
   -- ムーア近傍の和の行列を作る。
   for r = 1, rdim do 
      for c = 1, cdim do

         -- トーラス接続にする。
         local above, below, left, right 
         if r == 1    then above = rdim else above = r - 1 end
         if r == rdim then below = 1    else below = r + 1 end
         if c == 1    then left  = cdim else left  = c - 1 end
         if c == cdim then right = 1    else right = c + 1 end

         -- ムーア近傍の和を計算する。
         mat_moore[r][c] = mat_now[above][left] + mat_now[above][c] + mat_now[above][right] 
                         + mat_now[r][left]               +               mat_now[r][right]
                         + mat_now[below][left] + mat_now[below][c] + mat_now[below][right]
      end
   end
   local mat_next = mat_now
   
   -- 次世代行列を作る。
   for r = 1, rdim do 
      for c = 1, cdim do
         mat_next[r][c] = mat_rule[mat_now[r][c] + 1][mat_moore[r][c] + 1] 
      end
   end
   
   -- 次世代行列を返す。
   return mat_next 
end

参考:

新 Excelコンピュータシミュレーション -数学モデルを作って楽しく学ぼう-

新 Excelコンピュータシミュレーション -数学モデルを作って楽しく学ぼう-

  • 作者:三井 和男
  • 発売日: 2010/03/12
  • メディア: 単行本(ソフトカバー)
pp.144-166