Prequel
primitive recursive driven programming


Maze

(This example requires web workers.)

Find the key. Escape from the labirinth.

0 ← moves (min moves: 0)

Shuffle Hide

Run Pause Stop

0
0
0
← calls
← instructions
← memory (max use: 0)


Prequel program

Edit Save Debug

Module: RANDOM_WALK

IF MAZE.KEY_NEEDED >= 0 AND MAZE.HAS_KEY == 1
MAZE.MOVE(MAZE.KEY_NEEDED)
ENDIF
options = 0
n = MAZE.CAN_MOVE.LENGTH
REPEAT n
IF n <> MAZE.FROM AND n <> MAZE.KEY_NEEDED AND MAZE.CAN_MOVE[n] == 1
options += 1
ENDIF
ENDREP
IF options == 0 # dead end
to_cardinal = MAZE.FROM
MAZE.MOVE(to_cardinal)
ENDIF
random_option ~= options
to_cardinal = (MAZE.FROM+1)%4
IF MAZE.CAN_MOVE[to_cardinal] == 1 AND to_cardinal <> MAZE.KEY_NEEDED
IF random_option == 0
MAZE.MOVE(to_cardinal)
ENDIF
random_option--
ENDIF
to_cardinal = (MAZE.FROM+3)%4
IF MAZE.CAN_MOVE[to_cardinal] == 1 AND to_cardinal <> MAZE.KEY_NEEDED
IF random_option == 0
MAZE.MOVE(to_cardinal)
ENDIF
ENDIF
to_cardinal = (MAZE.FROM+2)%4
MAZE.MOVE(to_cardinal)

Input:

MAZE.INDEX_NORTH
MAZE.INDEX_EAST
MAZE.INDEX_SOUTH
MAZE.INDEX_WEST
 Index of cardinal points.
 -> 0 north-index
 -> 1 east-index
 -> 2 south-index
 -> 3 west-index
 Constants.
MAZE.CELL_CURRENT
 Current position in 2D coordinates.
 -> e.g. [0, 0]
MAZE.FROM
 Cardinal index of previous position.
 -> -1 if it is still at the starting position
 -> MAZE.INDEX_NORTH if it has arrived from north
 -> MAZE.INDEX_EAST if it has arrived from east
 -> MAZE.INDEX_SOUTH if it has arrived from south
 -> MAZE.INDEX_WEST if it has arrived from west
MAZE.CAN_MOVE[cardinal_index]
 Check whether movement is possible
  from the current position
  to each cardinal_index.
 -> 1 if it is
 -> 0 if it is not
MAZE.HAS_KEY
 Check whether key is being carried.
 -> 1 if it is
 -> 0 if it is not
MAZE.KEY_NEEDED
 Check whether the key is needed to make the next move.
 -> -1 if the key is not needed
 -> MAZE.INDEX_NORTH if the key is needed to move north
 -> MAZE.INDEX_EAST if the key is needed to move east
 -> MAZE.INDEX_SOUTH if the key is needed to move south
 -> MAZE.INDEX_WEST if the key is needed to move west
MAZE.CELL[cardinal_index]
 Adjacent 2D coordinates
  from the current position
  to cardinal_index.
 -> e.g. [1, 0]
MAZE.CELLS_VISITED
 List of cells already visited.
 -> e.g. [[0, 0], [1, 0]]
CALL.ARGS
 Holds the list of arguments passed with CALL.
 -> [arg1, ..., argN]

Procedures:

MAZE.MOVE(cardinal_index)
 Try to move to MAZE.CELL[cardinal_index].
 Restart program counter.
 Note that it increments the movement counter even if it cannot move.
CALL(&retvar1, ..., &retvarM, @modname, arg1, ..., argN)
 Start executing module modname, copying N arguments and expecting M return values.
 -> retvar: name of variable to hold the corresponding return value retval
 -> modname: name of module to start executing
 -> arg: value to be copied to the list CALL.ARGS
 Alternative syntax: retvar1, ..., retvarM = CALL(@modname, arg1, ..., argN)
 Note that recursive module calls are not allowed.
RETURN(retval1, ..., retvalM)
 Return M values from the current module.
 Resume execution at the next instruction of the corresponding CALL.
 -> retval: value to be copied to the corresponding variable retvar

Additional examples can be found on GitHub.