Skip to content

Commit

Permalink
make the dijkstra work
Browse files Browse the repository at this point in the history
  • Loading branch information
GunawanAhmad committed Mar 11, 2021
1 parent 42ce09a commit ee35c78
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 17 deletions.
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"vuex": "^3.4.0"
},
"devDependencies": {
"@fortawesome/fontawesome-free": "^5.15.2",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
Expand Down
59 changes: 59 additions & 0 deletions src/algorithms/dijkstra.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
export function dijkstra(grid, startNode, finishNode) {
startNode.distance = 0;
const visistedNodesInOrder = [];
const unvisitedNodes = getAllNodes(grid);
console.log(startNode);
while (unvisitedNodes.length != 0) {
sortNodesByDistance(unvisitedNodes);
const currNode = unvisitedNodes.shift();
if (currNode.distance === Infinity) {
return visistedNodesInOrder;
}
currNode.isVisited = true;
visistedNodesInOrder.push(currNode);
if (currNode === finishNode) return visistedNodesInOrder;
updateUnvisitedNeighbours(currNode, grid);
}
}

function sortNodesByDistance(unvisitedNodes) {
unvisitedNodes.sort((nodeA, nodeB) => nodeA.distance - nodeB.distance);
}

function updateUnvisitedNeighbours(node, grid) {
const unvisitedNeighbours = getUnvisistedNeighbours(node, grid);
for (let neighbour of unvisitedNeighbours) {
neighbour.distance = node.distance + 1;
neighbour.previousNode = node;
}
}

function getUnvisistedNeighbours(node, grid) {
const neighbours = [];
const { col, row } = node;
if (row > 0) neighbours.push(grid[row - 1][col]);
if (col > 0) neighbours.push(grid[row][col - 1]);
if (row < grid.length - 1) neighbours.push(grid[row + 1][col]);
if (col < grid[0].length - 1) neighbours.push(grid[row][col + 1]);
return neighbours.filter((node) => !node.isVisited);
}

function getAllNodes(grid) {
const nodes = [];
for (let row of grid) {
for (let col of row) {
nodes.push(col);
}
}
return nodes;
}

export function findTheShortestPath(finishNode) {
const nodesInShortesPathOrder = [];
let currNode = finishNode;
while (currNode !== null) {
nodesInShortesPathOrder.unshift(currNode);
currNode = currNode.previousNode;
}
return nodesInShortesPathOrder;
}
107 changes: 103 additions & 4 deletions src/components/Node.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@
node.isFinish ? 'finish-node' : '',
node.isStart ? 'start-node' : '',
]"
:id="`node-${node.row}-${node.col}`"
@click="test"
:draggable="node.isStart ? true : false"
></div>
</template>

<script>
export default {
props: ["node"],
methods: {
test(e) {
console.log(e.target);
},
},
};
</script>

