Created
July 14, 2012 21:26
-
-
Save scottwalters/3113445 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* | |
* 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 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
tar -xzvf snobol4-1.4.1.tar.gz | |
cd snobol4-1.4.1$ | |
./configure --without-readline --prefix=$HOME | |
make && make install |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$HOME/bin/snobol4 -b -d 40m boulder.sno - 149 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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