Skip to content

Instantly share code, notes, and snippets.

@scottwalters
Created July 14, 2012 21:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scottwalters/3113445 to your computer and use it in GitHub Desktop.
Save scottwalters/3113445 to your computer and use it in GitHub Desktop.
Pretty naive breadth first searching bot with board state scoring heuristics.
It sorts the search queue now and then according to whatever score it came up
with for each board position. It also is amnesiac in that it aggressively
prunes potentially valuable search nodes.
My original goal was to implement a completely naive solver in one SNOBOL
pattern, much as one would implement Scheme in one defun. SNOBOL's extensible
pattern matching system was famously sometimes abused for goal-directed
behavior like this.
As it is, there's an interactive mode created thinking I'd do some sort of
machine learning but didn't get past weighing the board rankings to favor
patterns it has seen before. The interactive mode is commented out by the
comment "XXX interactive or play". Another routine replays games, computer
or human solved, dumping out SNOBOL source code to add stuff to the hash
of recognized patterns.
As coincidence would have it, I gave a Perl talk at a YAPC recently on
games and the SDL, and my largest example was a very partial port of Super
Mario Brothers 3 that was extended with logic from the Boulderdash universe.
For the second time in recent months, I'm working on Boulderdash logic in
unstructured code.
I feel bad for not blotting out the calendar better and taking a more serious
stab at this one. I worked Friday and then had a friends going away party,
and never really bothered to sit down and think of good strategies for doing
this. For a second stab, I think I would do depth-first that attempts
different strategies and remembers, along with the route, which strategies
it is imploying at which point in case it has to back up. This would be
reaching for an analogy of how a human plays a game -- going as far as they
can, trying a different strategy at the point that they died, and so on.
-scott
scott@slowass.net
*
* run with: snobol4 -d 40m boulder.sno <map file> <time limit in seconds>
*
*
*
*
rock_above_space = len(1) '*' len(1) len(1) ' ' len(1)
rock_below_clear_right = len(1) '*' ' ' len(1) '*' ' '
rock_below_clear_left = ' ' '*' len(1) ' ' '*' len(1)
rock_on_lambda = len(1) '*' ' ' len(1) '\' ' '
*
*
*
data('saved_route(board,route,score,ranking,lambdas,robot_x,robot_y,runtime)')
queue_max = 1000
sort_queue_every = 100
queue = array('0:' queue_max ',2')
*
*
*
lambda_locations = array(1000)
*
*
*
rules = table()
* from contest1.map
rules<'####.\*## '> = 1 ;* D
rules<'####.\*#'> = 1 ;* D
rules<' ### *\*#\ '> = 1 ;* L
rules<' ### *\*'> = 1 ;* L
rules<'* * #. #'> = 1 ;* L
rules<'* * '> = 1 ;* L
rules<' ** \ .# # '> = 1 ;* D
rules<' ** \ .'> = 1 ;* D
rules<' *. \ ##*'> = 1 ;* D
rules<' *. \ '> = 1 ;* D
rules<' *.### \ L\'> = 1 ;* R
rules<' *.### \'> = 1 ;* R
rules<'**\### #'> = 1 ;* R
rules<'**\### '> = 1 ;* R
rules<'*#####* '> = 1 ;* L
rules<'*#####* '> = 1 ;* L
rules<' *###* #'> = 1 ;* U
rules<' *###* '> = 1 ;* U
rules<' * * #\#'> = 1 ;* L
rules<' * * '> = 1 ;* L
rules<' * \ ## '> = 1 ;* L
rules<' * \ '> = 1 ;* L
rules<' * L##.## '> = 1 ;* D
rules<' * L##'> = 1 ;* D
rules<' *###L# '> = 1 ;* L
rules<' *###L#'> = 1 ;* L
rules<'# ########*'> = 1 ;* L
rules<'# #####'> = 1 ;* L
* from contest2.map
rules<'.*.###L#....'> = 1 ;* R
rules<'.*.###L#'> = 1 ;* R
rules<'*..### ...L.'> = 1 ;* R
rules<'*..### .'> = 1 ;* R
rules<'.*.###* .. .'> = 1 ;* U
rules<'.*.###* '> = 1 ;* U
rules<'.**. * .\#.\'> = 1 ;* D
rules<'.**. * .'> = 1 ;* D
rules<' *.###* .. .'> = 1 ;* R
rules<' *.###* '> = 1 ;* R
rules<'*\.### ***#'> = 1 ;* R
rules<'*\.### '> = 1 ;* R
rules<'\#####* ** '> = 1 ;* U
rules<'\#####* '> = 1 ;* U
rules<'*### ** \# '> = 1 ;* L
rules<'*### ** '> = 1 ;* L
rules<' * ** .\# #'> = 1 ;* U
rules<' * ** .'> = 1 ;* U
rules<'\\ .\**.#'> = 1 ;* R
rules<'\\ .\'> = 1 ;* R
rules<'\### \**..'> = 1 ;* U
rules<'\### \'> = 1 ;* U
rules<'*### \*# \\'> = 1 ;* L
rules<'*### \*'> = 1 ;* L
rules<'* * .\*# .#'> = 1 ;* L
rules<'* * .\*'> = 1 ;* L
rules<'* * ....# . '> = 1 ;* L
rules<'* * ....'> = 1 ;* L
rules<'. *.....# # '> = 1 ;* L
rules<'. *.....'> = 1 ;* L
rules<'.. ..####..*'> = 1 ;* D
rules<'.. ..###'> = 1 ;* D
rules<' . .###. .'> = 1 ;* D
rules<' . .###'> = 1 ;* D
rules<' . * L## ## '> = 1 ;* D
rules<' . * L##'> = 1 ;* D
rules<' *###L# *'> = 1 ;* L
rules<' *###L#'> = 1 ;* L
rules<'# ########*'> = 1 ;* L
rules<'# #####'> = 1 ;* L
* from contest3.map
rules<'##..*..###..'> = 1 ;* L
rules<'##..*..#'> = 1 ;* L
rules<'## *...##.#.'> = 1 ;* L
rules<'## *...#'> = 1 ;* L
rules<'## ..####.. '> = 1 ;* D
rules<'## ..###'> = 1 ;* D
rules<' ...####..*'> = 1 ;* D
rules<' ...###'> = 1 ;* D
rules<' ..\.### ###'> = 1 ;* D
rules<' ..\.###'> = 1 ;* D
rules<' .\##### \\.'> = 1 ;* R
rules<' .\#####'> = 1 ;* R
rules<'.#.### ..#\'> = 1 ;* R
rules<'.#.### '> = 1 ;* R
rules<'#.\*## .*. .'> = 1 ;* R
rules<'#.\*## .'> = 1 ;* R
rules<'...**# #.. .'> = 1 ;* R
rules<'...**# #'> = 1 ;* R
rules<'....** ... L'> = 1 ;* R
rules<'....** .'> = 1 ;* R
rules<'.#L#.* ... '> = 1 ;* D
rules<'.#L#.* .'> = 1 ;* D
rules<' L##..* ..**'> = 1 ;* D
rules<' L##..* '> = 1 ;* D
rules<' ###. .* #..'> = 1 ;* L
rules<' ###. .*'> = 1 ;* L
rules<'* . *.* #.#'> = 1 ;* L
rules<'* . *.*'> = 1 ;* L
rules<'* * *..# #. '> = 1 ;* L
rules<'* * *..#'> = 1 ;* L
rules<'# **...# #\ '> = 1 ;* L
rules<'# **...#'> = 1 ;* L
rules<'## ..\\# ##*'> = 1 ;* L
rules<'## ..\\#'> = 1 ;* L
rules<'## .\### ## '> = 1 ;* D
rules<'## .\###'> = 1 ;* D
rules<' .########.'> = 1 ;* U
rules<' .#####'> = 1 ;* U
rules<'## . ### ## '> = 1 ;* R
rules<'## . ###'> = 1 ;* R
rules<'## .. # ##*'> = 1 ;* R
rules<'## .. #'> = 1 ;* R
rules<'# **.. # # '> = 1 ;* R
rules<'# **.. #'> = 1 ;* R
rules<' ***. # # '> = 1 ;* U
rules<' ***. #'> = 1 ;* U
rules<' * # .*# '> = 1 ;* U
rules<' * # '> = 1 ;* U
rules<'.. # #. '> = 1 ;* R
rules<'.. # #'> = 1 ;* R
rules<'.. ..* L'> = 1 ;* R
rules<'.. .'> = 1 ;* R
rules<'.#L# .. '> = 1 ;* R
rules<'.#L# .'> = 1 ;* R
rules<'##### .## '> = 1 ;* R
rules<'##### .'> = 1 ;* R
* from contest4.map
rules<'\. \...*.#.'> = 1 ;* U
rules<'\. \...'> = 1 ;* U
rules<'*.. ...#\#.'> = 1 ;* D
rules<'*.. ...'> = 1 ;* D
rules<'*. \... .#.'> = 1 ;* D
rules<'*. \...'> = 1 ;* D
rules<'* \.... .# '> = 1 ;* D
rules<'* \....'> = 1 ;* D
rules<'* \..... .# '> = 1 ;* R
rules<'* \.....'> = 1 ;* R
rules<' \..* .. '> = 1 ;* D
rules<' \..* '> = 1 ;* D
rules<' \....* #. '> = 1 ;* R
rules<' \....*'> = 1 ;* R
rules<' \.. #. '> = 1 ;* R
rules<' \.. '> = 1 ;* R
rules<' . \. .# #'> = 1 ;* D
rules<' . \. '> = 1 ;* D
rules<' ###. .\'> = 1 ;* R
rules<' ###. '> = 1 ;* R
rules<' #\### ...#'> = 1 ;* R
rules<' #\### '> = 1 ;* R
rules<'###### .. '> = 1 ;* L
rules<'###### '> = 1 ;* L
rules<' # ### ...#'> = 1 ;* U
rules<' # ### '> = 1 ;* U
rules<'..# .# #'> = 1 ;* U
rules<'..# '> = 1 ;* U
rules<'...# .# #'> = 1 ;* U
rules<'...# .'> = 1 ;* U
rules<'#... .#\ #'> = 1 ;* R
rules<'#... .#'> = 1 ;* R
rules<'.###. #.#..'> = 1 ;* U
rules<'.###. #'> = 1 ;* U
rules<'.L## #\..##'> = 1 ;* U
rules<'.L## #\'> = 1 ;* U
rules<'.#L# #\\# ##'> = 1 ;* L
rules<'.#L# #\\'> = 1 ;* L
rules<'\. ##### .L'> = 1 ;* U
rules<'\. ####'> = 1 ;* U
rules<'##. #####.#'> = 1 ;* D
rules<'##. ###'> = 1 ;* D
rules<' . ##### .L'> = 1 ;* R
rules<' . ####'> = 1 ;* R
rules<'.#L# # # ##'> = 1 ;* R
rules<'.#L# # '> = 1 ;* R
rules<'##### .## '> = 1 ;* R
rules<'##### .'> = 1 ;* R
* from contest5.map
rules<'######.#...\'> = 1 ;* L
rules<'######.#'> = 1 ;* L
rules<'## ###.....#'> = 1 ;* L
rules<'## ###..'> = 1 ;* L
rules<'.# ###....# '> = 1 ;* U
rules<'.# ###..'> = 1 ;* U
rules<'..# ....###'> = 1 ;* U
rules<'..# ...'> = 1 ;* U
rules<'.\.# .... #.'> = 1 ;* R
rules<'.\.# ...'> = 1 ;* R
rules<'\..## .\ ..'> = 1 ;* U
rules<'\..## .'> = 1 ;* U
rules<'\... ..\#..'> = 1 ;* U
rules<'\... ..'> = 1 ;* U
rules<'\\.. ... ..'> = 1 ;* U
rules<'\\.. ...'> = 1 ;* U
rules<' \. .. \ .\'> = 1 ;* R
rules<' \. .. '> = 1 ;* R
rules<' \.. \..\'> = 1 ;* R
rules<' \.. '> = 1 ;* R
rules<' \ .. \. \'> = 1 ;* R
rules<' \ .. '> = 1 ;* R
rules<' .\ . \ \'> = 1 ;* R
rules<' .\ . '> = 1 ;* R
rules<'..\ \. \'> = 1 ;* R
rules<'..\ '> = 1 ;* R
rules<'..\ .\. .'> = 1 ;* R
rules<'..\ .'> = 1 ;* R
rules<'.... ... #'> = 1 ;* U
rules<'.... .'> = 1 ;* U
rules<'.... .\. .#'> = 1 ;* U
rules<'.... .\'> = 1 ;* U
rules<'.... .\.. \#'> = 1 ;* L
rules<'.... .\.'> = 1 ;* L
rules<'.. ..\.. \.'> = 1 ;* L
rules<'.. ..\.'> = 1 ;* L
rules<'.. .. \*. \ '> = 1 ;* D
rules<'.. .. \*'> = 1 ;* D
rules<' . \. '> = 1 ;* L
rules<' . \'> = 1 ;* L
rules<'\ \* .'> = 1 ;* L
rules<'\ \'> = 1 ;* L
rules<'\\ \.. '> = 1 ;* U
rules<'\\ \'> = 1 ;* U
rules<'.*\ \.. \ '> = 1 ;* L
rules<'.*\ \.'> = 1 ;* L
rules<'.. \.. .\'> = 1 ;* L
rules<'.. \.'> = 1 ;* L
rules<'.. ... . '> = 1 ;* U
rules<'.. ..'> = 1 ;* U
rules<'... ...# ..'> = 1 ;* R
rules<'... ...'> = 1 ;* R
rules<'... .# .*'> = 1 ;* R
rules<'... .'> = 1 ;* R
rules<'..*\ .# .'> = 1 ;* L
rules<'..*\ .'> = 1 ;* L
rules<'.. .# .*'> = 1 ;* D
rules<'.. .'> = 1 ;* D
rules<' . .\'> = 1 ;* D
rules<' '> = 1 ;* D
rules<' . '> = 1 ;* R
rules<' '> = 1 ;* R
rules<' \ . '> = 1 ;* R
rules<' \ '> = 1 ;* R
rules<'\ * .'> = 1 ;* R
rules<'\ '> = 1 ;* R
rules<' . \. '> = 1 ;* U
rules<' . \'> = 1 ;* U
rules<'.. . \*. '> = 1 ;* U
rules<'.. . \*'> = 1 ;* U
rules<'... \*.# .'> = 1 ;* L
rules<'... \*.'> = 1 ;* L
rules<'.. \* .# .'> = 1 ;* D
rules<'.. \* .'> = 1 ;* D
rules<' * . '> = 1 ;* D
rules<' * '> = 1 ;* D
rules<' * .'> = 1 ;* D
rules<' * '> = 1 ;* D
rules<' .* '> = 1 ;* D
rules<' .* '> = 1 ;* D
rules<' . ..* . '> = 1 ;* D
rules<' . ..*'> = 1 ;* D
rules<' .. ... ..'> = 1 ;* D
rules<' .. ...'> = 1 ;* D
rules<' ..# #.. \..'> = 1 ;* D
rules<' ..# #..'> = 1 ;* D
rules<' .##\##. L##'> = 1 ;* D
rules<' .##\##.'> = 1 ;* D
rules<' ###L### \'> = 1 ;* D
rules<' ###L###'> = 1 ;* D
* from contest6.map
rules<'#..#####\\\#'> = 1 ;* R
rules<'#..#####'> = 1 ;* R
rules<'.##### #..#\'> = 1 ;* U
rules<'.##### #'> = 1 ;* U
rules<'..## #\####'> = 1 ;* U
rules<'..## #\'> = 1 ;* U
rules<'##.# #\#. #.'> = 1 ;* L
rules<'##.# #\#'> = 1 ;* L
rules<'## ####\ .'> = 1 ;* R
rules<'## ####'> = 1 ;* R
rules<'##.# # #. #.'> = 1 ;* R
rules<'##.# # #'> = 1 ;* R
rules<'##.## #.# .'> = 1 ;* R
rules<'##.## #'> = 1 ;* R
rules<'##.### #.\ .'> = 1 ;* R
rules<'##.### #'> = 1 ;* R
rules<'##.### #.. .'> = 1 ;* R
rules<'##.### #'> = 1 ;* R
rules<'##.### #.. .'> = 1 ;* R
rules<'##.### #'> = 1 ;* R
rules<'##.### #.. .'> = 1 ;* R
rules<'##.### #'> = 1 ;* R
rules<'##.### # . .'> = 1 ;* R
rules<'##.### #'> = 1 ;* R
rules<'##.### #L. .'> = 1 ;* R
rules<'##.### #'> = 1 ;* R
rules<'#..### ##. #'> = 1 ;* R
rules<'#..### #'> = 1 ;* R
rules<'.##### #.. .'> = 1 ;* U
rules<'.##### #'> = 1 ;* U
rules<'.### ##.##.'> = 1 ;* U
rules<'.### ##'> = 1 ;* U
rules<'..## ##*# L.'> = 1 ;* U
rules<'..## ##*'> = 1 ;* U
rules<'#..# #*## .'> = 1 ;* R
rules<'#..# #*#'> = 1 ;* R
rules<'.#..# #.#*#'> = 1 ;* U
rules<'.#..# #'> = 1 ;* U
rules<'.\#. ##*###'> = 1 ;* U
rules<'.\#. ##'> = 1 ;* U
rules<'* \# #### #'> = 1 ;* R
rules<'* \# ###'> = 1 ;* R
rules<' #### * .##'> = 1 ;* U
rules<' #### * '> = 1 ;* U
rules<' ### # ###'> = 1 ;* U
rules<' ### #'> = 1 ;* U
rules<' ### #.# ##'> = 1 ;* U
rules<' ### #.'> = 1 ;* U
rules<'#### #.. ##'> = 1 ;* L
rules<'#### #..'> = 1 ;* L
rules<'.# ###.* ##'> = 1 ;* U
rules<'.# ###.'> = 1 ;* U
rules<'* # #.*##.#'> = 1 ;* L
rules<'* # #.*'> = 1 ;* L
rules<'* * ##..####'> = 1 ;* L
rules<'* * ##..'> = 1 ;* L
rules<'. *##*#.#.# '> = 1 ;* U
rules<'. *##*#.'> = 1 ;* U
rules<'## * #.###. '> = 1 ;* L
rules<'## * #.#'> = 1 ;* L
rules<'## ##.##*. '> = 1 ;* L
rules<'## ##.#'> = 1 ;* L
rules<'## ###.##.. '> = 1 ;* L
rules<'## ###.#'> = 1 ;* L
rules<'## ###.##.. '> = 1 ;* L
rules<'## ###.#'> = 1 ;* L
rules<'## ###.##.. '> = 1 ;* L
rules<'## ###.#'> = 1 ;* L
rules<'## ##..##.\ '> = 1 ;* L
rules<'## ##..#'> = 1 ;* L
rules<'## #.#\##.\ '> = 1 ;* L
rules<'## #.#\#'> = 1 ;* L
rules<'## .#\\###\ '> = 1 ;* L
rules<'## .#\\#'> = 1 ;* L
rules<'## #\\\##\# '> = 1 ;* L
rules<'## #\\\#'> = 1 ;* L
rules<'## \\####\\ '> = 1 ;* D
rules<'## \\###'> = 1 ;* D
rules<' \\\####\\#'> = 1 ;* R
rules<' \\\###'> = 1 ;* R
rules<' ##\\ ###.'> = 1 ;* D
rules<' ##\\ '> = 1 ;* D
rules<' ####\\ .#.'> = 1 ;* L
rules<' ####\\ '> = 1 ;* L
rules<' #\### \\#'> = 1 ;* D
rules<' #\###'> = 1 ;* D
rules<' #.\### \\#'> = 1 ;* D
rules<' #.\###'> = 1 ;* D
rules<' #..\### \\.'> = 1 ;* D
rules<' #..\###'> = 1 ;* D
rules<' ...\### \\#'> = 1 ;* D
rules<' ...\###'> = 1 ;* D
rules<' ..#\### \\#'> = 1 ;* D
rules<' ..#\###'> = 1 ;* D
rules<' .#.\### ###'> = 1 ;* D
rules<' .#.\###'> = 1 ;* D
rules<' #.##### .'> = 1 ;* U
rules<' #.#####'> = 1 ;* U
rules<' .#. ### ###'> = 1 ;* U
rules<' .#. ###'> = 1 ;* U
rules<' ..# ### #'> = 1 ;* U
rules<' ..# ###'> = 1 ;* U
rules<' ... ### #'> = 1 ;* U
rules<' ... ###'> = 1 ;* U
rules<' #.. ### .'> = 1 ;* R
rules<' #.. ###'> = 1 ;* R
rules<'##.#. .#.'> = 1 ;* R
rules<'##.#. '> = 1 ;* R
rules<'##.##. ### .'> = 1 ;* R
rules<'##.##. #'> = 1 ;* R
rules<'##.### #.. .'> = 1 ;* R
rules<'##.### #'> = 1 ;* R
rules<'##.### #. .'> = 1 ;* R
rules<'##.### #'> = 1 ;* R
rules<'#\.### #.* #'> = 1 ;* R
rules<'#\.### #'> = 1 ;* R
rules<'\.#### #.. #'> = 1 ;* U
rules<'\.#### #'> = 1 ;* U
rules<'...# #.###.'> = 1 ;* U
rules<'...# #.'> = 1 ;* U
* from contest7.map
rules<' \### ### '> = 1 ;* R
rules<' \### '> = 1 ;* R
rules<' *\\# ###*'> = 1 ;* D
rules<' *\\# '> = 1 ;* D
rules<' *\.### .#\'> = 1 ;* R
rules<' *\.### '> = 1 ;* R
rules<'**\..# .#\'> = 1 ;* R
rules<'**\..# '> = 1 ;* R
rules<'*#\...* \ #'> = 1 ;* R
rules<'*#\...* '> = 1 ;* R
rules<'###...* # *#'> = 1 ;* D
rules<'###...* '> = 1 ;* D
rules<' #.. \.*# .#'> = 1 ;* D
rules<' #.. \.*'> = 1 ;* D
rules<' ... L\. #. '> = 1 ;* D
rules<' ... L\.'> = 1 ;* D
rules<' ..\# L\ '> = 1 ;* R
rules<' ..\# L\'> = 1 ;* R
rules<'. \\# .#L '> = 1 ;* D
rules<'. \\# '> = 1 ;* D
rules<' \## # .. \'> = 1 ;* R
rules<' \## # '> = 1 ;* R
rules<' \### #\'> = 1 ;* R
rules<' \### '> = 1 ;* R
rules<' #\### ## #'> = 1 ;* R
rules<' #\### '> = 1 ;* R
rules<'###### ## #'> = 1 ;* L
rules<'###### '> = 1 ;* L
rules<' # ### ## #'> = 1 ;* L
rules<' # ### '> = 1 ;* L
rules<' ### # '> = 1 ;* L
rules<' ### '> = 1 ;* L
rules<' ## # .. '> = 1 ;* U
rules<' ## # '> = 1 ;* U
rules<'. # .#L '> = 1 ;* L
rules<'. # '> = 1 ;* L
rules<' . # L\ '> = 1 ;* U
rules<' . # L\'> = 1 ;* U
rules<' .. L\. #. '> = 1 ;* L
rules<' .. L\.'> = 1 ;* L
rules<'. L ..* ..'> = 1 ;* L
rules<'. L ..'> = 1 ;* L
rules<'.. L ..#*## '> = 1 ;* L
rules<'.. L ..#'> = 1 ;* L
rules<'#. . ## \# '> = 1 ;* D
rules<'#. . ##'> = 1 ;* D
rules<' #\\ ####L'> = 1 ;* D
rules<' #\\ #'> = 1 ;* D
rules<' # ##\ \ '> = 1 ;* L
rules<' # ##\ '> = 1 ;* L
rules<' ###\#####'> = 1 ;* L
rules<' ###\#'> = 1 ;* L
rules<'# ######## '> = 1 ;* R
rules<'# #####'> = 1 ;* R
rules<' ### #####'> = 1 ;* R
rules<' ### #'> = 1 ;* R
rules<' # ## '> = 1 ;* U
rules<' # ## '> = 1 ;* U
rules<' # ####L'> = 1 ;* R
rules<' # #'> = 1 ;* R
rules<' L # . '> = 1 ;* R
rules<' L # '> = 1 ;* R
rules<' # # . '> = 1 ;* R
rules<' # # '> = 1 ;* R
*
*
*
duplicate_boards = table()
*
*
*
define('new_saved_route(board,route,score,ranking,lambdas,robot_x,robot_y,runtime)sb') :(new_saved_route_end)
new_saved_route
* eq(duplicate_routes<route>, 1) :f(new_saved_route_1)
* output = "argh! duplicate route added: " route
*new_saved_route_1
* duplicate_routes<route> = 1
* output = "route: " route
* sb = stringify_board(board)
* eq(duplicate_boards<sb>, 1) :f(new_saved_route_2)
* output = "argh! duplicate board added: " sb
*new_saved_route_2
* duplicate_boards<sb> = 1
gt(size(runtime), 0) :s(new_saved_route_3)
runtime = time() / 1000
new_saved_route_3
new_saved_route = saved_route(board,route,score,ranking,lambdas,robot_x,robot_y,runtime)
gt(ranking, 0) :s(new_saved_route_4)
ranking = rank_board( new_saved_route )
ranking(new_saved_route) = ranking
new_saved_route_4
* also note our score and route if it's the current best
gt(score, highest_score) :f(new_saved_route_5)
highest_score = score
highest_scoring_route = new_saved_route
new_saved_route_5
:(return)
new_saved_route_end
*
*
*
define('showboard(board)x,y,line,string_board,tmp') :(showboardend)
showboard
string_board = stringify_board(board)
showboard1
string_board len(xdim) . tmp = :f(return)
output = tmp :(showboard1)
showboardend
*
*
*
define('stringify_board(board)x,y,line,buffer') :(stringify_boardend)
stringify_board
y = -1
stringify_board1
line = ""
x = 0
y = y + 1
lt(y, ydim) :s(stringify_board2)
* exit condition
stringify_board = buffer :(return)
stringify_board2
line = line board<y,x>
x = x + 1
lt(x, xdim) :s(stringify_board2)
buffer = buffer line :(stringify_board1)
stringify_boardend
*
*
*
spiral_coords = array('12,2')
* basic 3x3 cube, starting at the stop above our head
spiral_coords<1,1> = 0; spiral_coords<1,2> = -1;
spiral_coords<2,1> = 1; spiral_coords<2,2> = -1;
spiral_coords<3,1> = 1; spiral_coords<3,2> = 0;
spiral_coords<4,1> = 1; spiral_coords<4,2> = 1;
spiral_coords<5,1> = 0; spiral_coords<5,2> = 1;
spiral_coords<6,1> = -1; spiral_coords<6,2> = 1;
spiral_coords<7,1> = -1; spiral_coords<7,2> = 0;
spiral_coords<8,1> = -1; spiral_coords<8,2> = -1;
* spikes sticking out on the top, bottom, left, and right
spiral_coords<9,1> = 0; spiral_coords<9,2> = -2;
spiral_coords<10,1> = 0; spiral_coords<10,2> = 2;
spiral_coords<11,1> = -2; spiral_coords<11,2> = 0;
spiral_coords<12,1> = 2; spiral_coords<12,2> = 0;
define('spiral_stringify_board(board,robot_x,robot_y),chr,i,x,y,line,buffer') :(spiral_stringify_boardend)
spiral_stringify_board
i = 1
spiral_stringify_board1
x = robot_x + spiral_coords<i,1>
y = robot_y + spiral_coords<i,2>
chr = board<y,x>
gt(size(chr), 0) :f(spiral_stringify_board2)
line = line chr
i = i + 1
le(i, 12) :s(spiral_stringify_board1)
spiral_stringify_board2
* debug
* output = "spiral_stringify_board: " line
spiral_stringify_board = line
:(return)
spiral_stringify_boardend
*
*
*
define('runboard(board,score,lambdas,route)x,y,sr,sb') :(runboardend)
runboard
newboard = array( "0:" ydim - 1 ",0:" xdim - 1)
y = ydim
runboard1
* new line of data
x = 0
y = y - 1
eq(y, -1) :f(runboard3)
* all done running the board; pack up and go home
* queue up our current state and also return it
* taking a step costs a point, and the board is run after each step, so we do this here
score = score - 1
sr = new_saved_route(newboard,route,score,,lambdas,robot_x,robot_y,)
sb = stringify_board(board)
eq(duplicate_boards<sb>, 1) :s(runboard3b)
lt(queue_high, queue_max) :s(runboard3a)
output = "warning! queue_high " queue_high " exceeded queue_max " queue_max :(runboard3b)
* XXX do something about this, such as sort and aggressively prune the queue
runboard3a
* queue_high points to the current last valid item on the queue; pre-increment to get an empty slot
queue_high = queue_high + 1
queue<queue_high,1> = sr
queue<queue_high,2> = ranking(sr)
runboard3b
duplicate_boards<sb> = 1
runboard = sr
:(return)
* iterate over everything on a line
runboard3
* go straight to the next character if we aren't looking at a boulder
ident(board<y,x>, '*') :f(runboardloop)
* build a single string representation of the six characters right around and below our current position
miniboard = board<y,x - 1> board<y,x> board<y,x + 1> board<y + 1,x - 1> board<y + 1,x> board<y + 1,x + 1>
* at this point, we know we have a boulder
* is it a boulder above a space?
miniboard rock_above_space :f(runboard4)
newboard<y,x> = ' '
newboard<y + 1,x> = '*' :(runboardloop1)
runboard4
miniboard rock_below_clear_right :f(runboard5)
ident(newboard<y + 2,x + 1>, 'R') :s(runboard_killed_robot)
newboard<y,x> = ' '
newboard<y + 1,x + 1> = '*' :(runboardloop1)
runboard5
miniboard rock_below_clear_left :f(runboard6)
ident(newboard<y + 2,x - 1>, 'R') :s(runboard_killed_robot)
newboard<y,x> = ' '
newboard<y + 1,x - 1> = '*' :(runboardloop1)
runboard6
miniboard rock_on_lambda :f(runboard7)
ident(newboard<y + 2,x + 1>, 'R') :s(runboard_killed_robot)
newboard<y,x> = ' '
newboard<y + 1,x + 1> = '*' :(runboardloop1)
runboard7
* any other actions here?
runboardloop
* default action is to copy the old board to the new one, so copy the current tile
newboard<y,x> = board<y,x>
* if something else was done (a boulder moved), then the logic handling that drew the target tile on the new board;
* this is branched to instead
runboardloop1
x = x + 1
eq(x, xdim) :s(runboard1)f(runboard3)
runboard_killed_robot
* output = "runboard killed the robot:"
* showboard(board)
* showboard(newboard)
:(freturn)
runboardend
*
*
*
define('move_w(board,score,lambdas,route,robot_x,robot_y)') :(move_w_end)
move_w
tile = board<robot_y, robot_x - 1>
* ident(tile, 'L') :f(move_w_test)
* eq(lambdas, total_lambdas) :f(move_w_test)
* output = "I AM STANDING RIGHT NEXT TO THE ACTIVATED EXIT: " tile
move_w_test
tile enterable :s(move_w_ok)
* can we push over a boulder to make room?
ident(tile, '*') :f(freturn)
ident(board<robot_y, robot_x - 2>, ' ') :f(freturn)
board<robot_y, robot_x - 2> = '*'
move_w_ok
ident(tile, '\') :f(move_w_1)
lambdas = lambdas + 1
score = score + 25
move_w_1
ident(tile, 'L') :f(move_w_2)
* output = "I WENT OUT THE EXIT"
score = score + lambdas * 25
move_w_2
board<robot_y, robot_x> = ' '
board<robot_y, robot_x - 1> = 'R'
robot_x = robot_x - 1
move_w = runboard(board,score,lambdas,route "L") :s(return)f(freturn)
move_w_end
*
*
*
define('move_e(board,score,lambdas,route,robot_x,robot_y)') :(move_e_end)
move_e
tile = board<robot_y, robot_x + 1>
tile enterable :s(move_e_ok)
* can we push over a boulder to make room?
ident(tile, '*') :f(freturn)
ident(board<robot_y, robot_x + 2>, ' ') :f(freturn)
board<robot_y, robot_x + 2> = '*'
move_e_ok
ident(tile, '\') :f(move_e_1)
lambdas = lambdas + 1
score = score + 25
move_e_1
ident(tile, 'L') :f(move_e_2)
score = score + lambdas * 25
move_e_2
board<robot_y, robot_x> = ' '
board<robot_y, robot_x + 1> = 'R'
robot_x = robot_x + 1
move_e = runboard(board,score,lambdas,route "R") :s(return)f(freturn)
move_e_end
*
*
*
define('move_d(board,score,lambdas,route,robot_x,robot_y)') :(move_d_end)
move_d
tile = board<robot_y + 1, robot_x>
tile enterable :f(freturn)
ident(tile, '\') :f(move_d_1)
lambdas = lambdas + 1
score = score + 25
move_d_1
ident(tile, 'L') :f(move_d_2)
score = score + lambdas * 25
move_d_2
board<robot_y, robot_x> = ' '
board<robot_y + 1, robot_x> = 'R'
robot_y = robot_y + 1
move_d = runboard(board,score,lambdas,route "D") :s(return)f(freturn)
move_d_end
*
*
*
define('move_u(board,score,lambdas,route,robot_x,robot_y)') :(move_u_end)
move_u
tile = board<robot_y - 1, robot_x>
tile enterable :f(freturn)
ident(tile, '\') :f(move_u_1)
lambdas = lambdas + 1
score = score + 25
move_u_1
ident(tile, 'L') :f(move_u_2)
score = score + lambdas * 25
move_u_2
board<robot_y, robot_x> = ' '
board<robot_y - 1, robot_x> = 'R'
robot_y = robot_y - 1
move_u = runboard(board,score,lambdas,route "U") :s(return)f(freturn)
move_u_end
*
*
*
map_filename = host(2,host(3))
filebuf = array('0:300')
* output = "command line arg: " map_filename
input(.map_file, 1, '', map_filename)
ydim = 0
ripapartline0a
line = map_file :f(ripapartline0d)
* linebuf = linebuf line
filebuf<ydim> = line
tmp = size(line)
gt(tmp, xdim) :f(ripapartline0b)
xdim = tmp
ripapartline0b
ydim = ydim + 1 :(ripapartline0a)
ripapartline0d
* output = "file is " xdim " x " ydim
board = array( "0:" ydim - 1 ",0:" xdim - 1, )
y = 0
ripapartline0aa
eq(size(filebuf<y>), xdim) :s(ripapartline0ab)
filebuf<y> = filebuf<y> " " :(ripapartline0aa)
ripapartline0ab
* output = "line: -->" filebuf<y> "<--"
y = y + 1
lt(y, ydim) :s(ripapartline0aa)
y = 0
ripapartline1
x = 0
ripapartline2
* linebuf len(1) . chr = :f(ripapartline6)
filebuf<y> pos(x) len(1) . chr
board<y,x> = chr
* output = "parsed out char " board<y,x> " for position " x ", " y
ident(chr, 'R') :f(ripapartline3)
robot_x = x
robot_y = y
ripapartline3
ident(chr, '\') :f(ripapartline4)
lambda_location = array(2)
lambda_location<1> = x
lambda_location<2> = y
lambda_locations<lambda_locations_max = lambda_locations_max + 1> = lambda_location
total_lambdas = total_lambdas + 1
ripapartline4
ident(chr, 'L') :f(ripapartline5)
exit_location = array(2)
exit_location<1> = x
exit_location<2> = y
ripapartline5
x = x + 1
lt(x, xdim) :s(ripapartline2)
y = y + 1
lt(y, ydim) :s(ripapartline1)
ripapartline6
larger_of_xdim_ydim = xdim
xdim_ydim_scalar = 10.0 / ( larger_of_xdim_ydim + 0.0 )
* output = "larger_of_xdim_ydim: " larger_of_xdim_ydim " xdim_ydim_scalar: " xdim_ydim_scalar
gt(ydim, xdim) :f(ripapartline6a)
larger_of_xdim_ydim = ydim
ripapartline6a
*
*
*
define('dump_queue(),i,j') :(dump_queue_end)
dump_queue
i = queue_low
dump_queue_3
ident(datatype(queue<i,1>),'SAVED_ROUTE') :f(dump_queue_3a)
output = "============================================================= dump queue ==="
output = "score: " score(queue<i,1>)
output = "priority: " queue<i,2>
showboard(board(queue<i,1>))
dump_queue_3a
i = i + 1
lt(i, queue_high) :s(dump_queue_3)
:(return)
dump_queue_end
*
*
*
define('show_saved_route(saved_route),i,j') :(show_saved_route_end)
show_saved_route
ident(datatype(saved_route), "SAVED_ROUTE") :s(show_saved_route_1)
output = "show_saved_route called with a " datatype(saved_route) " instead of a SAVED_ROUTE; giving up" :(freturn)
show_saved_route_1
output = "route: " route(saved_route)
output = "lambdas: " lambdas(saved_route)
output = "runtime: " runtime(saved_route)
output = "board:"
showboard(board(saved_route))
:(return)
show_saved_route_end
*
*
*
define('rank_board(sr),robot_x,robot_y,lambdas,sb,ssb,rank,i,xd,yd,xtmp,ytmp,total_distance,tmp') :(rank_board_end)
rank_board
* compute a priority value for this queued route; higher priorities tend to get explored sooner
* this formula uses score with the cost of the route subtracted back out to encourage longer routes
* the +10 is just to make real routes come before unused records
* XXX other factors... favor recent stright line runs? movement as judged by robot_x and robot_y?
* queue<queue_high,2> = score(queue<queue_high,1>) + 10
* queue<queue_high,2> = 100 - size(route(queue<queue_high,1>))
* queue<queue_high,2> = 10
* not using sb right now except for debug printing
* sb = stringify_board(board(sr))
ssb = spiral_stringify_board(board(sr),robot_x(sr),robot_y(sr))
robot_x = robot_x(sr)
robot_y = robot_y(sr)
* start above 0 so that real saved_route objects get sorted before empty, unused slots
rank = 1
* lambdas are interesting to us!
lambdas = lambdas(sr)
rank = rank + lambdas * 10
* okay, only ever one match this way, and all of the rules have to be the same length
* but we could start whacking characters off of the end off ssb and trying again... doing that
rank = rank + rules<ssb> * 10
ssb rpos(4) len(4) =
rank = rank + rules<ssb> * 10
* average distance to a lambda
* there will only ever be total_lambdas - lambdas on the board; divide our tally by that number
* skip places on the board where the lambda was collected
* average distance to a lambda is total_distance / ( total_lambdas - lambdas )
* number of lambdas we hold weights higher than this does
* also, points for how near we are to the nearest lambda
eq(total_lambdas, lambdas) :s(rank_board_2d)
* total_distance_test = 0
i = 1
nearest_lambda_distance = larger_of_xdim_ydim
rank_board_2
ident(board<lambda_locations<i><2>, lambda_locations<i><1>>, '\') :f(rank_board_2c)
xd = lambda_locations<i><1> - robot_x
gt(xd, 0) :s(rank_board_2a)
xd = -xd
rank_board_2a
yd = lambda_locations<i><2> - robot_y
gt(yd, 0) :s(rank_board_2b)
yd = -yd
rank_board_2b
* output = "distance to lambda location " i ": " xd + yd
* figure out if this is the nearest lambda, so far
lt(xd + yd, nearest_lambda_distance) :f(rank_board_2b1)
nearest_lambda_distance = xd + yd
rank_board_2b1
total_distance = total_distance + xd + yd
* total_distance_test = total_distance_test + sqrt(xd) + sqrt(yd)
rank_board_2c
i = i + 1
le(i, lambda_locations_max) :s(rank_board_2)
* tmp = larger_of_xdim_ydim - ( total_distance / ( total_lambdas - lambdas ) )
tmp = ( larger_of_xdim_ydim - ( total_distance / ( total_lambdas - lambdas ) ) ) * xdim_ydim_scalar
* output = "adding this to rank because of lambda distances: " tmp
rank = rank + tmp
rank_board_2d
* points for how close we are to the nearest lambda
* output = "nearest lambda: " nearest_lambda_distance
* showboard(board(sr))
lt(nearest_lambda_distance, 10) :f(rank_board_near_lambda_1)
rank = rank + 10 - nearest_lambda_distance
rank_board_near_lambda_1
* distance to the exist, if we've done our homework and ate our dinner
* this is the opposite of above; we're only interested in this condition if there are no lambdas left on the board
eq(total_lambdas, lambdas) :f(rank_board_3d)
xd = exit_location<1> - robot_x
gt(xd, 0) :s(rank_board_3a)
xd = -xd
rank_board_3a
yd = exit_location<2> - robot_y
gt(yd, 0) :s(rank_board_3b)
yd = -yd
rank_board_3b
* output = "giving this many points for proximity to exit: " ( ( xdim - xd ) + ( ydim - yd ) ) / 2
exit_distance_points = ( xdim - xd ) + ( ydim - yd )
* output = "exit_distance_points: " exit_distance_points
* showboard(board(sr))
rank = rank + exit_distance_points
rank_board_3d
* store it, return it
rank_board = rank
ranking(sr) = rank_board
* debugging
* gt(rank_board, 0) :f(rank_board_5b)
* output = "rank_board debug: got >0 score of " rank_board " on this board:"
* output = "rank_board debug: score of " rank_board " on this board:"
* output = "ssb: " ssb " robot_x: " robot_x " robot_y: " robot_y
* output = "total distances to lambdas: " total_distance " divided by num remaining lambdas: " total_distance / ( total_lambdas - lambdas )
*rank_board_5a
** sb len(xdim) . output = :f(rank_board_5b)s(rank_board_5a)
* showboard(board(sr))
*rank_board_5b
* debugging
:(return)
rank_board_end
*
*
*
define('sort_queue(),i,j,ranking') :(sort_queue_end)
sort_queue
queue = rsort(queue, 2)
* the result of the sort should be that all of the non-null stuff gets moved to the top, so fix high/low to match
queue_high = queue_high - queue_low
queue_low = 0
* highly experimental; can we get rid of the stupid stuff in the queue? probably not unless/until we start
* deducting points for stupidity
lt(queue_high, queue_max / 2) :s(sort_queue5z)
i = queue_max / 4
* output = "debug: emptying queue to halfway point; dropping " queue_high - i " entries"
* output = "debug: emptying queue to one-quarter way point; dropping " queue_high - i " entries"
sort_queue5b
queue<i><1> = 0
queue<i><2> = 0
i = i + 1
le(i, queue_high) :s(sort_queue5b)
queue_high = queue_max / 4
* output = "new queue_high: " queue_high
sort_queue5z
:(return)
sort_queue_end
*
*
*
define('replay(replay_route)ssb,board,score,lambdas,robot_x,robot_y,state,move,next_move') :(replay_end)
replay
output = "=================================================================="
output = "replaying route: " replay_route
state = initial_state
output(.patterns_file, 2, '', "rules.sno")
replay_loop
board = board(state)
score = score(state)
lambdas = lambdas(state)
robot_x = robot_x(state)
robot_y = robot_y(state)
* debug
* showboard(board)
* debug
replay_route len(1) . next_move
gt(size(next_move), 0) :f(replay00)
ssb = spiral_stringify_board(board, robot_x, robot_y)
output = patterns_file = " rules<'" ssb "'> = 1 ;* " next_move
ssb rpos(4) len(4) =
output = patterns_file = " rules<'" ssb "'> = 1 ;* " next_move
replay00
replay_route len(1) . move = :f(return)
eq(lambdas, total_lambdas) :s(replay0a)
enterable = any(' .\') :(replay0b)
replay0a
enterable = any(' .\L')
replay0b
ident(move, "L") :f(replay_1)
state = move_w(copy(board),score,lambdas,route,robot_x,robot_y) :f(replay_died)
replay_1
ident(move, "D") :f(replay_2)
state = move_d(copy(board),score,lambdas,route,robot_x,robot_y) :f(replay_died)
replay_2
ident(move, "R") :f(replay_3)
state = move_e(copy(board),score,lambdas,route,robot_x,robot_y) :f(replay_died)
replay_3
ident(move, "U") :f(replay_4)
state = move_u(copy(board),score,lambdas,route,robot_x,robot_y) :f(replay_died)
replay_4
ident(datatype(state), "SAVED_ROUTE") :s(replay_loop)
output = "replay: move gave us back a " datatype(state) "; giving up" :(return)
replay_died
output = "You died." :(return)
replay_end
*
*
*
define('interactive()board,route,score,lambdas,robot_x,robot_y') :(interactive_end)
interactive
state = queue<queue_low,1>
interactive_loop
board = board(state)
route = route(state)
score = score(state)
lambdas = lambdas(state)
robot_x = robot_x(state)
robot_y = robot_y(state)
showboard(board)
eq(lambdas, total_lambdas) :s(interactive0a)
enterable = any(' .\') :(interactive0b)
interactive0a
enterable = any(' .\L')
interactive0b
move = trim(input)
output = "read move: " move
move any('qxt') :f(interactive_0)
output = "quitting interactive mode on character " move :(return)
interactive_0
ident(move, "w") :f(interactive_1)
state = move_w(copy(board),score,lambdas,route,robot_x,robot_y) :f(interactive_died)
interactive_1
ident(move, "d") :f(interactive_2)
state = move_d(copy(board),score,lambdas,route,robot_x,robot_y) :f(interactive_died)
interactive_2
ident(move, "e") :f(interactive_3)
state = move_e(copy(board),score,lambdas,route,robot_x,robot_y) :f(interactive_died)
interactive_3
ident(move, "u") :f(interactive_4)
state = move_u(copy(board),score,lambdas,route,robot_x,robot_y) :f(interactive_died)
interactive_4
* debug
:(interactive_loop)
interactive_died
output = "You died." :(return)
interactive_end
*
*
*
define('play()board,route,score,lambdas,robot_x,robot_y') :(playend)
play
* have we run out of queued routes to explore?
gt(queue_low, queue_high) :s(return)
* have we run out of time to explore routes?
gt( time() / 1000, time_limit ) :s(return)
* every now and then, re-sort the queue
queue_sort_counter = queue_sort_counter + 1
* lt(queue_sort_counter, 300 ) :s(play0)
lt(queue_sort_counter, sort_queue_every ) :s(play0)
queue_sort_counter = 0
sort_queue()
play0
* queue<n,1> contains the 'saved_route' record; queue<n,2> is the sort priority
board = board(queue<queue_low,1>)
route = route(queue<queue_low,1>)
score = score(queue<queue_low,1>)
lambdas = lambdas(queue<queue_low,1>)
robot_x = robot_x(queue<queue_low,1>)
robot_y = robot_y(queue<queue_low,1>)
* free up the memory, especially from the board, and move up the index of the first occupied slow
* zero the sort order in ,2
queue<queue_low,1> = 0
queue<queue_low,2> = 0
queue_low = queue_low + 1
* XXX debug
* output = "route: " route
* showboard(board)
* output = "lambdas: " lambdas " total_lambdas: " total_lambdas
eq(lambdas, total_lambdas) :s(play0a)
enterable = any(' .\') :(play0b)
play0a enterable = any(' .\L')
* debugging
* output = "got all the lambdas! robot_x " robot_x " robot_y " robot_y " route: " route
* showboard(board)
play0b
* try moving different directions; the result of being able to move a direction is that that new route gets
* pushed onto the queue
* don't do stuff like DURLDURL where we move around between four spaces over and over again
* XXX but this would also rule out lluulluu and llllllll
* route rpos(8) len(4) $ tmp *tmp :s(play)
* don't go RLRL, etc
route rpos(4) "LRLR" :s(play1)
move_w(copy(board),score,lambdas,route,robot_x,robot_y)
play1
route rpos(4) "DUDU" :s(play2)
move_d(copy(board),score,lambdas,route,robot_x,robot_y)
play2
route rpos(4) "RLRL" :s(play3)
move_e(copy(board),score,lambdas,route,robot_x,robot_y)
play3
route rpos(4) "UDUD" :s(play4)
move_u(copy(board),score,lambdas,route,robot_x,robot_y)
play4
iterations = iterations + 1
* loop around and pick another route off of the front of the queue
:(play)
playend
*
*
*
* 'VALUE' indicates that a trace item should be printed whenever the value of n is set.
* 'CALL' indicates that each call of function n is to be traced.
* 'RETURN' indicates that each return from function n is to be traced.
* 'FUNCTION' indicates that both calls and returns for function n are to be traced.
* 'LABEL' indicates that goto's to the label n are to be traced. Note that simple sequential flow into a statement with that label is not traced.
* &trace = 100
* trace("play", "FUNCTION")
* trace("runboard", "FUNCTION")
* trace("move_u", "FUNCTION")
* trace("move_d", "FUNCTION")
* trace("move_w", "FUNCTION")
* trace("move_d", "FUNCTION")
*
*
*
* new_saved_route(board,route,score,ranking,lambdas,robot_x,robot_y,runtime)
initial_state = new_saved_route(board, "", 0, 1, 0,robot_x,robot_y, 0)
queue<0,1> = initial_state
queue<0,2> = 1
queue_low = 0
queue_high = 0
time_limit = host(2, host(3) + 1)
* output = "time limit: " time_limit
* XXX interactive or play
* interactive()
play()
ident(host(2,1), "-b") :s(highest_scoring_route_skip) ;* shh, quiet mode!
output = "queue used: " queue_high - queue_low " of total: " queue_max
output = "highest score: " highest_score
output = "total lambdas on board: " total_lambdas
output = "runtime now: " time() / 1000
output = "iterations ran: " iterations
output = "iterations/sec: " iterations / ( time() / 1000 )
ident(datatype(highest_scoring_route), "SAVED_ROUTE") :s(highest_scoring_route)
output = "left with a " datatype(highest_scoring_route) " instead of a SAVED_ROUTE; giving up" :(highest_scoring_route_skip)
highest_scoring_route
output = "highest score route: "
show_saved_route(highest_scoring_route)
highest_scoring_route_skip
* XXX
* evaluate how well sorting heuristics did; sort the queue and then dump the queue
* sort_queue()
* dump_queue()
* XXX
* use this in conjunction with interactive mode to output patterns and associated movements
* replay( route(highest_scoring_route) )
* always output the route
output = route(highest_scoring_route)
end
tar -xzvf snobol4-1.4.1.tar.gz
cd snobol4-1.4.1$
./configure --without-readline --prefix=$HOME
make && make install
$HOME/bin/snobol4 -b -d 40m boulder.sno - 149
snobol4 -- Programs written in SNOBOL require a SNOBOL interpreter to run. For some reason, Debian doesn't have any, so I've included the sourceball for one. The install script will attempt to build it and install it into $HOME, and the ./lifter wrapper attempts to use that. The tarball is originally available from http://www.snobol4.org/csnobol4/curr/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment