// Base case
// 1. Off the map
// 2. Hit a wall
// 3. Already visited
// 4. It's the end
const dirs = [
[1, 0], //top
[0, 1], //right
[-1, 0], //bottom
[0, -1], //left
];
function walk(
maze: string[],
wall: string,
curr: Point,
end: Point,
seen: boolean[][],
path: Point[],
): boolean {
// Base case
// 1. Off the map
if (
curr.x < 0 ||
curr.x >= maze[0].length ||
curr.y < 0 ||
curr.y >= maze.length
) {
return false;
}
// 2. Hit a wall
if (maze[curr.y][curr.x] === wall) {
return false;
}
// 3. Already visited
if (seen[curr.y][curr.x]) {
return false;
}
// 4. It's the end
if (curr.y === end.y && curr.x === end.x) {
path.push(curr);
return true;
}
// do Recurse
// pre
// update seen array
seen[curr.y][curr.x] = true;
// add next point to the path
path.push(curr);
// recurse
for (let i = 0; i < dirs.length; i++) {
const [y, x] = dirs[i];
if (
walk(maze, wall, { y: curr.y + y, x: curr.x + x }, end, seen, path)
) {
return true;
}
}
// post
// it's not the correct path, remove it
path.pop();
return false;
}
export default function solve(
maze: string[],
wall: string,
start: Point,
end: Point,
): Point[] {
const seen: boolean[][] = Array.from({ length: maze.length }, () =>
Array.from({ length: maze[0].length }, () => false),
);
const path: Point[] = [];
walk(maze, wall, start, end, seen, path);
return path;
}
Test:
import maze_solver from "@code/MazeSolver";
test("maze solver", function () {
const maze = [
"xxxxxxxxxx x",
"x x x",
"x x x",
"x xxxxxxxx x",
"x x",
"x xxxxxxxxxx",
];
const mazeResult = [
{ x: 10, y: 0 },
{ x: 10, y: 1 },
{ x: 10, y: 2 },
{ x: 10, y: 3 },
{ x: 10, y: 4 },
{ x: 9, y: 4 },
{ x: 8, y: 4 },
{ x: 7, y: 4 },
{ x: 6, y: 4 },
{ x: 5, y: 4 },
{ x: 4, y: 4 },
{ x: 3, y: 4 },
{ x: 2, y: 4 },
{ x: 1, y: 4 },
{ x: 1, y: 5 },
];
// there is only one path through
const result = maze_solver(maze, "x", { x: 10, y: 0 }, { x: 1, y: 5 });
expect(drawPath(maze, result)).toEqual(drawPath(maze, mazeResult));
});
function drawPath(data: string[], path: Point[]) {
const data2 = data.map((row) => row.split(""));
path.forEach((p) => {
if (data2[p.y] && data2[p.y][p.x]) {
data2[p.y][p.x] = "*";
}
});
return data2.map((d) => d.join(""));
}
标签:curr,recursive,solver,end,maze,return,path,Path,const From: https://www.cnblogs.com/Answer1215/p/17574061.html