2 -- original by Dave Bollinger <DBollinger@compuserve.com> posted to lua-l
3 -- modified to use ANSI terminal escape sequences
4 -- modified to use for instead of while
11 function delay() -- NOTE: SYSTEM-DEPENDENT, adjust as necessary
13 -- local i=os.clock()+1 while(os.clock()<i) do end
29 -- give birth to a "shape" within the cell array
30 function _CELLS
:spawn(shape
,left
,top
)
33 self
[top
+y
][left
+x
] = shape
[y
*shape
.w
+x
+1]
38 -- run the CA and produce the next generation
39 function _CELLS
:evolve(next)
40 local ym1
,y
,yp1
,yi
=self
.h
-1,self
.h
,1,self
.h
42 local xm1
,x
,xp1
,xi
=self
.w
-1,self
.w
,1,self
.w
44 local sum
= self
[ym1
][xm1
] + self
[ym1
][x
] + self
[ym1
][xp1
] +
45 self
[y
][xm1
] + self
[y
][xp1
] +
46 self
[yp1
][xm1
] + self
[yp1
][x
] + self
[yp1
][xp1
]
47 next[y
][x
] = ((sum
==2) and self
[y
][x
]) or ((sum
==3) and 1) or 0
48 xm1
,x
,xp1
,xi
= x
,xp1
,xp1
+1,xi
-1
50 ym1
,y
,yp1
,yi
= y
,yp1
,yp1
+1,yi
-1
54 -- output the array to screen
55 function _CELLS
:draw()
56 local out
="" -- accumulate to reduce flicker
59 out
=out
..(((self
[y
][x
]>0) and ALIVE
) or DEAD
)
68 local c
= ARRAY2D(w
,h
)
69 c
.spawn
= _CELLS
.spawn
70 c
.evolve
= _CELLS
.evolve
76 -- shapes suitable for use with spawn() above
78 HEART
= { 1,0,1,1,0,1,1,1,1; w
=3,h
=3 }
79 GLIDER
= { 0,0,1,1,0,1,0,1,1; w
=3,h
=3 }
80 EXPLODE
= { 0,1,0,1,1,1,1,0,1,0,1,0; w
=3,h
=4 }
81 FISH
= { 0,1,1,1,1,1,0,0,0,1,0,0,0,0,1,1,0,0,1,0; w
=5,h
=4 }
82 BUTTERFLY
= { 1,0,0,0,1,0,1,1,1,0,1,0,0,0,1,1,0,1,0,1,1,0,0,0,1; w
=5,h
=5 }
87 local thisgen
= CELLS(w
,h
)
88 local nextgen
= CELLS(w
,h
)
91 -- about 1000 generations of fun, then a glider steady-state
92 thisgen
:spawn(GLIDER
,5,4)
93 thisgen
:spawn(EXPLODE
,25,10)
94 thisgen
:spawn(FISH
,4,12)
98 write("\027[2J") -- ANSI clear screen
100 thisgen
:evolve(nextgen
)
101 thisgen
,nextgen
= nextgen
,thisgen
102 write("\027[H") -- ANSI home cursor
104 write("Life - generation ",gen
,"\n")
106 if gen
>2000 then break end
107 --delay() -- no delay