@cocacola-lover/knight_path_finder
Version:
Iterative path finding Algorithms for knight on a chessboard
266 lines (183 loc) • 7.59 kB
text/typescript
import { Square } from "./interfaces.js";
namespace ChessPointers {
export class BasicPointer {
readonly x : number;
readonly y : number;
readonly board : Square[][];
constructor(x : number, y : number, board : Square[][]) {
this.x = x; this.y = y; this.board = board;
}
at() : Square {
return this.board[this.x][this.y];
}
getNeighbours() : BasicPointer[] {
const ans: BasicPointer[] = [];
const moveOne : number[] = [1, -1];
moveOne.forEach((x) => {
if (this.isWithinBounds(this.x + x, this.y)) ans.push(new BasicPointer(this.x + x, this.y, this.board))
});
moveOne.forEach((y) => {
if (this.isWithinBounds(this.x, this.y + y)) ans.push(new BasicPointer(this.x, this.y + y, this.board))
})
return ans;
}
getPassableNeighbours() : BasicPointer[] {
return this.getNeighbours().filter((pointer) => pointer.at().isPassable);
}
toString() {
return `${this.x},${this.y}`;
}
static areSame(a : BasicPointer, b : BasicPointer) : boolean {
return a.board === b.board && a.x === b.x && a.y === b.y;
}
protected isWithinBounds(x: number, y : number) : boolean {
if (this.board[x] === undefined) return false;
if (this.board[x][y] === undefined) return false;
return true;
}
}
export class KnightPointer extends BasicPointer {
getNeighbours() : KnightPointer[] {
const ans: KnightPointer[] = [];
const moveOne : number[] = [1, -1];
const moveTwo : number[] = [2, -2];
moveOne.forEach((y) => {
moveTwo.forEach((x) => {
if (this.isWithinBounds(this.x + x, this.y + y)) ans.push(new KnightPointer(this.x + x, this.y + y, this.board))
if (this.isWithinBounds(this.x + y, this.y + x)) ans.push(new KnightPointer(this.x + y, this.y + x, this.board))
})
})
return ans;
}
}
export class KingPointer extends BasicPointer {
getNeighbours() : KingPointer[] {
const ans: KingPointer[] = [];
const moveOne : number[] = [1, -1, 0];
moveOne.forEach((y) => {
moveOne.forEach((x) => {
if (this.isWithinBounds(this.x + x, this.y + y)) ans.push(new KingPointer(this.x + x, this.y + y, this.board))
if (this.isWithinBounds(this.x + y, this.y + x)) ans.push(new KingPointer(this.x + y, this.y + x, this.board))
})
})
return ans;
}
}
export class BishopPointer extends BasicPointer {
getNeighbours() : BishopPointer[] {
const ans: BishopPointer[] = [];
const moveDiagonal : number[][] = [[1, 1], [-1, -1], [-1, 1], [1, -1]];
moveDiagonal.forEach((pair) => {
let [x, y] = pair;
for (let i = 1; this.isWithinBounds(this.x + x * i, this.y + y * i); i++)
ans.push(new BishopPointer(this.x + x * i, this.y + y * i, this.board));
})
return ans;
}
getPassableNeighbours(): BishopPointer[] {
const ans: BishopPointer[] = [];
const moveDiagonal : number[][] = [[1, 1], [-1, -1], [-1, 1], [1, -1]];
moveDiagonal.forEach((pair) => {
let [x, y] = pair;
for (let i = 1; this.isWithinBounds(this.x + x * i, this.y + y * i); i++){
const newPointer = new BishopPointer(this.x + x * i, this.y + y * i, this.board);
if (newPointer.at().isPassable) ans.push(newPointer);
else break;
}
})
return ans;
}
}
export class RookPointer extends BasicPointer {
getNeighbours() : RookPointer[] {
const ans: RookPointer[] = [];
const moveOne : number[] = [1, -1];
moveOne.forEach((x) => {
for (let i = 1; this.isWithinBounds(this.x + x * i, this.y); i++)
ans.push(new RookPointer(this.x + x, this.y, this.board))
});
moveOne.forEach((y) => {
for (let i = 1; this.isWithinBounds(this.x, this.y + y * i); i++)
ans.push(new RookPointer(this.x, this.y + y * i, this.board))
})
return ans;
}
getPassableNeighbours() : RookPointer[] {
const ans: RookPointer[] = [];
const moveOne : number[] = [1, -1];
moveOne.forEach((x) => {
for (let i = 1; this.isWithinBounds(this.x + x * i, this.y); i++){
const newPointer = new RookPointer(this.x + x * i, this.y, this.board)
if (newPointer.at().isPassable) ans.push(newPointer);
else break;
}
});
moveOne.forEach((y) => {
for (let i = 1; this.isWithinBounds(this.x, this.y + y * i); i++){
const newPointer = new RookPointer(this.x, this.y + y * i, this.board)
if (newPointer.at().isPassable) ans.push(newPointer);
else break;
}
})
return ans;
}
}
export class PawnPointer extends BasicPointer {
getNeighbours() : PawnPointer[] {
const ans: PawnPointer[] = [];
if (this.isWithinBounds(this.x, this.y + 1))
ans.push(new PawnPointer(this.x, this.y + 1, this.board));
return ans;
}
}
export class QueenPointer extends BasicPointer {
getNeighbours() : QueenPointer[] {
const ans: QueenPointer[] = [];
const moveDiagonal : number[][] = [[1, 1], [-1, -1], [-1, 1], [1, -1]];
moveDiagonal.forEach((pair) => {
let [x, y] = pair;
for (let i = 1; this.isWithinBounds(this.x + x * i, this.y + y * i); i++)
ans.push(new QueenPointer(this.x + x * i, this.y + y * i, this.board));
});
const moveOne : number[] = [1, -1];
moveOne.forEach((x) => {
for (let i = 1; this.isWithinBounds(this.x + x * i, this.y); i++)
ans.push(new QueenPointer(this.x + x, this.y, this.board))
});
moveOne.forEach((y) => {
for (let i = 1; this.isWithinBounds(this.x, this.y + y * i); i++)
ans.push(new QueenPointer(this.x, this.y + y * i, this.board))
})
return ans;
}
getPassableNeighbours() : QueenPointer[] {
const ans: QueenPointer[] = [];
const moveDiagonal : number[][] = [[1, 1], [-1, -1], [-1, 1], [1, -1]];
moveDiagonal.forEach((pair) => {
let [x, y] = pair;
for (let i = 1; this.isWithinBounds(this.x + x * i, this.y + y * i); i++){
const newPointer = new QueenPointer(this.x + x * i, this.y + y * i, this.board);
if (newPointer.at().isPassable) ans.push(newPointer);
else break;
}
});
const moveOne : number[] = [1, -1];
moveOne.forEach((x) => {
for (let i = 1; this.isWithinBounds(this.x + x * i, this.y); i++){
const newPointer = new QueenPointer(this.x + x * i, this.y, this.board)
if (newPointer.at().isPassable) ans.push(newPointer);
else break;
}
});
moveOne.forEach((y) => {
for (let i = 1; this.isWithinBounds(this.x, this.y + y * i); i++){
const newPointer = new QueenPointer(this.x, this.y + y * i, this.board)
if (newPointer.at().isPassable) ans.push(newPointer);
else break;
}
})
return ans;
}
}
};
export default ChessPointers;