Created
May 31, 2018 20:08
-
-
Save jvanmelckebeke/cbc2bd06af59aeef35b979460922e07e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = { | |
PathFinder: (grid, gridHeight, gridWidth) => { | |
/* grid; | |
gridHeight; | |
gridWidth; | |
startTile; | |
endTile; | |
/!** Array of the already checked tiles. *!/ | |
closedList = []; | |
openList = [];*/ | |
console.log('activated'); | |
let openList = []; | |
let closedList = []; | |
let startTile, endTile; | |
function searchPath(start, end) { | |
startTile = start; | |
console.log(startTile); | |
endTile = end; | |
/** Path validation */ | |
if (grid[start.y][start.x] === 0) { | |
console.log('The start tile in not walkable, choose different tile than', start, grid[start.y][start.x]); | |
return []; | |
} | |
if (grid[end.y][end.x] === 0) { | |
console.log('The end tile in not walkable, choose different tile than', end); | |
return []; | |
} | |
/** Start A* Algorithm */ | |
/** Add the starting tile to the openList */ | |
console.log('start', start, openList.push(start)); //expected output: start {x: 10, y: 9} 1 || real output: the same | |
console.log('openlist = ', openList); // expected output: [{x: 10, y: 9}] || real output: [] | |
let currentTile; | |
while (openList.length > 0) { | |
console.log('openlist = ', openList); | |
//current node = node for open list with the lowest cost. | |
currentTile = getTileWithLowestTotal(openList); | |
//if the currentTile is the endTile, then we can stop searching | |
if (currentTile.x === end.x && currentTile.y === end.y) { | |
return shortestPath(); | |
} | |
else { | |
//move the current tile to the closed list and remove it from the open list. | |
openList.splice(openList.indexOf(currentTile) - 1, 1); | |
// openList.filter(value => value.x !== currentTile.x && value.y !== currentTile.y); | |
closedList.push(currentTile); | |
// //Get all adjacent Tiles | |
let adjacentTiles = getAdjacentTiles(currentTile); | |
for (let adjacentTile of adjacentTiles) { | |
//Get tile is not in the open list | |
if (!openList.contains(adjacentTile)) { | |
//Get tile is not in the closed list | |
if (!closedList.contains(adjacentTile)) { | |
//move it to the open list and calculate cost | |
openList.push(adjacentTile); | |
//calculate the cost | |
adjacentTile.cost = currentTile.cost + 1; | |
//calculate the manhattan distance | |
adjacentTile.heuristic = manhattanDistance(adjacentTile); | |
// calculate the total amount | |
adjacentTile.total = adjacentTile.cost + adjacentTile.heuristic; | |
} | |
} | |
} | |
} | |
} | |
console.log('boo'); | |
} | |
function getTileWithLowestTotal(openList) { | |
let tileWithLowestTotal = {}; | |
let lowestTotal = 999999999; | |
/** Search open tiles and get the tile with the lowest total cost */ | |
for (let openTile of openList) { | |
if (openTile.total <= lowestTotal) { | |
//clone lowestTotal | |
lowestTotal = openTile.total; | |
tileWithLowestTotal = openTile; | |
} | |
} | |
console.log('tilewithlowesttotal', tileWithLowestTotal); | |
return tileWithLowestTotal; | |
} | |
function getAdjacentTiles(current) { | |
let adjacentTiles = []; | |
let adjacentTile = {}; | |
//Tile to left | |
if (current.x - 1 >= 0) { | |
adjacentTile = grid[current.x - 1][current.y]; | |
if (adjacentTile === 1) { | |
adjacentTiles.push({x: current.x, y: current.y, cost: 1}); | |
} | |
} | |
//Tile to right | |
if (current.x + 1 < gridWidth) { | |
adjacentTile = grid[current.x + 1][current.y]; | |
if (adjacentTile === 1) { | |
adjacentTiles.push({x: current.x, y: current.y, cost: 1}); | |
} | |
} | |
//Tile to Under | |
if (current.y + 1 < gridHeight) { | |
adjacentTile = grid[current.x][current.y + 1]; | |
if (adjacentTile === 1) { | |
adjacentTiles.push({x: current.x, y: current.y, cost: 1}); | |
} | |
} | |
//Tile to Above | |
if (current.y - 1 >= 0) { | |
adjacentTile = grid[current.x][current.y - 1]; | |
if (adjacentTile === 1) { | |
adjacentTiles.push({x: current.x, y: current.y, cost: 1}); | |
} | |
} | |
return adjacentTiles; | |
} | |
/** Calculate the manhattan distance */ | |
function manhattanDistance(adjacentTile) { | |
return Math.abs((endTile.x - adjacentTile.x) + (endTile.y - adjacentTile.y)); | |
} | |
function shortestPath() { | |
let startFound = false; | |
let currentTile = endTile; | |
let pathTiles = []; | |
//includes the end tile in the path | |
pathTiles.push(endTile); | |
while (!startFound) { | |
let adjacentTiles = getAdjacentTiles(currentTile); | |
//check to see what newest current tile. | |
for (let adjacentTile of adjacentTiles) { | |
//check if it is the start tile | |
if (adjacentTile.x === startTile.x && adjacentTile.y === startTile.y) { | |
return pathTiles; | |
} | |
//it has to be inside the closedList or openList | |
if (closedList.contains(adjacentTile) || openList.contains(adjacentTile)) { | |
if (adjacentTile.cost <= currentTile.cost && adjacentTile.cost > 0) { | |
//change the current tile. | |
currentTile = adjacentTile; | |
//Add this adjacentTile to the path list | |
pathTiles.push(adjacentTile); | |
//highlight way with yellow balls | |
break; | |
} | |
} | |
} | |
} | |
} | |
return { | |
searchPath: (start, end) => searchPath(start, end), | |
}; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment