Skip to content

Commit

Permalink
added parallel visualization capability
Browse files Browse the repository at this point in the history
  • Loading branch information
kartik-at-sopra committed Jul 13, 2024
1 parent 94f97db commit 8f2fba1
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 59 deletions.
21 changes: 13 additions & 8 deletions A_star.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export default function visualizeAStar(grid, startNode, finishNode) {
document.querySelector("#start-visualization").classList.add("disable-button")
const visitedNodesInOrder = AStar(startNode, finishNode, grid)
const shortestPathInOrder = getShortestPathInOrder(finishNode)
animateAlgo(visitedNodesInOrder, shortestPathInOrder)
Expand All @@ -22,7 +21,7 @@ function AStar(startNode, finishNode, grid) {
if (!!closestNode.isWall) continue
if (closestNode.gScore === Infinity) return visitedNodesInOrder

closestNode.isVisited = true
closestNode.isVisited.astar = true
visitedNodesInOrder.push(closestNode)
if (closestNode === finishNode) return visitedNodesInOrder
updateNeighborNodes(grid, finishNode, closestNode)
Expand All @@ -42,7 +41,7 @@ function animateAlgo(visitedNodesInOrder, shortestPathInOrder) {
if (visitedNodesInOrder[i] === undefined) console.log(i)
setTimeout(() => {
const node = visitedNodesInOrder[i]
document.getElementById(node.id).classList.add("visited")
document.getElementById(node.id).classList.add("visited-astar")
}, 10 * i);
}
}
Expand All @@ -54,8 +53,14 @@ function animateShortestPath(shortestPathInOrder) {
}
for (let i = 1; i < shortestPathInOrder.length - 1; i++) {
setTimeout(() => {
if(i === 1) {
document.querySelector('.start').classList.add('animate')
}
else if(i === shortestPathInOrder.length-2) {
document.querySelector('.finish').classList.add('animate')
}
const node = shortestPathInOrder[i]
document.getElementById(node.id).classList.add("path")
document.getElementById(node.id).classList.add("path-astar")
}, 10 * 5 * i);
}
}
Expand All @@ -69,27 +74,27 @@ function updateNeighborNodes(grid, finishNode, node) {
neighbors.forEach(neighbor => {
neighbor.gScore = node.gScore + 1
neighbor.hScore = Math.abs(neighbor.row - finishNode.row) + Math.abs(neighbor.col - finishNode.col)
neighbor.prevNode = node
neighbor.prevNode.astar = node
})
}

function getNeighbors(grid, node) {
const neighbors = []
const { row, col } = node
if (row > 0) neighbors.push(grid[row - 1][col])
if (col < grid.length - 1) neighbors.push(grid[row][col + 1])
if (col < grid[0].length - 1) neighbors.push(grid[row][col + 1])
if (row < grid.length - 1) neighbors.push(grid[row + 1][col])
if (col > 0) neighbors.push(grid[row][col - 1])

return neighbors.filter(neighbor => !neighbor.isVisited)
return neighbors.filter(neighbor => !neighbor.isVisited.astar)
}

function getShortestPathInOrder(finishNode) {
const shortestPathInOrder = []
let currentNode = finishNode
while (currentNode !== null) {
shortestPathInOrder.unshift(currentNode)
currentNode = currentNode.prevNode
currentNode = currentNode.prevNode.astar
}
return shortestPathInOrder
}
56 changes: 39 additions & 17 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import visualizeDijkstra from "./dijkstra.js"
import visualizeAStar from "./A_star.js"

const mazeSize = 30
const ratio = 2.5
const mazeCols = 70
const mazeRows = mazeCols / ratio
const grid = []
let isPressed = false
let isStarted = false
let dijDone = false
let astarDone = false
let startNode = []
let finishNode = []
let myStorage = window.sessionStorage
if(myStorage.getItem("algo") === null) myStorage.setItem("algo", "Dijkstra")
let algo = myStorage.getItem("algo")
document.querySelector("#select-algo").value = algo
console.log(algo)

main()

Expand All @@ -23,28 +26,33 @@ function main() {
}

