mirror of
https://gitea.smigz.com/smiggiddy/odin-codeprojects.git
synced 2024-12-25 06:00:43 -05:00
157 lines
4 KiB
JavaScript
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());
|