portfolio/assets/js/pathfinder.js
2026-01-01 19:34:11 -05:00

164 lines
3.1 KiB
JavaScript

const timer = ms => new Promise(res => setTimeout(res, ms))
var cols = 8
var rows = 8
let grid = new Array(cols);
let openSet = [];
let closedSet = [];
let start;
let end;
let path = [];
function heuristic(position0, position1) {
let d1 = Math.abs(position1.x - position0.x);
let d2 = Math.abs(position1.y - position0.y);
return d1 + d2;
}
function GridPoint(x, y) {
this.x = x;
this.y = y;
this.f = 0;
this.g = 0;
this.h = 0;
this.neighbors = [];
this.parent = undefined;
this.updateNeighbors = function(grid) {
let i = this.x;
let j = this.y;
var tmpNeighbor;
if (i < cols - 1) {
tmpNeighbor = grid[i + 1][j]
if (!player.isBoundary([tmpNeighbor.x, tmpNeighbor.y])) {
this.neighbors.push(tmpNeighbor);
}
}
if (i > 0) {
tmpNeighbor = grid[i - 1][j]
if (!player.isBoundary([tmpNeighbor.x, tmpNeighbor.y])) {
this.neighbors.push(tmpNeighbor);
}
}
if (j < rows - 1) {
tmpNeighbor = grid[i][j + 1]
if (!player.isBoundary([tmpNeighbor.x, tmpNeighbor.y])) {
this.neighbors.push(tmpNeighbor);
}
}
if (j > 0) {
tmpNeighbor = grid[i][j - 1]
if (!player.isBoundary([tmpNeighbor.x, tmpNeighbor.y])) {
this.neighbors.push(tmpNeighbor);
}
}
};
}
function init(destX, destY) {
for (let i = 0; i < cols; i++) {
grid[i] = new Array(rows);
}
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
grid[i][j] = new GridPoint(i, j);
}
}
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
grid[i][j].updateNeighbors(grid);
}
}
start = grid[player.canvasX][player.canvasY];
end = grid[destX][destY]
openSet.push(start);
console.log(grid);
}
function search(destX, destY) {
path = [];
init(destX, destY);
while (openSet.length > 0) {
let lowestIndex = 0;
for (let i = 0; i < openSet.length; i++) {
if (openSet[i].f < openSet[lowestIndex].f) {
lowestIndex = i;
}
}
let current = openSet[lowestIndex];
if (current === end) {
let temp = current;
path.push(temp);
while (temp.parent) {
path.push(temp.parent);
temp = temp.parent;
}
return path.reverse()
}
openSet.splice(lowestIndex, 1);
closedSet.push(current);
let neighbors = current.neighbors;
for (let i = 0; i < neighbors.length; i++) {
let neighbor = neighbors[i];
if (!closedSet.includes(neighbor)) {
let possibleG = current.g + 1;
if (!openSet.includes(neighbor)) {
openSet.push(neighbor);
} else if (possibleG >= neighbor.g) {
continue;
}
neighbor.g = possibleG;
neighbor.h = heuristic(neighbor, end);
neighbor.f = neighbor.g + neighbor.h;
neighbor.parent = current;
}
}
}
return [];
}
async function pathfind(destX, destY) {
var newPath = search(destX, destY)
for (let i = 0; i < newPath.length; i++) {
if (newPath[i].x > player.canvasX) {
player.direction = 'right'
} else if (newPath[i].x < player.canvasX) {
player.direction = 'left'
}
if (newPath[i].y > player.canvasY) {
player.direction = 'down'
} else if (newPath[i].y < player.canvasY) {
player.direction = 'up'
}
player.canvasX = newPath[i].x
player.canvasY = newPath[i].y
await timer(100)
}
}