[REBOL] [SCRIPT]Game of Life in /View
From: coussement::c::itc::mil::be at: 4-May-2001 11:26
hi list:
Just for the fun of learning /View, I've just hack a *Game of Life* ...
Thanks again to Anton for helping me for the dynamic refresh of the panel.
Just Copy&Paste and enjoy it !
<script>
rebol [
title: "Game of Life"
date: 03-may-2001
file: %gol.r
author: "C. COUSSEMENT"
email: [coussement--c--itc--mil--be]
comment: {Game of Life is a cellular automaton on an infinite quadratic
grid.
Each grid cell is either alive/on or dead/off.
The new state of each cell is computed in discrete timesteps
and is
determinated by it's old state and the sum of the alive cells
among
its surrounding 8 nearest neighbours cells. All these changes
are
simultaneously over the whole, infinite grid! - which can be
only simulated !
The Game of Life rules let a cell in the next generation only
alive if
a living cell is either surrounded by either 2 or 3 alive
cells, the
*survive condition*, or a dead cell flips into the alive state
in the
next generation if it is surrounded by exactly 3 living cells,
the *borne
condition*. Otherwise it dies or stays dead.
Therefore a given initial pattern, a collection of alive cells
in a
universe of dead cells, develops according to these rules over
the
generations and produces various configurations.
These special rules were invented 1970 by the mathematician
J.H.
Conway to garanty that the cellular automaton is on the
boundary
between unbounded growth and decay into dullness. It was
proven that
it's chaotic behaviour is unpredictable and it could be used
to build
an universal turing-machine and even an universal constructor.
One
of the important open problems is whether a sufficient large
random
populated universe will develop selforganization structures.
}
usage: {
>> do %gol.r
*ESC*
>> unview
A dimension of 10x10 works fast enough on a P233 under WinNT4
}
]
init-map: func [
"set initial pattern"
max-x [integer!]
max-y [integer!]
/local x y map
][
map: make block! []
for x 1 max-x 1 [
;random/seed now
for y 1 max-y 1 [
append map to-integer rejoin [x y]
append/only map to-block pick reduce [true false] random 2
]
]
return map
]
kill: func [
"set given cell to dead"
map [block!]
x [integer!]
y [integer!]
][
clear select map to-integer rejoin [x y]
append select map to-integer rejoin [x y] false
return map
]
birth: func [
"set given cell to life"
map [block!]
x [integer!]
y [integer!]
][
clear select map to-integer rejoin [x y]
append select map to-integer rejoin [x y] true
return map
]
alive?: func [
"get cell status"
map [block!]
x [integer!]
y [integer!]
][
return first select map to-integer rejoin [x y]
]
neightboor: func [
"get amount of surronding alive cells"
map [block!]
x [integer!]
y [integer!]
/local lives
][
lives: make integer! 0
if all [(x > 1)(y < max-y)(alive? map (x - 1) (y + 1))][lives: lives +
1]
if all [(x)(y < max-y)(alive? map (x) (y + 1))][lives: lives + 1]
if all [(x < max-x)(y < max-y)(alive? map (x + 1) (y + 1))][lives: lives
+ 1]
if all [(x > 1)(y)(alive? map (x - 1) (y))][lives: lives + 1]
if all [(x < max-x)(y)(alive? map (x + 1) (y))][lives: lives + 1]
if all [(x > 1)(y > 1)(alive? map (x - 1) (y - 1))][lives: lives + 1]
if all [(x)(y > 1)(alive? map (x) (y - 1))][lives: lives + 1]
if all [(x < max-x)(y > 1)(alive? map (x + 1) (y - 1))][lives: lives +
1]
return lives
]
make-generation: func [
"compute status of each cell"
map [block!]
max-x [integer!]
max-y [integer!]
/local x y
][
for x 1 max-x 1 [
for y 1 max-y 1 [
;--- survive condition
if any [((neightboor map x y) < 2)((neightboor map x y) > 3)]
[map: kill map x y]
;--- borne condition
if all[(not alive? map x y)((neightboor map x y) = 3)] [map:
birth map x y]
]
]
return map
]
show-visual: func [
"visualize map"
max-x [integer!]
max-y [integer!]
/local x y main society map
][
;--- initialize map
map: init-map max-x max-y
;--- set layout
lay: [
style amibe box 20x20 black
space 1x1
]
for x 1 max-x 1 [
for y 1 max-y 1 [
append lay 'amibe
]
append lay 'return
]
lay: layout lay
view/new lay
;--- animate
forever [
count: 0
for x 1 max-x 1 [
for y 1 max-y 1 [
count: count + 1
either alive? map x y [
set in pick lay/pane count 'color red
][
set in pick lay/pane count 'color black
]
show pick lay/pane count
]
]
map: make-generation map max-x max-y
]
]
;--- get map dim from user
max-x: to-integer ask "x dimension = "
max-y: to-integer ask "y dimension = "
;--- begin show
show-visual max-x max-y
</script>
Regards,
chr==