Expand All @@ -22,11 +30,102 @@ export default {
display: inline-block;
}
.finish-node {
background: red;
.node.finish-node {
background: transparent;
height: 25px;
width: 25px;
outline: 1px solid rgb(192, 191, 191);
display: inline-block;
position: relative;
}
.node.start-node {
position: relative;
background: transparent;
height: 25px;
width: 25px;
outline: 1px solid rgb(192, 191, 191);
display: inline-block;
}
.node.start-node::before {
/* display: none; */
font-family: "Font Awesome 5 Free";
font-weight: 900;
font-size: 1.5rem;
content: "\f3c5";
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: black;
}
.start-node {
background: green;
.node.finish-node::before {
/* display: none; */
font-family: "Font Awesome 5 Free";
font-weight: 900;
font-size: 1.5rem;
content: "\f140";
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: black;
}
.visited {
background: gray;
}
.short {
animation-name: shortestPath;
animation-duration: 1.5s;
animation-timing-function: ease-out;
animation-direction: alternate;
animation-iteration-count: 1;
animation-fill-mode: forwards;
opacity: 0;
}
@keyframes visitedAnimation {
/* 0% {
opacity: 0.2;
background-color: gray;
border-radius: 100%;
}
50% {
opacity: 0.5;
background-color: gray;
}
75% {
opacity: 0.7;
background-color: gray;
}
100% {
opacity: 1;
background-color: gray; */
/* } */
}
@keyframes shortestPath {
0% {
opacity: 0.3;
background-color: rgb(255, 254, 106);
}
50% {
opacity: 0.7;
background-color: rgb(255, 254, 106);
}
100% {
opacity: 1;
background-color: rgb(255, 254, 106);
}
}
</style>
16 changes: 9 additions & 7 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import "@fortawesome/fontawesome-free/css/all.css";
import "@fortawesome/fontawesome-free/js/all.js";

Vue.config.productionTip = false
Vue.config.productionTip = false;

new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
render: (h) => h(App),
}).$mount("#app");
55 changes: 49 additions & 6 deletions src/views/PathfindingVisualizer.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<div class="container">
<button @click="runDijkstraAlgo" class="btn">RUN</button>
<div class="grid" v-for="(row, rowIndex) in grid" :key="rowIndex">
<Node v-for="(col, colIndex) in row" :key="colIndex" :node="col"></Node>
</div>
Expand All @@ -8,23 +9,24 @@

<script>
import Node from "../components/Node.vue";
import { dijkstra, findTheShortestPath } from "../algorithms/dijkstra";
export default {
components: { Node },
data() {
return {
START_NODE_ROW: 10,
START_NODE_COL: 10,
FINISH_NODE_ROW: 15,
FINISH_NODE_COL: 15,
START_NODE_ROW: 12,
START_NODE_COL: 13,
FINISH_NODE_ROW: 11,
FINISH_NODE_COL: 30,
grid: [],
};
},
methods: {
getInitialGrid() {
const grid = [];
for (let row = 0; row < 30; row++) {
for (let row = 0; row < 20; row++) {
const currentRow = [];
for (let col = 0; col < 30; col++) {
for (let col = 0; col < 40; col++) {
currentRow.push(this.createNode(col, row));
}
grid.push(currentRow);
Expand All @@ -40,8 +42,43 @@ export default {
isVisited: false,
isWall: false,
previousNode: null,
distance: Infinity,
};
},
runDijkstraAlgo() {
const startNode = this.grid[this.START_NODE_ROW][this.START_NODE_COL];
const finishNode = this.grid[this.FINISH_NODE_ROW][this.FINISH_NODE_COL];
const visitedNodeInOrder = dijkstra(this.grid, startNode, finishNode);
const shortestPathNodesInOrder = findTheShortestPath(finishNode);
this.visualizeDijkstra(visitedNodeInOrder, shortestPathNodesInOrder);
},
visualizeDijkstra(visitedNodeInOrder, shortestPathNodesInOrder) {
for (let i = 0; i <= visitedNodeInOrder.length; i++) {
if (i === visitedNodeInOrder.length) {
setTimeout(() => {
console.log("short");
this.visualizeShortestPath(shortestPathNodesInOrder);
}, 20 * i);
}
setTimeout(() => {
const node = visitedNodeInOrder[i];
document
.getElementById(`node-${node.row}-${node.col}`)
.classList.add("visited");
}, 20 * i);
}
},
visualizeShortestPath(shortestPathNodesInOrder) {
for (let i = 0; i < shortestPathNodesInOrder.length; i++) {
setTimeout(() => {
const node = shortestPathNodesInOrder[i];
document
.getElementById(`node-${node.row}-${node.col}`)
.classList.add("short");
}, 20 * i);
}
},
},
mounted() {
this.grid = this.getInitialGrid();
Expand All @@ -64,4 +101,10 @@ export default {
align-items: center;
margin-top: 200px;
}
.btn {
position: absolute;
top: 2rem;
left: 50%;
}
</style>

0 comments on commit ee35c78

Please sign in to comment.