An implementation of the
a* (spoken: a star) algorithm for path finding.
Bright grey fields can be used to travel. The randomly generated dark grey
fields are obstacles.
The alogorithm starts at the yellow field in the top left corner and searches
a path to the blue target fields. The red fields show the path found. The green
fields are used during computation. They are yet to process as long as the destination
is not reached.
To start click on two cells to pick start and target.
The algorithm is divided into two steps. The first step is to find a path from start to destination.
The second path is to track back the path from destination to start.
You need three array: One with the yet to compute fields (openSet), one with the already computed
fields (closedSet) and the path array.
At first I created a grid of cells of type Acell, which is a class i defined in aclass.js. The class own following attributes:
constructor(x, y, w, h) {
this.x = x;
this.y = y;
this.wi = w;
this.he = h;
this.f;
this.g;
this.h;
this.neighbors = [];
this.prev = undefined;
this.obstacle=false;
}
Where x and y are the indices of the cell in the grid and wi and he are its width and height. f, g, h are valkues used in the the a* algorithm. Where
function draw() {
let current;
if(openSet.length === 0) {
noLoop(); // no solution available
} else {
let c = getLowestScoreCell();
current = openSet[c];
if(current === goal) { // found the goal
let temp = current;
for(let i = 0; i < 25; i++ ) {
temp = temp.getPrevious();
}
noLoop();
}
// remove current cell from openSet, add it to closedSet and
// process every neighbor of current
openSet.splice(current, 1);
closedSet.push(current);
var neighbors = current.getNeighbors();
for(let i = 0; i < neighbors.length; i++) {
var neighbor = neighbors[i];
if(neighbor != undefined && neighbor.obstacle==false) {
if( !closedSet.includes(neighbors) ) {
// add one to the g value (grid)
var tempG = current.getG() + 1;
if( openSet.includes(neighbor) ) {
// If open set contains this cell and the calculated g value
// is smaller than its value, update the cell
if( tempG < neighbor.getG() ) {
neighbor.setG(tempG);
}
} else {
neighbor.setG(tempG);
openSet.push(neighbor);
}
}
// Compute the h and f values for the current cell.
neighbor.setH( heuristic(neighbor, goal) );
neighbor.setF( neighbor.getG() + neighbor.getH() );
neighbor.setPrevious(current);
}
}
}
}
One important function that is used in the above algorithm is function getLowestScoreCell() which returns the cell whith the lowest score (the lowest f value), i.e. the cell with which the algorithm will proceed its calculation.
function getLowestScoreCell() {
lowest = 0;
for(let i =0; i < openSet.length; i++) {
if(openSet[i].getF() < openSet[lowest].getF()) {
lowest = i;
}
}
return lowest;
}
Last edit: 2022-12-19