Here the source:
REBOL [
Title: "A Variation on Conway's Game of Life "
Author: "Ayrris Aunario"
Email: aaunario@yahoo.com
Purpose: { A GUI implementation of a modified version of the popular cellular automaton system.
The rules: 1) Each cell (square) on the grid is either alive (blue) or dead (white)
2) For every iteration, each cell's next state depends on current state and # of live neighbors
a) if cell is alive, it stays alive <=> 2 or 3 neighbors are alive
b) if cell is dead, becomes alive <=> exactly 3 neighbors are alive
3) Each cell's 8 neighbors comprise of adjacent cells unless it is on the edge, then use wrap-around rule
Choose initial configuration of live cells (click cells to toggle between states) or "RANDOMIZE", start, and watch patterns emerge
}
Date: 20-Sep-2005/18:31:07-7:00
Version: 0.0.4
File: %game-of-life-variation.r
]
game_off?: true
gsl: 50 ;specify grid side-length (in cells)
csl: 10 ;specify cell side-length (in pixels)
game_off?: true
affected: copy [] ; used for keeping track of cells whose states might change for each iteration
alive: copy [] ; stores live cells
grid-pane: copy [] ; list of all cells on the grid
; make prototype cell
cell: make face [
id: none
size: as-pair (csl) (csl)
edge: none
offset: none
neighbors: copy []
nc: 0 ;count of cell's living neighbors
color: none
setneighbors: does [
for j -1 1 1 [
for k -1 1 1[
if any [j <> 0 k <> 0] [
posx: to-string (-1 * j + 1 + (offset/x / csl))
posy: to-string (k * -1 + 1 + (offset/y / csl))
if (to-integer posx) > gsl [posx: to-string 1]
if (to-integer posy) > gsl [posy: to-string 1]
if posx = "0" [posx: to-string gsl]
if posy = "0" [posy: to-string gsl]
append neighbors to-word rejoin ["cell" posx "x" posy]
]
]
]
]
ncreset: does [nc: 0]
nc++: does [nc: nc + 1]
;if cell is alive, tell each of its neighbors
sendstate: does [
append affected id
foreach n neighbors [
do in (get n) 'nc++
append affected n
]
]
;sets cell's state for next iteration based on number of neighbors
setns: does [
either show? [
either any [nc > 3 nc < 2][show?: false ][append alive id ]
][
if nc = 3 [
show?: true
append alive id
]
]
ncreset
]
feel: make feel [
engage: func [face action event] [
if action = 'down [
either face/color [
face/color: none
remove find alive face/id
][
append alive face/id
face/color: blue
]
show face
]
]
]
]
; function called to run 1 each iteration
run_step: does [
foreach a unique alive [
do in (get a) 'sendstate
]
clear alive
foreach af unique affected [do in (get af) 'setns ]
clear affected
]
auto_steps: does [
start_steps
forever [
if game_off? [break]
run_step
show cells
wait 0.01
]
]
stop_steps: does [
game_off?: true
foreach g grid-pane [g/show?: true g/color: none]
foreach a alive [set in (get a) 'color blue]
]
start_steps: does [
foreach g grid-pane [ g/show?: false g/color: blue]
foreach a alive [set in (get a) 'show? true]
auto-init?: true
]
;create the panel containing the grid of cells
cells: make face [
size: as-pair (gsl * csl) (gsl * csl)
offset: 0x0
edge: none
color: white
gll: as-pair csl csl
effect: [grid gll gll]
pane: grid-pane
]
window: make face [
size: 502x650
offset: 100x50
edge: make edge [
color: 0.0.0
size: 1x1
]
color: none
pane: [cells input-panel]
]
;function that initializes each cell in the grid
make-grid: func [g c /local p][
;show progress of cell initializatin
view/new p: layout [
h5 "Initializing Grid:"
progress snow 300x10
]
for x 1 g 1 [
for y 1 g 1 [
set in last p/pane 'data ((g * (x - 1) + y) / ( g ** 2))
show p
append grid-pane set (to-word rejoin ["cell" to-string x "x" to-string y]) make cell[
offset: as-pair (x - 1 * c) (y - 1 * c)
id: to-word rejoin ["cell" to-string x "x" to-string y]
setneighbors
]
]
]
unview p
]
;function for picking random initial configuration of live cells
randinit: has [randcellind numcellspicked p][
numcellspicked: random (gsl * gsl)
view/new p: layout [
h5 "Picking cells:"
progress snow 300x10
]
for i 1 (numcellspicked) 1 [
randcellind: random (gsl * gsl)
set in last p/pane 'data (i / numcellspicked)
show p
a: pick grid-pane (randcellind)
a/color: blue
append alive a/id
]
unview p
]
;function for clearing grid
clear-grid: does [
gameoff?: true
auto-init?: false
clear alive
clear affected
clear grid-pane
make-grid gsl csl
]
;panel containing various control buttons
input-panel: make face [
size: 500x150
offset: 0x500
edge: make edge [
color: black
size: 1x1
]
pane: reduce layout[
toggle "START" "STOP" [either game_off?: not value [stop_steps] [auto_steps]]
return
button "RUN 1 STEP" [if not game_off?[break] start_steps run_step stop_steps show cells]
return
button "CLEAR" [if not game_off? [break] clear-grid show cells]
return
button "RANDOMIZE" [if not game_off? [break] if not tail? alive [clear-grid] randinit show cells]
]
]
make-grid gsl csl
view window
No comments:
Post a Comment