function initializeGrid() {

for (let row = 0; row < mazeSize; row++) {
for (let row = 0; row < mazeRows; row++) {
const currentRow = []
for (let col = 0; col < mazeSize; col++) {
for (let col = 0; col < mazeCols; col++) {
const currentNode = {
row,
col,
id: row + "-" + col,
isStart: false,
isFinish: false,
isVisited: false,
isVisited: {
dij: false,
astar: false
},
isWall: false,
distance: Infinity,
prevNode: null
prevNode: {
dij: null,
astar: null
}
}
currentRow.push(currentNode)
}
grid.push(currentRow)
}

for (let i = 0; i < mazeSize; i++) {
for (let j = 0; j < mazeSize; j++) {
for (let i = 0; i < mazeRows; i++) {
for (let j = 0; j < mazeCols; j++) {
let div = document.createElement("div")
div.classList.add("node")
div.id = i + "-" + j
Expand All @@ -55,15 +63,30 @@ function initializeGrid() {


function setupVisualizerBTN() {
document.querySelector("#start-visualization").addEventListener("click", startVis)
if((algo === "Dijkstra" && !dijDone) || (algo === "A Star" && !astarDone)) {
document.querySelector("#start-visualization").addEventListener("click", startVis)
document.querySelector("#start-visualization").classList.remove("disable-button")
isStarted = false
}
}

function startVis() {
if (!Array.isArray(startNode) && !Array.isArray(finishNode)) {
isStarted = true
if(algo === "Dijkstra") visualizeDijkstra(grid, startNode, finishNode)
else visualizeAStar(grid, startNode, finishNode)
document.querySelector("#start-visualization").removeEventListener("click", startVis)
if(algo === "Dijkstra" && !dijDone) {
visualizeDijkstra(grid, startNode, finishNode)
dijDone = true
}
else if(algo === "A Star" && !astarDone) {
visualizeAStar(grid, startNode, finishNode)
astarDone = true
}
if((dijDone && astarDone) || (algo === "Dijkstra" && dijDone) || (algo === "A Star" && astarDone)) {
document.querySelector("#start-visualization").removeEventListener("click", startVis)
document.querySelector("#start-visualization").classList.add("disable-button")
isStarted = true
}
else isStarted = false
}
else alert("ADD START AND END NODES")
}
Expand All @@ -78,10 +101,9 @@ document.querySelectorAll(".dropdown-element").forEach((element) => {
element.addEventListener("click", e => {
algo = e.target.innerText
myStorage.setItem("algo", algo)
document.querySelector("#select-algo").value = algo
document.querySelector(".dropdown-content").classList.toggle("show")


document.querySelector("#select-algo").value = algo
document.querySelector(".dropdown-content").classList.toggle("show")
setupVisualizerBTN()
})
})

Expand Down
22 changes: 13 additions & 9 deletions dijkstra.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export default function visualizeDijkstra(grid, startNode, finishNode) {
document.querySelector("#start-visualization").classList.add("disable-button")
const visitedNodesInOrder = dijkstra(startNode, finishNode, grid)
const shortestPathInOrder = getShortestPathInOrder(finishNode)
animateAlgo(visitedNodesInOrder, shortestPathInOrder)
Expand All @@ -15,7 +14,7 @@ function dijkstra(startNode, finishNode, grid) {
if (!!closestNode.isWall) continue
if (closestNode.distance === Infinity) return visitedNodesInOrder

closestNode.isVisited = true
closestNode.isVisited.dij = true
visitedNodesInOrder.push(closestNode)
if (closestNode === finishNode) return visitedNodesInOrder
updateNeighborNodes(grid, closestNode)
Expand All @@ -36,7 +35,7 @@ function animateAlgo(visitedNodesInOrder, shortestPathInOrder) {
if (visitedNodesInOrder[i] === undefined) console.log(i)
setTimeout(() => {
const node = visitedNodesInOrder[i]
document.getElementById(node.id).classList.add("visited")
document.getElementById(node.id).classList.add("visited-dij")
}, 10 * i);
}
}
Expand All @@ -48,8 +47,14 @@ function animateShortestPath(shortestPathInOrder) {
}
for (let i = 1; i < shortestPathInOrder.length - 1; i++) {
setTimeout(() => {
if(i === 1) {
document.querySelector('.start').classList.add('animate')
}
else if(i === shortestPathInOrder.length-2) {
document.querySelector('.finish').classList.add('animate')
}
const node = shortestPathInOrder[i]
document.getElementById(node.id).classList.add("path")
document.getElementById(node.id).classList.add("path-dij")
}, 10 * 5 * i);
}
}
Expand All @@ -62,27 +67,26 @@ function updateNeighborNodes(grid, node) {
const neighbors = getNeighbors(grid, node)
neighbors.forEach(neighbor => {
neighbor.distance = node.distance + 1
neighbor.prevNode = node
neighbor.prevNode.dij = node
})
}

function getNeighbors(grid, node) {
const neighbors = []
const { row, col } = node
if (row > 0) neighbors.push(grid[row - 1][col])
if (col < grid.length - 1) neighbors.push(grid[row][col + 1])
if (col < grid[0].length - 1) neighbors.push(grid[row][col + 1])
if (row < grid.length - 1) neighbors.push(grid[row + 1][col])
if (col > 0) neighbors.push(grid[row][col - 1])

return neighbors.filter(neighbor => !neighbor.isVisited)
return neighbors.filter(neighbor => !neighbor.isVisited.dij)
}

function getShortestPathInOrder(finishNode) {
const shortestPathInOrder = []
let currentNode = finishNode
while (currentNode !== null) {
shortestPathInOrder.unshift(currentNode)
currentNode = currentNode.prevNode
currentNode = currentNode.prevNode.dij
}
return shortestPathInOrder
}
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pathfinder visualizer</title>
<link rel="stylesheet" href="style.css">
<script type="module" defer="" src="app.js"></script>
<script type="module" defer src="app.js"></script>
</head>

<body>
Expand Down
Loading

0 comments on commit 8f2fba1

Please sign in to comment.