Incomplete draft: do not cite!

Clairvoyance is most useful for planning and other search algorithms, so we'll start with a very simple pathfinder.  We'll assume we have a 5x5 grid and that we're trying to get from the top-left corner to the bottom-right corner by moving only right or down.1  So, although this is a good introductory example, it won't be a good pathfinder.  That said, it's cool that its core loop can be written in one line:

while (!done()) choose right(); or down();

The map

We'll represent the map as a 2D array of strings, each of which is the name2 of a tile: white for a blank space, red for an obstacle. We'll put these in the variables s and X respectively so we can type out a grid more easily:

var s = "white";     // free space
var X = "red";       // obstacle
var size = 5;
var map = grid([
   [s, s, s, s, s],
   [s, s, s, s, s],
   [s, s, s, X, X],
   [s, s, s, s, s],
   [s, s, s, X, s]
]);

(The grid primitive just makes a 2D array)

We'll use global variables to represent our position, which will initially be the top-left corner:

var x = 0;
var y = 0;

The pathfinder

Again, we only move down or to the right for the moment; we never have to back up to find a solution.  So our basic algorithm is just “go right and/or down until we're there”:

function solve()
{
   while (!done())
      choose
         right();
      or
         down();
}

The right and down functions just need to change our coordinates.  But we'll also mark our path so we'll be able to see it afterward, storing either "right" (a tile with a right arrow), when we move right, or "down" one when we move down:

function right() {
   map[x, y] = "right";
   x = x+1;
}

function down() {
   map[x, y] = "down";
   y = y+1;
}

But we do have to avoid obstacles.  So if we move into a cell that has something other than s (the empty space tile), we fail:

function right() {
   map[x, y] = "right";
   x = x+1;
   if (map[x, y] != s) fail;
}

function down() {
   map[x, y] = "down";
   y = y+1;
   if (map[x, y] != s) fail;
}

And we should also fail if we move off the map:

function right() {
   map[x, y] = "right";
   x = x+1;
   if (x == size || map[x, y] != s) fail;
}

function down() {
   map[x, y] = "down";
   y = y+1;
   if (y == size || map[x, y] != s) fail;
}

You can try out the pathfinder by clicking below and then pressing the Run button in the window that pops up.  Running it multiple times will give you different paths.  And you can modify the map if you like:

// Find a way from the top-left corner to the bottom-right
// using only down- and right-moves.  Moving off the board
// or hitting an obstacle (occupied square) is failure.
function solve()
{
   while (!done())
      choose
         right();
      or
         down();
}

// Design of the map
var s = "white";     // free space
var X = "red";       // obstacle
var size = 5;
var map = grid([
             [s, s, s, s, s],
             [s, s, s, s, s],
             [s, s, s, X, X],
             [s, s, s, s, s],
             [s, s, s, X, s]
           ]);

var x = 0;
var y = 0;

function right() {
   map[x, y] = "right";
   x = x+1;
   if (x == size || map[x, y] != s) fail;
   map[x, y] = "green";
}

function down() {
   map[x, y] = "down";
   y = y+1;
   if (y == size || map[x, y] != s) fail;
   map[x, y] = "green";
}

function done()
{
   return x == size-1 && y == size-1;
}

solve();
printLine("Path:");
printTilemap(map);

Notes


  1. This is just so that all paths are the same length, which lets us defer dealing with shortest paths until later.

  2. Technically it's a URL for a tile, and if no extension it defaults to .png.  So white really means the url white.png on the sandbox's server.  You can use other URLs, though, if you prefer.