Skip to content

Commit 3a9c1c9

Browse files
committed
Refactor algorithm triggers to single useEffect hook
1 parent e9bca32 commit 3a9c1c9

File tree

3 files changed

+126
-100
lines changed

3 files changed

+126
-100
lines changed

src/components/ControlPanel.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// ControlPanel.tsx
2+
import React from 'react';
3+
4+
const ControlPanel = ({
5+
BFSSolver,
6+
DFSSolver,
7+
DijkstraSolver,
8+
PrimsMazeSolver,
9+
DFSMazeSolver,
10+
generateTable,
11+
clearLatestRun
12+
}: {
13+
BFSSolver: () => void,
14+
DFSSolver: () => void,
15+
DijkstraSolver: () => void,
16+
PrimsMazeSolver: () => void,
17+
DFSMazeSolver: () => void,
18+
generateTable: () => void,
19+
clearLatestRun: () => void
20+
}) => {
21+
22+
function runAlgorithm(setAlgorithm: () => void): void {
23+
clearLatestRun();
24+
setAlgorithm();
25+
}
26+
27+
return (
28+
<div>
29+
<button onClick={() => runAlgorithm(BFSSolver)} style={{ backgroundColor: 'white', color: 'black' }}>Run BFS Visualisation</button>
30+
<button onClick={() => runAlgorithm(DFSSolver)} style={{ backgroundColor: 'white', color: 'black' }}>Run DFS Visualisation</button>
31+
<button onClick={() => runAlgorithm(DijkstraSolver)} style={{ backgroundColor: 'white', color: 'black' }}>Run Dijkstra Visualisation</button>
32+
<button onClick={() => runAlgorithm(PrimsMazeSolver)} style={{ backgroundColor: 'white', color: 'black' }}>Generate Prims Maze</button>
33+
<button onClick={() => runAlgorithm(DFSMazeSolver)} style={{ backgroundColor: 'white', color: 'black' }}>Generate DFS Maze</button>
34+
<button onClick={generateTable} style={{ backgroundColor: 'white', color: 'black' }}>Reset Board</button>
35+
<button onClick={clearLatestRun} style={{ backgroundColor: 'white', color: 'black' }}>Clear Latest Run</button>
36+
</div>
37+
);
38+
};
39+
40+
export default ControlPanel;

src/pages/PathfindingVisualiser.tsx

Lines changed: 17 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -5,63 +5,19 @@ import { HiChevronDoubleRight } from "react-icons/hi2";
55
import { HiOutlineFlag } from "react-icons/hi";
66
import { Cell } from '../algorithms/utils/PathfindingUtils';
77
import MazeGrid from '../components/MazeGrid.tsx';
8-
import { BreadthFirstSearch } from '../algorithms/pathfinding/BreadthFirstSearch.ts';
9-
import { Dijkstra } from '../algorithms/pathfinding/Dijkstra.ts';
10-
import { DepthFirstSearch } from '../algorithms/pathfinding/DepthFirstSearch.ts';
11-
import { primsMazeGeneration } from '../algorithms/mazes/PrimsMazeGeneration.ts';
12-
import { dfsMazeGeneration } from '../algorithms/mazes/DFSMazeGeneration.ts';
138
import mazeHooks from '../utils/mazeHooks.ts';
9+
import pathfindingAlgorithmHooks from '../utils/pathfindingAlgorithmHooks.ts';
1410

