Conway's Game of Life!
Author |
Message |
Lapsus Antepedis

|
Posted: Tue Aug 16, 2005 5:19 pm Post subject: Conway's Game of Life! |
|
|
I needed something to do, so I wrote Conway's Game of life. It runs really slowly, and it's tiny (the window.), but it works properly! ^.^
If anyone has any ideas on how to make it run faster, please let me know. I'm thinking of using pic.new and pic.scale to make it bigger, but then I'd need to create variables for each generation's picture and scaled picture...
I'm also thinking of trying to write a 3D version using vpython, but that'll be really slow and confusing
Oh well, here's the code
Turing: |
% Conway's Game of life!
% Coded by Lapsus Antepedis in 2005
var life : int := Window.Open ("graphics:200;200, title:Conway's Game of Life, noscrollbars")
View.Set ("offscreenonly")
%var stats : int := Window.Open ("graphics:300;400, title:Stats")
%% Some code for loading a picture to start with
% var pictor : int := Pic.FileNew ("conway.bmp")
% Pic.Draw (pictor, 0, 0, picCopy)
% Pic.Free (pictor)
type organism :
record
populated : boolean
buddies : int
end record
var cell : array 0 .. maxx, 0 .. maxy of organism
%var alive, died, born : int := 0
proc drawcells
% alive := 0
Window.SetActive (life )
for x : 0 .. maxx
for y : 0 .. maxy
if cell (x, y ).populated then
drawdot (x, y, 7)
% alive += 1
else
drawdot (x, y, 0)
end if
end for
end for
View.Update
end drawcells
proc buddycount
% empties array
for x : 0 .. maxx
for y : 0 .. maxy
cell (x, y ).buddies := 0
end for
end for
%counts buddies
for x : 2 .. maxx - 2
for y : 2 .. maxy - 2
if cell (x + 1, y ).populated then
cell (x, y ).buddies + = 1
end if
if cell (x - 1, y ).populated then
cell (x, y ).buddies + = 1
end if
if cell (x, y + 1).populated then
cell (x, y ).buddies + = 1
end if
if cell (x, y - 1).populated then
cell (x, y ).buddies + = 1
end if
if cell (x + 1, y + 1).populated then
cell (x, y ).buddies + = 1
end if
if cell (x - 1, y - 1).populated then
cell (x, y ).buddies + = 1
end if
if cell (x + 1, y - 1).populated then
cell (x, y ).buddies + = 1
end if
if cell (x - 1, y + 1).populated then
cell (x, y ).buddies + = 1
end if
end for
end for
end buddycount
proc cycle
% died := 0
% born := 0
for x : 0 .. maxx
for y : 0 .. maxy
%if populated
if cell (x, y ).populated then
%with less than 2 buddies
if cell (x, y ).buddies <= 1 then
%die
cell (x, y ).populated := false
% died += 1
%with more than 3 buddies
elsif cell (x, y ).buddies >= 4 then
%die
cell (x, y ).populated := false
% died += 1
%if 2 or 3 buddies
else
%live
cell (x, y ).populated := true
end if
end if
%if has 3 buddies
if cell (x, y ).buddies = 3 then
%live
cell (x, y ).populated := true
% born += 1
end if
end for
end for
end cycle
%% Some more code for starting with a picture
% for x : 0 .. maxx
% for y : 0 .. maxy
% if whatdotcolour (x, y) not= 0 then
% cell (x, y).populated := true
% else
% cell (x, y).populated := false
% end if
% end for
% end for
% Code for generating Random Start
for x : 0 .. maxx
for y : 0 .. maxy
if Rand.Int (1, 4) = 1 then
cell (x, y ).populated := true
else
cell (x, y ).populated := false
end if
end for
end for
%Window.SetActive (stats)
%locate (1, 1)
% put "Alive | Born | Died | Change"
% put "------+-------+-------+-------"
loop
drawcells
% Window.SetActive (stats)
% put alive : 6, "| ", born : 6, "| ", died : 6, "| ", born - died : 6
buddycount
cycle
end loop
|
|
|
|
|
|
 |
Sponsor Sponsor

|
|
 |
Cervantes

|
Posted: Tue Aug 16, 2005 9:12 pm Post subject: (No subject) |
|
|
Good job.
One thing that stood out to me was your many if statements to determine how many buddies any particular cell has. Instead of using many if statements, you can use two for loops:
code: |
for dx : -1 .. 1
for dy : -1 .. 1
if dx = 0 and dy = 0 then % We only want to check around the spot, not the spot itself
else
%check using the coordinate (x + dx, y + dy)
end if
end for
end for
|
I took this and then furthered it by, instead of constantly determining how many buddies each cell has, only update the tally when a change is made around the cell. Here's the code:
Turing: |
var life : int := Window.Open ("graphics:200;200, title:Conway's Game of Life, noscrollbars")
View.Set ("offscreenonly")
type organism :
record
populated : boolean
buddies : int
end record
var cell : array 0 .. maxx, 0 .. maxy of organism
for x : lower (cell, 1) .. upper (cell, 1)
for y : lower (cell, 2) .. upper (cell, 2)
cell (x, y ).buddies := 0
end for
end for
proc drawcells
for x : 0 .. maxx
for y : 0 .. maxy
if cell (x, y ).populated then
drawdot (x, y, 7)
else
drawdot (x, y, 0)
end if
end for
end for
View.Update
end drawcells
proc step_buddies_around (x, y, step : int)
for dx : max (1, x - 1) .. min (x + 1, maxx - 1)
for dy : max (1, y - 1) .. min (y + 1, maxy - 1)
if dx = x and dy = y then
else
cell (dx, dy ).buddies + = step
end if
end for
end for
end step_buddies_around
proc cycle
for x : 0 .. maxx
for y : 0 .. maxy
%if populated
if cell (x, y ).populated then
%with less than 2 buddies, or with more than 3 buddies
if cell (x, y ).buddies < 2 or cell (x, y ).buddies > 3 then
%die
cell (x, y ).populated := false
step_buddies_around (x, y, - 1)
end if
end if
%if has 3 buddies
if cell (x, y ).buddies = 3 then
%spawn new life
cell (x, y ).populated := true
step_buddies_around (x, y, + 1)
end if
end for
end for
end cycle
% Code for generating Random Start
for x : 0 .. maxx
for y : 0 .. maxy
if Rand.Int (1, 4) = 1 then
cell (x, y ).populated := true
step_buddies_around (x, y, + 1)
else
cell (x, y ).populated := false
end if
end for
end for
var current_time := Time.Elapsed
loop
View.Set ("title:" + realstr (Time.Elapsed - current_time, 0) + " ms")
current_time := Time.Elapsed
drawcells
cycle
end loop
|
My computer does a cycle every 450ms or so, though mine behaves a little different than yours. For some reason mine seems to create a "mat" of life, rather than distinct "clumps". Perhaps it has something to do with the way I've handled the edges? In any case, it begins in the same manner as yours and has a cycle every 900 ms, whereas yours started around 1150.
Good work. +15 bits.
EDIT: Modding/Donating bits isn't working now. I owe you.  |
|
|
|
|
 |
|
|