game of life 5

nspire で作ったユーザー定義函数lua とを組み合わせる。
エミュレーターでわずか 23 行 × 35 列を 1 世代を更新するのに 0.1 秒もかかっている。
ハンドヘルド本体では遅すぎて使いものにならない。
こんなアルゴリズムではだめだということである。

Define game_of_life(mat)=
Func
:Local rdim,cdim,mat_top,mat_bottom,mat_temp,mat_left,mat_right,mat_torus,r,c,temp,mat_moore,mat,mat_rule,above,below,hidari,migi
:mat_moore:=mat
:rdim:=rowDim(mat)
:cdim:=colDim(mat)
:For r,1,rdim
:   For c,1,cdim
:      If r=1 Then
:         above:=rdim
:      Else
:         above:=r-1
:      EndIf
:      If r=rdim Then
:         below:=1
:      Else
:         below:=r+1
:      EndIf
:      If c=1 Then
:         hidari:=cdim
:      Else
:         hidari:=c-1
:      EndIf
:      If c=cdim Then
:         migi:=1
:      Else
:         migi:=c+1
:      EndIf
:      mat_moore[r,c]:=sum({mat[above,hidari],mat[above,c],mat[above,migi],mat[r,hidari],mat[r,migi],mat[below,hidari],mat[below,c],mat[below,migi]})
:©mat_moore[r,c]:=countIf({mat[above,hidari],mat[above,c],mat[above,migi],mat[r,hidari],mat[r,migi],mat[below,hidari],mat[below,c],mat[below,migi]},1)
:©mat_moore[r,c]:=mat[above,hidari]+mat[above,c]+mat[above,migi]+mat[r,hidari]+mat[r,migi]+mat[below,hidari]+mat[below,c]+mat[below,migi]
:   EndFor
:EndFor
:
:©次世代のmatをつくる。
:mat_rule:=[[0,0,0,1,0,0,0,0,0][0,0,1,1,0,0,0,0,0]]
:For r,1,rdim
:   For c,1,cdim
:      mat[r,c]:=mat_rule[mat[r,c]+1,mat_moore[r,c]+1]
:   EndFor
:EndFor
:Return mat
:EndFunc
platform.apiLevel = "2.4"
platform.window:setBackgroundColor(0x000000)
local sideLen = 9
local a
local n = 1
mat = var.recall("mat") -- nspire で用意した初代行列を lua へ読み込む。
function on.paint(gc)    
   gc: setFont("sansserif","r",24) -- 世代数を表示する。
   gc:setColorRGB(0x71C671)
   gc:drawString(n, 1, 1, "top")
   
   gc:setColorRGB(0xC0FF3E) -- 行列を描画する。
   for r = 1, #mat do
      for c = 1, #mat[1] do
         if mat[r][c] == 1 then
            gc:fillRect((c - 1) * sideLen, (r - 1) * sideLen, sideLen, sideLen)
         end
      end
   end
end
function on.enterKey() -- enter キーでタイマースタート
   timer.start(0.02)
end
function on.escapeKey() --esc キーで一時停止
   timer.stop()
end
function on.arrowLeft() -- 左矢印キーで別の乱数にリセット
   mat =math.eval("list▶mat(randInt(0, 1, 23 * 35), 35)")
   --mat =math.eval("list▶mat(floor(rand(23 * 35) + 0.4), 35)")
   n = 1
   var.store("a", mat) -- あとで確認できるよう保存しておく。
   platform.window:invalidate()
end
function on.timer()
   n = n+1
   var.store("mat", mat) -- タイマーがスタートしたら今の行列を nspire へ渡す。
   mat = math.eval("game_of_life(mat)") -- nspire に次世代行列を計算させ、計算された次世代行列を lua へ読み込む。
   platform.window:invalidate()
end