1511
const PathfindingVisualiser: React.FC = () => {
1612
const { width = 0, height = 0 } = useWindowDimensions();
1713
const [isDrawing, setIsDrawing] = useState<boolean>(false);
1814
const [drawingValue, setDrawingValue] = useState<boolean>(false);
1915
const [isMovingNode, setIsMovingNode] = useState<'start' | 'end' | null>(null);
20-
const [runDijkstra, setRunDijkstra] = useState<boolean>(false);
21-
const [runBFS, setRunBFS] = useState<boolean>(false);
22-
const [runDFS, setRunDFS] = useState<boolean>(false);
23-
const [generatePrimsMaze, setGeneratePrimsMaze] = useState<boolean>(false);
24-
const [generateDFSMaze, setGenerateDFSMaze] = useState<boolean>(false);
2516

2617
useEffect(() => {
2718
generateTable();
2819
}, [width, height]);
2920

30-
useEffect(() => {
31-
if (runDijkstra) {
32-
callDijkstra();
33-
setRunDijkstra(false);
34-
}
35-
}, [runDijkstra]);
36-
37-
useEffect(() => {
38-
if (runBFS) {
39-
callBFS();
40-
setRunBFS(false);
41-
}
42-
}, [runBFS]);
43-
44-
useEffect(() => {
45-
if (runDFS) {
46-
callDFS();
47-
setRunDFS(false);
48-
}
49-
}, [runDFS]);
50-
51-
useEffect(() => {
52-
if (generatePrimsMaze) {
53-
primsMazeRun();
54-
setGeneratePrimsMaze(false);
55-
}
56-
}, [generatePrimsMaze]);
57-
58-
useEffect(() => {
59-
if (generateDFSMaze) {
60-
DFSMazeRun();
61-
setGenerateDFSMaze(false);
62-
}
63-
}, [generateDFSMaze]);
64-
6521
const {
6622
maze,
6723
setMaze,
@@ -74,6 +30,15 @@ const PathfindingVisualiser: React.FC = () => {
7430
populateOptimalPath,
7531
} = mazeHooks(width, height);
7632

33+
const { triggerAlgorithm } = pathfindingAlgorithmHooks({
34+
clearLatestRun,
35+
populateOptimalPath,
36+
maze,
37+
startNode,
38+
endNode,
39+
setMaze,
40+
});
41+
7742
const handleMouseDown = (rowIndex: number, colIndex: number) => {
7843
if (maze[rowIndex][colIndex].start) {
7944
setIsMovingNode('start');
@@ -126,57 +91,9 @@ const PathfindingVisualiser: React.FC = () => {
12691
});
12792
};
12893

129-
async function callBFS(){
130-
const optimalPath = await BreadthFirstSearch(maze, maze[startNode[0]][startNode[1]], maze[endNode[0]][endNode[1]], setMaze);
131-
await populateOptimalPath(optimalPath);
132-
}
133-
134-
async function callDijkstra(){
135-
const optimalPath = await Dijkstra(maze, maze[startNode[0]][startNode[1]], maze[endNode[0]][endNode[1]], setMaze);
136-
await populateOptimalPath(optimalPath);
137-
}
138-
139-
async function callDFS(){
140-
const optimalPath = await DepthFirstSearch(maze, maze[startNode[0]][startNode[1]], maze[endNode[0]][endNode[1]], setMaze);
141-
await populateOptimalPath(optimalPath);
142-
}
143-
144-
function triggerBFS(){
145-
clearAttribute('visited');
146-
clearAttribute('finalPath');
147-
setRunBFS(true);
148-
}
149-
150-
function triggerDijkstra(){
151-
clearAttribute('visited');
152-
clearAttribute('finalPath');
153-
setRunDijkstra(true);
154-
}
155-
156-
function triggerDFS(){
94+
function clearLatestRun(){
15795
clearAttribute('visited');
15896
clearAttribute('finalPath');
159-
setRunDFS(true);
160-
}
161-
162-
function triggerPrimsMaze(){
163-
clearAttribute('visited');
164-
clearAttribute('finalPath');
165-
setGeneratePrimsMaze(true);
166-
}
167-
168-
function triggerDFSMaze(){
169-
clearAttribute('visited');
170-
clearAttribute('finalPath');
171-
setGenerateDFSMaze(true);
172-
}
173-
174-
function primsMazeRun(){
175-
primsMazeGeneration(maze, maze[startNode[0]][startNode[1]], maze[endNode[0]][endNode[1]], setMaze);
176-
}
177-
178-
function DFSMazeRun(){
179-
dfsMazeGeneration(maze, maze[startNode[0]][startNode[1]], maze[endNode[0]][endNode[1]], setMaze);
18097
}
18198

18299
return (
@@ -187,13 +104,13 @@ const PathfindingVisualiser: React.FC = () => {
187104
handleMouseEnter={handleMouseEnter}
188105
handleMouseUp={handleMouseUp}
189106
/>
190-
<button onClick={() => {triggerBFS();}} style={{backgroundColor: 'white', color: 'black'}}>Run BFS Visualisation</button>
191-
<button onClick={() => {triggerDFS();}} style={{backgroundColor: 'white', color: 'black'}}>Run DFS Visualisation</button>
192-
<button onClick={() => {triggerDijkstra();}} style={{backgroundColor: 'white', color: 'black'}}>Run Djikstra Visualisation</button>
193-
<button onClick={() => {triggerPrimsMaze();}} style={{backgroundColor: 'white', color: 'black'}}>Generate Prims Maze</button>
194-
<button onClick={() => {triggerDFSMaze();}} style={{backgroundColor: 'white', color: 'black'}}>Generate DFS Maze</button>
107+
<button onClick={() => triggerAlgorithm('bfs')} style={{backgroundColor: 'white', color: 'black'}}>Run BFS Visualisation</button>
108+
<button onClick={() => triggerAlgorithm('dfs')} style={{backgroundColor: 'white', color: 'black'}}>Run DFS Visualisation</button>
109+
<button onClick={() => triggerAlgorithm('dijkstra')} style={{backgroundColor: 'white', color: 'black'}}>Run Djikstra Visualisation</button>
110+
<button onClick={() => triggerAlgorithm('primsMaze')} style={{backgroundColor: 'white', color: 'black'}}>Generate Prims Maze</button>
111+
<button onClick={() => triggerAlgorithm('dfsMaze')} style={{backgroundColor: 'white', color: 'black'}}>Generate DFS Maze</button>
195112
<button onClick={() => generateTable()} style={{backgroundColor: 'white', color: 'black'}}>Reset Board</button>
196-
<button onClick={() => {clearAttribute('visited'); clearAttribute('finalPath')}} style={{backgroundColor: 'white', color: 'black'}}>Clear Latest Run</button>
113+
<button onClick={() => clearLatestRun()} style={{backgroundColor: 'white', color: 'black'}}>Clear Latest Run</button>
197114
</div>
198115
);
199116
};
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { useState, useEffect } from 'react';
2+
import { Cell } from '../algorithms/utils/PathfindingUtils';
3+
import { BreadthFirstSearch } from '../algorithms/pathfinding/BreadthFirstSearch.ts';
4+
import { Dijkstra } from '../algorithms/pathfinding/Dijkstra.ts';
5+
import { DepthFirstSearch } from '../algorithms/pathfinding/DepthFirstSearch.ts';
6+
import { primsMazeGeneration } from '../algorithms/mazes/PrimsMazeGeneration.ts';
7+
import { dfsMazeGeneration } from '../algorithms/mazes/DFSMazeGeneration.ts';
8+
9+
interface PathfindingAlgorithmHooksProps {
10+
clearLatestRun: () => void;
11+
populateOptimalPath: (optimalPath: Cell[]) => void;
12+
maze: Cell[][];
13+
startNode: number[];
14+
endNode: number[];
15+
setMaze: (maze: Cell[][]) => void;
16+
}
17+
18+
const pathfindingAlgorithmHooks = ({
19+
clearLatestRun,
20+
populateOptimalPath,
21+
maze,
22+
startNode,
23+
endNode,
24+
setMaze,
25+
}: PathfindingAlgorithmHooksProps) => {
26+
const [algorithm, setAlgorithm] = useState<string | null>(null);
27+
28+
useEffect(() => {
29+
if (!algorithm) return;
30+
31+
const startCell = maze[startNode[0]][startNode[1]];
32+
const endCell = maze[endNode[0]][endNode[1]];
33+
34+
const algorithmMap: Record<string, () => Promise<void> | void> = {
35+
bfs: async () => {
36+
const optimalPath = await BreadthFirstSearch(maze, startCell, endCell, setMaze);
37+
if (optimalPath) populateOptimalPath(optimalPath);
38+
},
39+
dijkstra: async () => {
40+
const optimalPath = await Dijkstra(maze, startCell, endCell, setMaze);
41+
if (optimalPath) populateOptimalPath(optimalPath);
42+
},
43+
dfs: async () => {
44+
const optimalPath = await DepthFirstSearch(maze, startCell, endCell, setMaze);
45+
if (optimalPath) populateOptimalPath(optimalPath);
46+
},
47+
primsMaze: () => {
48+
primsMazeGeneration(maze, startCell, endCell, setMaze);
49+
},
50+
dfsMaze: () => {
51+
dfsMazeGeneration(maze, startCell, endCell, setMaze);
52+
},
53+
};
54+
55+
algorithmMap[algorithm]?.();
56+
57+
setAlgorithm(null);
58+
}, [algorithm, maze, startNode, endNode, clearLatestRun, populateOptimalPath, setMaze]);
59+
60+
const triggerAlgorithm = (algorithm: 'bfs' | 'dijkstra' | 'dfs' | 'primsMaze' | "dfsMaze") => {
61+
clearLatestRun();
62+
setAlgorithm(algorithm)};
63+
64+
return {
65+
triggerAlgorithm,
66+
};
67+
};
68+
69+
export default pathfindingAlgorithmHooks;

0 commit comments

Comments
 (0)