added an implementation of Conway's game of life as en example
This commit is contained in:
223
examples/game_of_life.sl
Normal file
223
examples/game_of_life.sl
Normal file
@@ -0,0 +1,223 @@
|
||||
# Conway's Game of Life
|
||||
|
||||
import stdlib/stdlib.sl
|
||||
import stdlib/io.sl
|
||||
import stdlib/mem.sl
|
||||
|
||||
macro WIDTH 0 40 ;
|
||||
macro HEIGHT 0 24 ;
|
||||
macro GENERATIONS 0 80 ;
|
||||
macro CELLS 0 WIDTH HEIGHT * ;
|
||||
macro FRAME_DELAY 0 35000000;
|
||||
|
||||
#cell_addr [*, grid, x | y] -> [* | addr]
|
||||
word cell_addr
|
||||
WIDTH * + 8 * +
|
||||
end
|
||||
|
||||
#get_cell [*, grid, x | y] -> [* | value]
|
||||
word get_cell
|
||||
dup 0 < if
|
||||
2drop drop 0
|
||||
else dup HEIGHT >= if
|
||||
2drop drop 0
|
||||
else over 0 < if
|
||||
2drop drop 0
|
||||
else over WIDTH >= if
|
||||
2drop drop 0
|
||||
else
|
||||
cell_addr @
|
||||
end
|
||||
end
|
||||
|
||||
#term_enter [*] -> [*]
|
||||
word term_enter
|
||||
# Enter alternate screen: ESC[?1049h
|
||||
27 putc 91 putc 63 putc 49 putc 48 putc 52 putc 57 putc 104 putc
|
||||
# Hide cursor: ESC[?25l
|
||||
27 putc 91 putc 63 putc 50 putc 53 putc 108 putc
|
||||
end
|
||||
|
||||
#term_leave [*] -> [*]
|
||||
word term_leave
|
||||
# Show cursor: ESC[?25h
|
||||
27 putc 91 putc 63 putc 50 putc 53 putc 104 putc
|
||||
# Leave alternate screen (restores original terminal view): ESC[?1049l
|
||||
27 putc 91 putc 63 putc 49 putc 48 putc 52 putc 57 putc 108 putc
|
||||
end
|
||||
|
||||
#clear_screen_home [*] -> [*]
|
||||
word clear_screen_home
|
||||
# Clear full screen: ESC[2J
|
||||
27 putc 91 putc 50 putc 74 putc
|
||||
# Move cursor home: ESC[H
|
||||
27 putc 91 putc 72 putc
|
||||
end
|
||||
|
||||
#frame_sleep [*] -> [*]
|
||||
word frame_sleep
|
||||
# Busy wait between frames; tune FRAME_DELAY for your machine.
|
||||
FRAME_DELAY for
|
||||
1 drop
|
||||
end
|
||||
end
|
||||
|
||||
#set_cell [*, grid, x, y | value] -> [*]
|
||||
word set_cell
|
||||
>r
|
||||
cell_addr
|
||||
r> !
|
||||
end
|
||||
|
||||
#count_neighbors [*, grid, x | y] -> [* | n]
|
||||
word count_neighbors
|
||||
with g x y in
|
||||
0
|
||||
g x 1 - y 1 - get_cell +
|
||||
g x y 1 - get_cell +
|
||||
g x 1 + y 1 - get_cell +
|
||||
g x 1 - y get_cell +
|
||||
g x 1 + y get_cell +
|
||||
g x 1 - y 1 + get_cell +
|
||||
g x y 1 + get_cell +
|
||||
g x 1 + y 1 + get_cell +
|
||||
end
|
||||
end
|
||||
|
||||
#print_cell [* | state] -> [*]
|
||||
word print_cell
|
||||
if 35 putc else 46 putc end
|
||||
end
|
||||
|
||||
#print_board [* | grid] -> [*]
|
||||
word print_board
|
||||
0
|
||||
while dup HEIGHT < do
|
||||
0
|
||||
while dup WIDTH < do
|
||||
2 pick
|
||||
1 pick
|
||||
3 pick
|
||||
get_cell print_cell
|
||||
1 +
|
||||
end
|
||||
drop
|
||||
10 putc
|
||||
1 +
|
||||
end
|
||||
drop
|
||||
drop
|
||||
10 putc
|
||||
end
|
||||
|
||||
#evolve [*, state | neighbors] -> [* | new_state]
|
||||
word evolve
|
||||
over 1 == if
|
||||
nip
|
||||
dup 2 == if
|
||||
drop 1
|
||||
else
|
||||
dup 3 == if drop 1 else drop 0 end
|
||||
end
|
||||
else
|
||||
nip
|
||||
dup 3 == if drop 1 else drop 0 end
|
||||
end
|
||||
end
|
||||
|
||||
#copy_qwords [*, dst, src | count] -> [*]
|
||||
word copy_qwords
|
||||
while dup 0 > do
|
||||
over @
|
||||
3 pick swap !
|
||||
swap 8 + swap
|
||||
rot 8 + -rot
|
||||
1 -
|
||||
end
|
||||
drop 2drop
|
||||
end
|
||||
|
||||
#clear_board [* | grid] -> [*]
|
||||
word clear_board
|
||||
0
|
||||
while dup CELLS < do
|
||||
over over 8 * + 0 !
|
||||
1 +
|
||||
end
|
||||
drop
|
||||
drop
|
||||
end
|
||||
|
||||
#seed_glider [* | grid] -> [*]
|
||||
word seed_glider
|
||||
dup 1 0 1 set_cell
|
||||
dup 2 1 1 set_cell
|
||||
dup 0 2 1 set_cell
|
||||
dup 1 2 1 set_cell
|
||||
dup 2 2 1 set_cell
|
||||
drop
|
||||
end
|
||||
|
||||
#step [*, current | next] -> [*, current | next]
|
||||
word step
|
||||
0
|
||||
while dup HEIGHT < do
|
||||
0
|
||||
while dup WIDTH < do
|
||||
# current next y x
|
||||
3 pick
|
||||
1 pick
|
||||
3 pick
|
||||
get_cell
|
||||
# current next y x state
|
||||
|
||||
4 pick
|
||||
2 pick
|
||||
4 pick
|
||||
count_neighbors
|
||||
# current next y x state neighbors
|
||||
|
||||
evolve
|
||||
# current next y x new_state
|
||||
|
||||
3 pick
|
||||
2 pick
|
||||
4 pick
|
||||
cell_addr
|
||||
swap !
|
||||
# current next y x
|
||||
|
||||
1 +
|
||||
end
|
||||
drop
|
||||
1 +
|
||||
end
|
||||
drop
|
||||
end
|
||||
|
||||
word main
|
||||
CELLS 8 * alloc
|
||||
CELLS 8 * alloc
|
||||
|
||||
over clear_board
|
||||
dup clear_board
|
||||
|
||||
over seed_glider
|
||||
|
||||
term_enter
|
||||
|
||||
GENERATIONS for
|
||||
clear_screen_home
|
||||
over print_board
|
||||
frame_sleep
|
||||
2dup step
|
||||
over over CELLS copy_qwords
|
||||
end
|
||||
|
||||
term_leave
|
||||
|
||||
swap CELLS 8 * free
|
||||
CELLS 8 * free
|
||||
|
||||
0
|
||||
end
|
||||
Reference in New Issue
Block a user