Conway's Game of Life in Turing
Author |
Message |
Insectoid
|
Posted: Mon Jun 23, 2014 5:04 pm Post subject: Conway's Game of Life in Turing |
|
|
I had a little spare time today (which doesn't happen often), so I tried my own implementation of Conway's Game of Life in Turing. My goal for this was to keep the code very neat and legible and have a minimum of comments. I could've done a few extra things, like forwarding the functions & procedures and sorting the bodies into an ideal order but I didn't bother with that.
My original plan was to update all the cells with processes, because I rarely get to use them and it seemed an ideal time, but Turing couldn't handle that many processes running at once. I suppose I could limit it to n processes and have each do 1/nth of the cells but I got lazy and swapped to procedures. I'm not sure processes would help it run any faster anyway, depending on Turing's implementation of them.
You can define functions to seed a pattern if you like. I've included a function to seed a glider as an example. Alternatively, you can draw a bitmap image in paint where each white pixel is a dead cell and every other pixel is a live one. Save as 'seed.bmp' and put it in the same folder as the source file. If it fails to load, then it will default to a couple of gliders. I haven't tested the bitmap code yet, because Turing doesn't like bitmaps with negative heights, which are the only bitmaps that Mac software can create, for some reason. If someone tests this, please upload your seed image so I can. Use a neat pattern if you can, like a gun or pulsar.
Anyway, here's the code:
Turing: |
%Conway's Game of Life
%true is alive, false is dead
View.Set ("offscreenonly")
%size of the game grid
var width : int := 40
var height : int := 30
%2-d array represents the grid. 2nd grid is for back buffer. Each tick, the old grid becomes the buffer and the old buffer becomes the new grid.
var grid : array 0.. 1, 0..width- 1, 0..height- 1 of int
%Checks if cell (x, y) in the active grid is alive. Returns 1 for alive, 0 for dead.
function check_cell (x : int, y : int, active_grid : int) : int
if grid (active_grid, x mod width, y mod height ) > 0 then
result 1
end if
result 0
end check_cell
%checks all neighbors of cell (x,y) in the active grid and returns the number of live ones.
function count_living_neighbors (x : int, y : int, active_grid : int) : int
var living_neighbors : int := 0
living_neighbors + = check_cell (x- 1, y+ 1, active_grid )
living_neighbors + = check_cell (x- 1, y, active_grid )
living_neighbors + = check_cell (x- 1, y- 1, active_grid )
living_neighbors + = check_cell (x, y+ 1, active_grid )
living_neighbors + = check_cell (x, y- 1, active_grid )
living_neighbors + = check_cell (x+ 1, y+ 1, active_grid )
living_neighbors + = check_cell (x+ 1, y, active_grid )
living_neighbors + = check_cell (x+ 1, y- 1, active_grid )
result living_neighbors
end count_living_neighbors
%Updates cell (x,y) in the active grid according to the rules of the game. Was intended to be a process but Turing couldn't handle that many at once.
proc update_cell (x : int, y : int, active_grid : int)
var inactive_grid : int := active_grid *- 1 + 1
var living_neighbors : int := count_living_neighbors (x, y, active_grid )
%apply rules to cell
if grid (active_grid, x, y ) > 0 then
if living_neighbors < 2 or living_neighbors > 3 then grid (inactive_grid, x, y ) := 0
elsif living_neighbors = 2 or living_neighbors = 3 then grid (inactive_grid, x, y ) := 1
end if
else
if living_neighbors = 3 then grid (inactive_grid, x, y ) := 1
else grid (inactive_grid, x, y ) := 0
end if
end if
end update_cell
%updates the active grid
proc tick (active_grid : int)
for x : 0..width- 1
for y : 0..height- 1
update_cell (x, y, active_grid )
end for
end for
end tick
proc draw_grid (active_grid : int)
for x : 0..width- 1
for y : 0..height- 1
Draw.FillBox (x* 10, y* 10, x* 10+ 10, y* 10+ 10, grid (active_grid, x, y )+ 1)
end for
end for
end draw_grid
/*********************************
**pre-defined pattern functions**
*********************************/
proc insert_glider (x : int, y : int, active_grid : int)
grid (active_grid, x mod width, y mod height ) := 1
grid (active_grid, (x+ 1) mod width, y mod height ) := 1
grid (active_grid, (x+ 2) mod width, y mod height ) := 1
grid (active_grid, (x+ 2) mod width, (y+ 1) mod height ) := 1
grid (active_grid, (x+ 1) mod width, (y+ 2) mod height ) := 1
end insert_glider
%if seed.bmp exists it is copied to the grid. Otherwise it is initialized to gliders.
proc seed_grid (active_grid : int)
var seed_image : int := Pic.FileNew ("seed.bmp")
var pixel_color : int
if seed_image > 0 then
height := Pic.Height (seed_image )
width := Pic.Width (seed_image )
Pic.Draw (seed_image, 0, 0, picCopy)
for x : 0..width- 1
for y : 0..height- 1
pixel_color := whatdotcolor (x, y )
if pixel_color = 0 then
grid (active_grid, x, y ) := 0
else
grid (active_grid, x, y ) := 1
end if
end for
end for
else
for x : 0..width- 1
for y : 0..height- 1
for _grid : 0.. 1
grid (_grid, x, y ) := 0
end for
end for
end for
insert_glider (0, 0, 0)
insert_glider (10, 10, 0)
end if
end seed_grid
/********
**Body**
********/
%run the game
seed_grid (0)
var n := 0
loop
cls
tick (n )
draw_grid (n )
n := -n + 1 %swaps the active grid
View.Update
Time.DelaySinceLast (100)
end loop
|
|
|
|
|
|
|
Sponsor Sponsor
|
|
|
Nathan4102
|
Posted: Mon Jun 23, 2014 7:18 pm Post subject: RE:Conway\'s Game of Life in Turing |
|
|
Thats pretty awesome for a one day thing! I made a version of this, but it used the mouse as input instead of a file. If I get a bit of time later Ill make you a bmp of some sort of shooter if no-one has yet. |
|
|
|
|
|
Insectoid
|
Posted: Mon Jun 23, 2014 7:52 pm Post subject: RE:Conway\'s Game of Life in Turing |
|
|
More like a 1-hour thing . Did it on my lunch break. |
|
|
|
|
|
Srlancelot39
|
Posted: Mon Jun 23, 2014 10:19 pm Post subject: RE:Conway\'s Game of Life in Turing |
|
|
OMG! I did one of these in highschool! They're epic... |
|
|
|
|
|
|
|