odin-codespace/csci/knightsTravials.js

157 lines
4 KiB
JavaScript

class Node {
constructor() {
this.distance = null;
this.predecessor = null;
}
}
class Queue {
constructor() {
this.queue = [];
}
enqueue(thing) {
this.queue.push(thing);
}
dequeue() {
return this.queue.shift();
}
isEmpty() {
return this.queue.length === 0;
}
}
class Graph {
constructor(columns, rows) {
this.adjMatrix = [];
this.rows = rows;
this.columns = columns;
// Build the adj list
this.buildAdjList();
}
buildAdjList() {
this.adjList = [];
// Possible knight moves relative to its current position
const moves = [
[-1, -2],
[-2, -1],
[-2, 1],
[-1, 2],
[1, -2],
[2, -1],
[2, 1],
[1, 2],
];
for (let y = 0; y < this.rows; y++) {
let rowData = [];
for (let x = 0; x < this.columns; x++) {
let adjPositions = [];
// Generate adjacent positions for the current square
for (const [dx, dy] of moves) {
const newX = x + dx;
const newY = y + dy;
// Check if the new position is within the board boundaries
if (
newX >= 0 &&
newX < this.columns &&
newY >= 0 &&
newY < this.rows
) {
adjPositions.push([newX, newY]);
}
}
rowData.push(adjPositions);
}
this.adjList.push(rowData);
}
}
knightMoves(start, finish) {
this.bfsInfo = [];
let itemFound = false;
this.start = start;
this.finish = finish;
for (let i = 0; i < this.columns; i++) {
this.bfsInfo[i] = [];
for (let j = 0; j < this.rows; j++) {
this.bfsInfo[i][j] = new Node();
}
}
// This is to mark where we're starting the loop
this.bfsInfo[start[0]][start[1]].distance = 0;
// instantiate the queue
let queue = new Queue();
queue.enqueue(start);
while (!queue.isEmpty() && !itemFound) {
let vertex = queue.dequeue();
if (vertex[0] === finish[0] && vertex[1] === finish[1]) {
itemFound = true;
break;
}
for (
let i = 0;
i < this.adjList[vertex[1]][vertex[0]].length;
i++
) {
let neighbor = this.adjList[vertex[1]][vertex[0]][i];
let x = neighbor[0];
let y = neighbor[1];
if (this.bfsInfo[x][y].distance === null) {
this.bfsInfo[x][y].distance =
this.bfsInfo[vertex[0]][vertex[1]].distance + 1;
this.bfsInfo[x][y].predecessor = [vertex[0], vertex[1]];
}
queue.enqueue(neighbor);
}
}
}
lookAtBfs() {
this.path = [this.finish];
let queue = new Queue();
let x = this.finish[0];
let y = this.finish[1];
queue.enqueue(this.bfsInfo[x][y]);
while (!queue.isEmpty()) {
let current = queue.dequeue();
if (current.predecessor) {
this.path.unshift(current.predecessor);
x = current.predecessor[0];
y = current.predecessor[1];
let previousNode = this.bfsInfo[x][y];
queue.enqueue(previousNode);
}
}
return this.path;
}
}
let g = new Graph(8, 8);
console.dir(g.adjList);
console.table(g.adjList[0]);
console.table(g.adjList[0][0]);
g.knightMoves([0, 0], [7, 7]);
console.log(g.lookAtBfs());
g.knightMoves([0, 0], [3, 3]);
console.log(g.lookAtBfs());
g.knightMoves([3, 3], [4, 3]);
console.log(g.lookAtBfs());