forked from zeroflag/punyforth
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample-game-of-life.forth
66 lines (56 loc) · 1.71 KB
/
example-game-of-life.forth
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
BUFFER_SIZE buffer: screen2
: xchg-screen ( -- )
screen screen1 = if
screen2 actual !
else
screen1 actual !
then ;
: north ( x y -- x' y' ) 1- 63 and ;
: north-east ( x y -- x' y' ) swap 1+ swap 1- ;
: east ( x y -- x' y' ) swap 1+ 127 and swap ;
: south-east ( x y -- x' y' ) swap 1+ swap 1+ ;
: south ( x y -- x' y' ) 1+ 63 and ;
: south-west ( x y -- x' y' ) swap 1- swap 1+ ;
: west ( x y -- x' y' ) swap 1- 127 and swap ;
: north-west ( x y -- x' y' ) swap 1- swap 1- ;
: xyover ( x y n -- x y n x y ) >r 2dup r> -rot ;
: #neighbours ( x y -- n )
2dup north pixel-set?
xyover north-east pixel-set? +
xyover east pixel-set? +
xyover south-east pixel-set? +
xyover south pixel-set? +
xyover south-west pixel-set? +
xyover west pixel-set? +
xyover north-west pixel-set? +
nip nip abs ;
: kill-life ( x y ) xchg-screen unset-pixel xchg-screen ;
: give-life ( x y ) xchg-screen set-pixel xchg-screen ;
: cell-state ( x y ) pixel-set? 1 and ;
: next-generation ( -- )
DISPLAY_HEIGHT 1- 0 do
DISPLAY_WIDTH 1- 0 do
i j cell-state
i j #neighbours or \ newstate = (oldstate | #neighbors) == 3.
3 = if
i j give-life
else
i j kill-life
then
loop
loop ;
: evolve ( ntimes -- )
0 do
next-generation
xchg-screen
display
loop ;
: place-random-cell ( -- )
random DISPLAY_WIDTH 2 - %
random DISPLAY_HEIGHT 2 - %
set-pixel ;
: random-population ( size -- )
0 do place-random-cell loop ;
display-init
1024 random-population
10 evolve