@@ -9,14 +9,12 @@ import { Dijkstra } from '../algorithms/pathfinding/Dijkstra.ts';
99import { DepthFirstSearch } from '../algorithms/pathfinding/DepthFirstSearch.ts' ;
1010import { primsMazeGeneration } from '../algorithms/mazes/PrimsMazeGeneration.ts' ;
1111import { dfsMazeGeneration } from '../algorithms/mazes/DFSMazeGeneration.ts' ;
12+ import mazeHooks from '../utils/mazeHooks.ts' ;
1213
1314const PathfindingVisualiser : React . FC = ( ) => {
1415 const { width = 0 , height = 0 } = useWindowDimensions ( ) ;
15- const [ maze , setMaze ] = useState < Cell [ ] [ ] > ( [ ] ) ;
1616 const [ isDrawing , setIsDrawing ] = useState < boolean > ( false ) ;
1717 const [ drawingValue , setDrawingValue ] = useState < boolean > ( false ) ;
18- const [ startNode , setStartNode ] = useState < number [ ] > ( [ 0 , 0 ] ) ;
19- const [ endNode , setEndNode ] = useState < number [ ] > ( [ 0 , 0 ] ) ;
2018 const [ isMovingNode , setIsMovingNode ] = useState < 'start' | 'end' | null > ( null ) ;
2119 const [ runDijkstra , setRunDijkstra ] = useState < boolean > ( false ) ;
2220 const [ runBFS , setRunBFS ] = useState < boolean > ( false ) ;
@@ -63,48 +61,17 @@ const PathfindingVisualiser: React.FC = () => {
6361 }
6462 } , [ generateDFSMaze ] ) ;
6563
66- function setStartPosition ( flatHeight : number , flatWidth : number ) {
67- const rowIndex = Math . floor ( flatHeight / 2 ) ;
68- const colIndex = Math . floor ( flatWidth / 4 ) ;
69- setMaze ( prevMaze => {
70- const newMaze = [ ...prevMaze ] ;
71- newMaze [ rowIndex ] [ colIndex ] = new Cell ( rowIndex , colIndex ) ;
72- newMaze [ rowIndex ] [ colIndex ] . start = true ;
73- return newMaze ;
74- } ) ;
75- setStartNode ( [ rowIndex , colIndex ] ) ;
76- }
77-
78- function setEndPosition ( flatHeight : number , flatWidth : number ) {
79- const rowIndex = Math . floor ( flatHeight / 2 ) ;
80- const colIndex = Math . floor ( flatWidth * 3 / 4 ) ;
81- setMaze ( prevMaze => {
82- const newMaze = [ ...prevMaze ] ;
83- newMaze [ rowIndex ] [ colIndex ] = new Cell ( rowIndex , colIndex ) ;
84- newMaze [ rowIndex ] [ colIndex ] . end = true ;
85- return newMaze ;
86- } ) ;
87- setEndNode ( [ rowIndex , colIndex ] ) ;
88- }
89-
90- function generateTable ( ) {
91- let flatHeight = Math . floor ( ( height - 26 ) / 26 ) ;
92- if ( flatHeight % 2 === 0 ) flatHeight += 1 ;
93- let flatWidth = Math . floor ( ( width - 326 ) / 26 ) ;
94- if ( flatWidth % 2 === 0 ) flatWidth += 1 ;
95-
96- const newMaze = [ ] ;
97- for ( let i = 0 ; i < flatHeight ; i ++ ) {
98- const row = [ ] ;
99- for ( let j = 0 ; j < flatWidth ; j ++ ) {
100- row . push ( new Cell ( i , j ) ) ;
101- }
102- newMaze . push ( row ) ;
103- }
104- setMaze ( newMaze ) ;
105- setStartPosition ( flatHeight , flatWidth ) ;
106- setEndPosition ( flatHeight , flatWidth ) ;
107- }
64+ const {
65+ maze,
66+ setMaze,
67+ startNode,
68+ endNode,
69+ setStartNode,
70+ setEndNode,
71+ generateTable,
72+ clearAttribute,
73+ populateOptimalPath,
74+ } = mazeHooks ( width , height ) ;
10875
10976 const handleMouseDown = ( rowIndex : number , colIndex : number ) => {
11077 if ( maze [ rowIndex ] [ colIndex ] . start ) {
@@ -158,50 +125,6 @@ const PathfindingVisualiser: React.FC = () => {
158125 } ) ;
159126 } ;
160127
161- function clearAttribute ( attribute : keyof Cell ) {
162- if ( maze . length === 0 || maze [ 0 ] . length === 0 ) {
163- console . error ( `Maze is empty or not initialized.` ) ;
164- return ;
165- }
166-
167- const sampleCell = maze [ 0 ] [ 0 ] ;
168- const validAttributes = Object . keys ( sampleCell ) ;
169-
170- if ( ! validAttributes . includes ( attribute ) ) {
171- console . error ( `Invalid attribute: ${ attribute } ` ) ;
172- return ;
173- }
174-
175- setMaze ( prevMaze => prevMaze . map ( row =>
176- row . map ( cell => ( { ...cell , [ attribute ] : false } ) )
177- ) ) ;
178- } ;
179-
180- async function populateOptimalPath ( optimalPath : Cell [ ] | null ) {
181- if ( ! optimalPath ) {
182- return ;
183- }
184-
185- const delay = 50 ; // Delay in milliseconds between each update
186-
187- const updateCell = ( index : number ) => {
188- if ( index >= optimalPath . length ) {
189- return ;
190- }
191-
192- setMaze ( prevMaze => {
193- const newMaze = prevMaze . map ( row => row . map ( cell => ( { ...cell } ) ) ) ;
194- newMaze [ optimalPath [ index ] . row ] [ optimalPath [ index ] . col ] . finalPath = true ;
195- return newMaze ;
196- } ) ;
197-
198- // Schedule the next update with delay
199- requestAnimationFrame ( ( ) => setTimeout ( ( ) => updateCell ( index + 1 ) , delay ) ) ;
200- } ;
201-
202- updateCell ( 0 ) ;
203- }
204-
205128 async function callBFS ( ) {
206129 const optimalPath = await BreadthFirstSearch ( maze , maze [ startNode [ 0 ] ] [ startNode [ 1 ] ] , maze [ endNode [ 0 ] ] [ endNode [ 1 ] ] , setMaze ) ;
207130 await populateOptimalPath ( optimalPath ) ;
@@ -235,23 +158,23 @@ const PathfindingVisualiser: React.FC = () => {
235158 setRunDFS ( true ) ;
236159 }
237160
238- function primsMazeRun ( ) {
161+ function triggerPrimsMaze ( ) {
239162 clearAttribute ( 'visited' ) ;
240163 clearAttribute ( 'finalPath' ) ;
241164 setGeneratePrimsMaze ( true ) ;
242165 }
243166
244- function DFSMazeRun ( ) {
167+ function triggerDFSMaze ( ) {
245168 clearAttribute ( 'visited' ) ;
246169 clearAttribute ( 'finalPath' ) ;
247170 setGenerateDFSMaze ( true ) ;
248171 }
249172
250- function triggerPrimsMaze ( ) {
173+ function primsMazeRun ( ) {
251174 primsMazeGeneration ( maze , maze [ startNode [ 0 ] ] [ startNode [ 1 ] ] , maze [ endNode [ 0 ] ] [ endNode [ 1 ] ] , setMaze ) ;
252175 }
253176
254- function triggerDFSMaze ( ) {
177+ function DFSMazeRun ( ) {
255178 dfsMazeGeneration ( maze , maze [ startNode [ 0 ] ] [ startNode [ 1 ] ] , maze [ endNode [ 0 ] ] [ endNode [ 1 ] ] , setMaze ) ;
256179 }
257180
0 commit comments