Your task is to write a RoboZZle interpreter. If you're not familiar with the game, please watch the video at robozzle.com or read my description below.
A robot lives on a rectangular grid of squares coloured red, green, blue, or black. Black squares are inaccessible. The others are accessible and some of them contain a star. The goal is to collect all the stars without stepping on the black squares or falling off the map. The robot occupies one square and faces a particular direction - left, right, up, or down. It follows assembly-like instructions grouped into subroutines F1,F2,...,F5. An instruction is a pair of a predicate ("none", "if on red", "if on green", "if on blue") and an action ("go forward", "turn left", "turn right", "paint the current square red", "paint it green", "paint it blue", "do nothing", "call F1", ..., "call F5"). Calls to subroutines use a stack and can be recursive. Just like in conventional programming, after the last instruction of a subroutine is completed, execution carries on from the point where the subroutine was called. Execution begins from the first instruction of F1 and continues until either the robot has visited all squares with stars, or when the robot steps on a black square or outside the map, or 1000 instructions have been executed (failed predicates and "do nothing" actions don't count), or there are no more instructions to execute (stack underflow).
Inputs:
a
- a 12x16 character matrix (as usually represented in your language, e.g. array of strings) that encodes a map -'#'
for inaccessible (black) squares,'*'
for squares with a star,'.'
for the restc
- a 12x16 character matrix describing the colours of accessible squares -'R'
(red),'G'
(green), or'B'
(blue). Inaccessible squares will be represented by an arbitrary letter from the three.y
andx
- the robot's 0-based row and column;a[y][x]
is guaranteed to be'.'
d
- the direction the robot is facing:0 1 2 3
for right, down, left, up, i.e. towards(y,x+1)
,(y+1,x)
,(y,x-1)
,(y-1,x)
f
- a single string, the concatenated implementations of F1...F5. Each implementation is a (possibly empty) sequence of predicate-action pairs (at most 10 pairs per subroutine), terminated with a'|'
.predicates:
'_'
none,'r'
red,'g'
green,'b'
blueactions:
'F'
go forward,'L'
turn left,'R'
turn right,'r'
paint red,'g'
paint green,'b'
paint blue,'1'
call F1, ...,'5'
call F5,'_'
do nothing
You don't have to name you inputs like the above, but their values must be as specified.
Output: 1
(or true
) if the robot collects all stars according to the rules, 0
(false
) otherwise.
a=["################","################","##*....*...*#.##","##.####.#####.##","##.####.#####.##","##.####*...*#.##","##.########.####","##*........*#.##","################","################","################","################"]
c=["RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRBBBBRGGGGRRRR","RRBRRRRGRRRRRRRR","RRBRRRRGRRRRRRRR","RRBRRRRRGGGBRRRR","RRBRRRRRRRRGRRRR","RRRBBBBGGGGBRBRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR"]
y=2; x=6; d=2
// and then depending on "f":
f="_FrLg2_1|_FbLrR_2||||" // result:1
f="_FrRg2_1|_FbLrR_2||||" // result:0 (stepped on a black square)
f="_FrLrL_1|_FbLrR_2||||" // result:0 (1000-step limit exceeded)
f="_FrLg2__|________||||" // result:0 (stack underflow)
Another example, involving "paint" instructions:
a=["#***************","#*###*###*###*##","#*###*###*###*##","***#***#***#***#","***#***#***#***#","*###*###*###*###","***#***#***#***#","***#***#***#***#","***#***#***#***#","*###*###*###*###","*.*#***#***#***#","***#***#***#***#"]
c=["RGGGGGGGGGGGGGGG","RBRRRGRRRGRRRGRR","RBRRRGRRRGRRRGRR","RBRRGGGRGGGRGGGR","BRRRGGGRGGGRGGGR","BRRRGRRRGRRRGRRR","BRRRGGGRGGGRGGGR","RBRRGGGRGGGRGGGR","BRRRGGGRGGGRGGGR","BRRRGRRRGRRRGRRR","BGRRGGGRGGGRGGGR","RBRRGGGRGGGRGGGR"]
y=10; x=1; d=0
f="_2_R_R_1|_FgRgFgFg3rRr4b2_Fgb|_F_F_R|_2_L_r||"
// result:1
To generate your own test, go to a puzzle from the list at robozzle.com, try to solve it (or not solve it), press F12 in your browser, type in the JS console:
r=robozzle;s=JSON.stringify;with(r.level)console.log('a='+s(Items)+'\nc='+s(Colors)+'\ny='+RobotRow+'\nx='+RobotCol+'\nd='+RobotDir+'\nf='+s(r.encodeSolution()))
and reformat the result for your language.
Shortest wins. No loopholes.