Script Library: 1222 scripts
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

Archive version of: game-of-life-variation.r ... version: 3 ... aunario 17-Sep-2005

Amendment note: fixed problem caused by script checker replacing 'ignore with 'ignore || Publicly available? Yes

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: 16-Sep-2005/18:07-7:00
	Version: 0.0.3
	File: %game-of-life-variation.r
	Library: [
		Level: 'intermediate
		Platform: 'win
		Type: [demo fun game]
		Domain: [math gui game]
		Tested-under: none
		Support: none
		License: none
		See-also: none
	]
]


gsl: 50 	;specify grid side-length (in cells)
csl: 10 	;specify cell side-length (in pixels)

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: 10x10
	edge: none	
	offset: none
	neighbors: copy [] 
	nc: 0    ;count of cell's living neighbors
	state: 0
	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 rejoin ["cell" posx "x" posy] 
	 			]
			]
		]
	]



	
	ncreset: does [nc: 0]
	
	nc++: does [nc: nc + 1]
	
	setstate: func [st] [ 
		either st = 0 [
			color: none
		][
			if not find alive id [append alive id]
			color: blue
		]	
	state: st
	]
	
	;if cell is alive, tell each of its neighbors
	sendstate: does [
			if not find affected id [append affected id]
			foreach n neighbors [
				do in (get to-word n) 'nc++
				if not find affected n [append affected n] 
			]
	]

	;sets cell's state for next iteration based on number of neighbors
	setns: does [
		either state = 0 [
			if nc = 3 [setstate 1]
		][
			either any [nc > 3 nc < 2][
				setstate 0
			][
				if not find alive id [append alive id]
			]
		]	
		ncreset
	]
	
	feel: make feel [
		engage: func [face action event] [
			if action = 'down [
				either face/state = 0 [
					face/setstate 1
				][
					face/setstate 0
					remove find alive face/id
				]
			show face
			]
		]
	]
]	

; function called to run 1 each iteration
run_step: does [

		foreach a alive [
			do in (get to-word a) 'sendstate
		]
		clear alive
		
				
		foreach af affected [
			do in (get to-word af) 'setns
		]
		clear affected
] 

;create the panel containing the grid of cells
cells: make face [
	size: as-pair (gsl * csl) (gsl * csl)
	offset: 0x0
	edge: none
	color: white
	effect: [grid 10x10 10x10]
	pane: grid-pane
	rate: none
	

	;use time event to allow automatic iterations
	feel: make feel [
		engage: func [face action event][
			if action = 'time [
				run_step 
				show face				
			]
		]
	]


] 

window: make face [
	size: 502x600
	offset: 100x100 
	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][
	for x 1 g 1 [
		for y 1 g 1 [
			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: rejoin ["cell" to-string x "x" to-string y]
				setneighbors
			]	
		]
	]
]

;function for allowing random initial configuration of live cells
randinit: has [rand][
	for i 1 (random (gsl * gsl)) 1 [
		rand: random (gsl * gsl)
		a: pick grid-pane (rand)
		a/setstate 1
	]
]
		
;panel containing various control buttons
input-panel: make face [
	size: 500x100
	offset: 0x500
	edge: make edge [
		color: black
		size: 1x1
	]
	pane: reduce layout[
		toggle "START" "STOP" [either value [cells/rate: 2 ][cells/rate: none] show window] 
		return
		button "RUN 1 STEP" [run_step show cells]
		return
		button "CLEAR" [clear alive clear affected clear grid-pane make-grid gsl csl show cells]
		return
		button "RANDOMIZE" [randinit show cells]
	]	
]

make-grid gsl csl
view window