@@ -6,13 +6,26 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
66
77part 'grid_notifier_state.dart' ;
88
9+ class MazeDirection {
10+ final int rowDelta;
11+ final int colDelta;
12+
13+ const MazeDirection ._(this .rowDelta, this .colDelta);
14+
15+ static const up = MazeDirection ._(- 1 , 0 );
16+ static const down = MazeDirection ._(1 , 0 );
17+ static const left = MazeDirection ._(0 , - 1 );
18+ static const right = MazeDirection ._(0 , 1 );
19+ }
20+
921class GridNotifierCubit extends StateNotifier <GridNotifierState > {
1022 GridNotifierCubit () : super (GridNotifierState ());
1123 final int columnSquares = 20 ;
1224 static const Duration scaleAppearDurationForWall = Duration (milliseconds: 700 );
13- static const Duration clearDuration = Duration (microseconds: 10 );
25+ static const Duration clearDuration = Duration (microseconds: 1 );
1426 static const Duration drawFindingPathDuration = Duration (milliseconds: 2 );
1527 static const Duration drawSearcherDuration = Duration (milliseconds: 5 );
28+ static const Duration mazeDuration = Duration (milliseconds: 10 );
1629
1730 int tapDownIndex = - 1 ;
1831 GridStatus tapDownGridStatus = GridStatus .empty;
@@ -318,7 +331,7 @@ class GridNotifierCubit extends StateNotifier<GridNotifierState> {
318331 }
319332 }
320333
321- void generateMaze () {
334+ void generateMaze () async {
322335 final gridData = List <GridStatus >.from (state.gridData);
323336
324337 // Clear the maze but keep start and target points
@@ -328,68 +341,40 @@ class GridNotifierCubit extends StateNotifier<GridNotifierState> {
328341 }
329342 }
330343
331- // Start the division from the full grid
332- _recursiveDivision (gridData, 0 , state.rowMainAxisCount, 0 , state.columnCrossAxisCount);
333- }
334-
335- Future <void > _recursiveDivision (
336- List <GridStatus > gridData, int rowStart, int rowEnd, int colStart, int colEnd) async {
337- if (rowEnd - rowStart < 2 || colEnd - colStart < 2 ) return ; // Avoid too small segments
344+ // Random starting point
345+ final random = Random ();
346+ int startRow = (random.nextInt (state.rowMainAxisCount - 2 ) ~ / 2 ) * 2 + 1 ;
347+ int startCol = (random.nextInt (state.columnCrossAxisCount - 2 ) ~ / 2 ) * 2 + 1 ;
338348
339- bool divideVertically = Random (). nextBool ( );
349+ await _cravePassage (startRow, startCol, gridData );
340350
341- if (divideVertically) {
342- return _recursiveVerticalDivision (gridData, rowStart, rowEnd, colStart, colEnd);
343- } else {
344- return _recursiveHorizontalDivision (gridData, rowStart, rowEnd, colStart, colEnd);
345- }
351+ state = state.copyWith (gridData: gridData);
346352 }
347353
348- Future <void > _recursiveVerticalDivision (
349- List <GridStatus > gridData, int rowStart, int rowEnd, int colStart, int colEnd) async {
350- if (rowEnd - rowStart < 2 || colEnd - colStart < 2 ) return ;
351-
352- int splitCol = Random ().nextInt (colEnd - colStart - 1 ) + colStart + 1 ;
353- for (int row = rowStart; row < rowEnd; row++ ) {
354- if (row == rowStart || row == rowEnd - 1 ) continue ; // Skip the boundary
355- final index = row * state.columnCrossAxisCount + splitCol;
356- final grid = gridData[index];
357- if (grid == GridStatus .startPoint || grid == GridStatus .targetPoint) return ;
358- gridData[index] = GridStatus .wall;
359- state = state.copyWith (gridData: List <GridStatus >.from (gridData));
360- await Future .delayed (const Duration (milliseconds: 10 ));
361- }
362-
363- // Open a passage
364- int passageAt = Random ().nextInt (rowEnd - rowStart) + rowStart;
365- gridData[passageAt * state.columnCrossAxisCount + splitCol] = GridStatus .empty;
354+ Future <void > _cravePassage (int row, int col, List <GridStatus > gridData) async {
355+ final directions = [MazeDirection .up, MazeDirection .down, MazeDirection .left, MazeDirection .right];
356+ directions.shuffle ();
366357
367- await _recursiveDivision (gridData, rowStart, rowEnd, colStart, splitCol);
368- await _recursiveDivision (gridData, rowStart, rowEnd, splitCol + 1 , colEnd) ;
369- }
358+ for ( final direction in directions) {
359+ final newRow = row + direction.rowDelta * 2 ;
360+ final newCol = col + direction.colDelta * 2 ;
370361
371- Future <void > _recursiveHorizontalDivision (
372- List <GridStatus > gridData, int rowStart, int rowEnd, int colStart, int colEnd) async {
373- if (rowEnd - rowStart < 2 || colEnd - colStart < 2 ) return ;
362+ if (_isValidCell (newRow, newCol) &&
363+ gridData[newRow * state.columnCrossAxisCount + newCol] == GridStatus .empty) {
364+ gridData[(row + direction.rowDelta) * state.columnCrossAxisCount + (col + direction.colDelta)] =
365+ GridStatus .wall;
366+ gridData[newRow * state.columnCrossAxisCount + newCol] = GridStatus .wall;
374367
375- int splitRow = Random ().nextInt (rowEnd - rowStart - 1 ) + rowStart + 1 ;
376- for (int col = colStart; col < colEnd; col++ ) {
377- if (col == colStart || col == colEnd - 1 ) continue ; // Skip the boundary
368+ state = state.copyWith (gridData: List .from (gridData));
378369
379- final index = splitRow * state.columnCrossAxisCount + col;
380- final grid = gridData[index];
381- if (grid == GridStatus .startPoint || grid == GridStatus .targetPoint) return ;
382- gridData[index] = GridStatus .wall;
370+ await Future .delayed (mazeDuration);
383371
384- state = state. copyWith (gridData : List < GridStatus >. from ( gridData) );
385- await Future . delayed ( const Duration (milliseconds : 10 ));
372+ await _cravePassage (newRow, newCol, gridData);
373+ }
386374 }
375+ }
387376
388- // Open a passage
389- int passageAt = Random ().nextInt (colEnd - colStart) + colStart;
390- gridData[splitRow * state.columnCrossAxisCount + passageAt] = GridStatus .empty;
391-
392- await _recursiveDivision (gridData, rowStart, splitRow, colStart, colEnd);
393- await _recursiveDivision (gridData, splitRow + 1 , rowEnd, colStart, colEnd);
377+ bool _isValidCell (int row, int col) {
378+ return row > 0 && col > 0 && row < state.rowMainAxisCount && col < state.columnCrossAxisCount;
394379 }
395380}
0 commit comments