swarm-0.3.0.0: data/scenarios/Challenges/_word-search/solution.sw
def doN = \n. \f. if (n > 0) {f; doN (n - 1) f} {}; end;
def intersperse = \n. \f2. \f1. if (n > 0) {
f1;
if (n > 1) {
f2;
} {};
intersperse (n - 1) f2 f1;
} {};
end;
def waitUntilUnblocked =
x <- blocked;
if x {
wait 1;
waitUntilUnblocked;
} {};
end;
def whichOrdinal =
isC <- ishere "capital C";
if (isC) {
return 0;
} {
isO <- ishere "capital O";
if (isO) {
return 1;
} {
isW <- ishere "capital W";
if (isW) {
return 2;
} {
return (-1);
}
}
}
end;
// Go to upper-left corner
def goToCorner =
myLoc <- whereami;
doN (fst myLoc) move;
turn right;
doN (-(snd myLoc)) move;
turn right;
end;
def highlightLetter =
drill down;
end;
def traverseRow = \expectedOrdinal. \colCount.
theFoundOrdinal <- whichOrdinal;
// Logic: the first letter of the target word is *always*
// considered a "match".
let shouldAdvance = theFoundOrdinal == expectedOrdinal || theFoundOrdinal == 0 in
newExpectedOrdinal <- if shouldAdvance {
return $ theFoundOrdinal + 1;
} {
// Reset the progress
return 0;
};
if (newExpectedOrdinal == 3) {
turn back;
intersperse 3 move highlightLetter;
return true;
} {
if (colCount > 1) {
move;
traverseRow newExpectedOrdinal (colCount - 1);
} {
return false;
};
};
end;
def advanceRow =
turn left;
move;
turn left;
end;
/**
Travels forward and then backward
across a row, to check for solutions
in either direction.
*/
def traverseCols = \width. \height.
didWin <- traverseRow 0 width;
if didWin {
return true;
} {
turn back;
didWinBackward <- traverseRow 0 width;
if didWinBackward {
return true;
} {
if (height > 1) {
advanceRow;
traverseCols width $ height - 1;
} {
return false;
};
}
}
end;
def solve = \boardWidth. \boardHeight.
waitUntilUnblocked;
goToCorner;
wonHorizontally <- traverseCols boardWidth boardHeight;
if wonHorizontally {
return true;
} {
// If we did not find a horizontal solution,
// look for vertical solutions.
turn right;
traverseCols boardHeight boardWidth;
}
end;
solve 25 15;