Skip to content

Commit

Permalink
Reduced duplication of code in the pathfinding files
Browse files Browse the repository at this point in the history
  • Loading branch information
tobinatore committed Oct 14, 2020
1 parent 31092f6 commit 0d29c03
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 211 deletions.
85 changes: 3 additions & 82 deletions assets/js/Pathfinding/astar_pf.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class AStar {
*/
async run(grid, start, end) {
// reset the grid so previous runs don't affect this one
this.resetGrid(grid);
resetGrid(grid);
// initialize the list containing the unvisited nodes and the
// starting point
var openSet = [];
Expand Down Expand Up @@ -39,7 +39,7 @@ class AStar {
break;
}

var nbs = this.getNeighbours(grid, curr);
var nbs = getNeighbours(grid, curr);

//examine every neighbour of the current node
for (const nb in nbs) {
Expand Down Expand Up @@ -91,62 +91,6 @@ class AStar {
return manhDist;
}

/**
* Resets the grid and every node to their initial state.
* @param {Object[][]} grid - 2d array of objects representing the grid
*/
resetGrid(grid) {
for (let y = 0; y < grid.length; y++) {
for (let x = 0; x < grid[y].length; x++) {
// reset distances, fScores, predecessors and visited status of every node
grid[y][x].dist = Infinity;
grid[y][x].fScore = Infinity;
grid[y][x].predecessor = undefined;
grid[y][x].visited = false;

// color cell white if it's a floor tile or grey if it's a weight
if (grid[y][x].type != "wall" && grid[y][x].type != "weight") {
d3.select("#node-" + y + "-" + x).attr("fill", "#FFF");
} else if (grid[y][x].type == "weight") {
d3.select("#node-" + y + "-" + x).attr("fill", "#B0B0B0");
}
}
}
}

/**
* Gets all nodes bordering the current node.
* @param {Object[][]} grid - 2d array of nodes
* @param {Object} v - The current node
* @returns {Object[]} - A list of nodes adjacent to the current node
*/
getNeighbours(grid, v) {
var nbs = [];

if (v.col - 1 >= 0 && grid[v.row][v.col - 1]) {
if (grid[v.row][v.col - 1].type != "wall")
// push left neighbour
nbs.push(grid[v.row][v.col - 1]);
}
if (v.col + 1 < grid[0].length && grid[v.row][v.col + 1]) {
if (grid[v.row][v.col + 1].type != "wall")
// push right neighbour
nbs.push(grid[v.row][v.col + 1]);
}
if (v.row - 1 >= 0 && grid[v.row - 1][v.col]) {
if (grid[v.row - 1][v.col].type != "wall")
// push upper neighbour
nbs.push(grid[v.row - 1][v.col]);
}
if (v.row + 1 < grid.length && grid[v.row + 1][v.col]) {
if (grid[v.row + 1][v.col].type != "wall")
// push lower neighbour
nbs.push(grid[v.row + 1][v.col]);
}

return nbs;
}

/**
* Finds the node with the lowest fScore, removes it from the list
* and returns it.
Expand Down Expand Up @@ -199,29 +143,6 @@ class AStar {

list.unshift(v);
// animate the stick figure
this.makeHimRun(list);
}

/**
* Animates the stick figure to move from start to target.
* @param {Object[]} list - List of nodes in the path
*/
async makeHimRun(list) {
// loop over the list and adjust the position of the
// stick figure
for (let i in list) {
d3.select("#start")
.transition()
.duration(50)
.attr("x", list[i].x)
.attr("y", list[i].y);
await timeout(50);
}

await timeout(200);
// teleport the stick figure back to the starting point
var x = gridData[startPos.y][startPos.x].x;
var y = gridData[startPos.y][startPos.x].y;
d3.select("#start").attr("x", x).attr("y", y);
makeHimRun(list);
}
}
59 changes: 2 additions & 57 deletions assets/js/Pathfinding/bfs_pf.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class BFS {
return;
}

var neighbours = this.getNeighbours(grid, v);
var neighbours = getNeighbours(grid, v);

// examine every neighbour of the current cell
for (const n in neighbours) {
Expand Down Expand Up @@ -89,39 +89,6 @@ class BFS {
}
}

/**
* Gets all nodes bordering the current node.
* @param {Object[][]} grid - 2d array of nodes
* @param {Object} v - The current node
* @returns {Object[]} - A list of nodes adjacent to v
*/
getNeighbours(grid, v) {
var nbs = [];

if (v.col - 1 >= 0 && grid[v.row][v.col - 1]) {
if (grid[v.row][v.col - 1].type != "wall")
// push left neighbour
nbs.push(grid[v.row][v.col - 1]);
}
if (v.col + 1 < grid[0].length && grid[v.row][v.col + 1]) {
if (grid[v.row][v.col + 1].type != "wall")
// push right neighbour
nbs.push(grid[v.row][v.col + 1]);
}
if (v.row - 1 >= 0 && grid[v.row - 1][v.col]) {
if (grid[v.row - 1][v.col].type != "wall")
// push upper neighbour
nbs.push(grid[v.row - 1][v.col]);
}
if (v.row + 1 < grid.length && grid[v.row + 1][v.col]) {
if (grid[v.row + 1][v.col].type != "wall")
// push lower neighbour
nbs.push(grid[v.row + 1][v.col]);
}

return nbs;
}

/**
* Finds the node with the lowest total distance, removes it from the list
* and returns it.
Expand Down Expand Up @@ -162,28 +129,6 @@ class BFS {
}
list.unshift(v);
// animate the stick figure
this.makeHimRun(list);
}

/**
* Animates the stick figure to move from start to target.
* @param {Object[]} list - List of nodes in the path
*/
async makeHimRun(list) {
// loop over the list and adjust the position of the
// stick figure
for (let i in list) {
d3.select("#start")
.transition()
.duration(50)
.attr("x", list[i].x)
.attr("y", list[i].y);
await timeout(50);
}
await timeout(200);
// teleport it back to the starting point
var x = gridData[startPos.y][startPos.x].x;
var y = gridData[startPos.y][startPos.x].y;
d3.select("#start").attr("x", x).attr("y", y);
makeHimRun(list);
}
}
49 changes: 2 additions & 47 deletions assets/js/Pathfinding/dfs_pf.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,6 @@
class DFS {
constructor() {}

/**
* Resets the grid and every node.
* @param {Object[][]} grid - 2d array of objects representing the grid
*/
resetGrid(grid) {
for (let y = 0; y < grid.length; y++) {
for (let x = 0; x < grid[y].length; x++) {
// reset distances, fScores, predecessors and visited status of every node
grid[y][x].dist = Infinity;
grid[y][x].fScore = Infinity;
grid[y][x].predecessor = undefined;
grid[y][x].visited = false;

// color cell white if it's a floor tile or grey if it's a weight
if (grid[y][x].type != "wall" && grid[y][x].type != "weight") {
d3.select("#node-" + y + "-" + x).attr("fill", "#FFF");
} else if (grid[y][x].type == "weight") {
d3.select("#node-" + y + "-" + x).attr("fill", "#B0B0B0");
}
}
}
}

/**
* Run the algorithm with the provided values.
* @param {Object[][]} grid - A 2d array representing the grid the algorithm runs on
Expand All @@ -33,7 +10,7 @@ class DFS {
*/
async run(grid, start, end) {
// resetting the grid before every run
this.resetGrid(grid);
resetGrid(grid);
var node = grid[start.y][start.x];
// calling the recursive dfs function and awaiting
// the last node of the path
Expand Down Expand Up @@ -142,28 +119,6 @@ class DFS {
}
list.unshift(v);
// animate the stick figure
this.makeHimRun(list);
}

/**
* Animates the stick figure to move from start to target.
* @param {Object[]} list - List of nodes in the path
*/
async makeHimRun(list) {
// loop over the path list
// and adjust the position of the stick figure
for (let i in list) {
d3.select("#start")
.transition()
.duration(50)
.attr("x", list[i].x)
.attr("y", list[i].y);
await timeout(50);
}
await timeout(200);
// teleport the stick figure back to the start
var x = gridData[startPos.y][startPos.x].x;
var y = gridData[startPos.y][startPos.x].y;
d3.select("#start").attr("x", x).attr("y", y);
makeHimRun(list);
}
}
27 changes: 2 additions & 25 deletions assets/js/Pathfinding/dijkstra_pf.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class Dijkstras {
}

// get adjacent nodes
var neighbours = this.getNeighbours(grid, v);
var neighbours = getNeighbours(grid, v);

for (const n in neighbours) {
// get index of neighbour in queue
Expand Down Expand Up @@ -173,29 +173,6 @@ class Dijkstras {
// add source node to the path list
// and animate the stick figure
list.unshift(v);
this.makeHimRun(list);
}

/**
* Animates the stick figure to move from start to target.
* @param {Object[]} list - List of nodes in the path
*/
async makeHimRun(list) {
// update x and y coordinates of the stick figure
// to the coordinates of every node in the path
for (let i in list) {
d3.select("#start")
.transition()
.duration(50)
.attr("x", list[i].x)
.attr("y", list[i].y);
await timeout(50);
}

// teleport stick figure back to the source node
await timeout(200);
var x = gridData[startPos.y][startPos.x].x;
var y = gridData[startPos.y][startPos.x].y;
d3.select("#start").attr("x", x).attr("y", y);
makeHimRun(list);
}
}
79 changes: 79 additions & 0 deletions assets/js/Pathfinding/pf_helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/** @module PathfindingHelperFunctions */

/**
* Gets all nodes bordering the current node.
* @param {Object[][]} grid - 2d array of nodes
* @param {Object} v - The current node
* @returns {Object[]} - A list of nodes adjacent to v
*/
function getNeighbours(grid, v) {
var nbs = [];

if (v.col - 1 >= 0 && grid[v.row][v.col - 1]) {
if (grid[v.row][v.col - 1].type != "wall")
// push left neighbour
nbs.push(grid[v.row][v.col - 1]);
}
if (v.col + 1 < grid[0].length && grid[v.row][v.col + 1]) {
if (grid[v.row][v.col + 1].type != "wall")
// push right neighbour
nbs.push(grid[v.row][v.col + 1]);
}
if (v.row - 1 >= 0 && grid[v.row - 1][v.col]) {
if (grid[v.row - 1][v.col].type != "wall")
// push upper neighbour
nbs.push(grid[v.row - 1][v.col]);
}
if (v.row + 1 < grid.length && grid[v.row + 1][v.col]) {
if (grid[v.row + 1][v.col].type != "wall")
// push lower neighbour
nbs.push(grid[v.row + 1][v.col]);
}

return nbs;
}

/**
* Resets the grid and every node to their initial state.
* @param {Object[][]} grid - 2d array of objects representing the grid
*/
function resetGrid(grid) {
for (let y = 0; y < grid.length; y++) {
for (let x = 0; x < grid[y].length; x++) {
// reset distances, fScores, predecessors and visited status of every node
grid[y][x].dist = Infinity;
grid[y][x].fScore = Infinity;
grid[y][x].predecessor = undefined;
grid[y][x].visited = false;

// color cell white if it's a floor tile or grey if it's a weight
if (grid[y][x].type != "wall" && grid[y][x].type != "weight") {
d3.select("#node-" + y + "-" + x).attr("fill", "#FFF");
} else if (grid[y][x].type == "weight") {
d3.select("#node-" + y + "-" + x).attr("fill", "#B0B0B0");
}
}
}
}

/**
* Animates the stick figure to move from start to target.
* @param {Object[]} list - List of nodes in the path
*/
async function makeHimRun(list) {
// loop over the path list
// and adjust the position of the stick figure
for (let i in list) {
d3.select("#start")
.transition()
.duration(50)
.attr("x", list[i].x)
.attr("y", list[i].y);
await timeout(50);
}
await timeout(200);
// teleport the stick figure back to the start
var x = gridData[startPos.y][startPos.x].x;
var y = gridData[startPos.y][startPos.x].y;
d3.select("#start").attr("x", x).attr("y", y);
}
1 change: 1 addition & 0 deletions pathfinding.html
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@ <h4>Useful Links</h4>
<script src="assets/js/Maze/growing_tree.js"></script>
<script src="assets/js/Maze/binary_tree_generator.js"></script>
<script src="assets/js/Maze/sidewinder.js"></script>
<script src="assets/js/Pathfinding/pf_helpers.js"></script>

<!-- Template Main JS File -->
<script src="assets/js/main.js"></script>
Expand Down

0 comments on commit 0d29c03

Please sign in to comment.