JSFiddle - React, Tailwind, and code Playground
JavaScript
function knightPath(bounds, startPosition, targetPosition) {
class Position {
constructor(X, Y) {
if (!X || !Y) return;
this.X = X;
this.Y = Y;
}
fromString(str) {
const [X, Y] = str.split("-");
this.X = X.charCodeAt(0) - 65;
this.Y = Y - 1;
return this;
}
isValid() {
if (this.X < 0 || this.X >= bounds.X) return false;
if (this.Y < 0 || this.Y >= bounds.Y) return false;
return true;
}
toString() {
return `${String.fromCharCode(this.X + 65)}-${this.Y + 1}`;
}
}
const POSSIBLE_NEXT_POSITION_DELTAS = [
[1, 2],
[2, 1],
[2, -1],
[1, -2],
[-1, -2],
[-2, -1],
[-2, 1],
[-1, 2]
];
function generateNextPositions(position) {
return POSSIBLE_NEXT_POSITION_DELTAS.map(
delta => new Position(position.X + delta[0], position.Y + delta[1])
).filter(p => p.isValid());
}
const paths = [[new Position().fromString(startPosition)]];
while (paths.length) {
const currentPath = paths.shift();
const currentPos = currentPath[currentPath.length - 1];
const nextPositions = generateNextPositions(currentPos);
for (const nextPosition of nextPositions) {
if (nextPosition.toString() === targetPosition) {
return [...currentPath, nextPosition].map(p => p.toString());
}
const visitedPositions = currentPath.map(p => p.toString());
if (!visitedPositions.includes(nextPosition.toString())) {
paths.push([...currentPath, nextPosition]);
}
}
}
return false;
}
document.body.textContent = knightPath({ X: 8, Y: 8 }, "A-1", "B-4");