/** Fill the stack with empty cells. */ static void GridFillStackWithEmptyCells(void) { int Row, Column; CellsStackInitialize(); // Reverse parsing to create a stack with empty coordinates beginning on the top-left part of the grid (this allows to make speed comparisons with the older way to find empty cells) for (Row = Grid_Size - 1; Row >= 0; Row--) { for (Column = Grid_Size - 1; Column >= 0; Column--) { if (Grid[Row][Column] == GRID_EMPTY_CELL_VALUE) CellsStackPush(Row, Column); } } }
/** The brute force backtrack algorithm. * @return 1 if the grid was solved or 0 if not. */ static int Backtrack(void) { int Row, Column; unsigned int Bitmask_Missing_Numbers, Tested_Number; // Find the first empty cell (don't remove the stack top now as the backtrack can return soon if no available number is found) if (CellsStackReadTop(&Row, &Column) == 0) { // No empty cell remain and there is no error in the grid : the solution has been found if (GridIsCorrectlyFilled()) return 1; // A bad grid was generated... #ifdef DEBUG printf("[Backtrack] Bad grid generated !\n"); #endif return 0; } // Get available numbers for this cell Bitmask_Missing_Numbers = GridGetCellMissingNumbers(Row, Column); // If no number is available a bad grid has been generated... It's safe to return here as the top of the stack has not been altered if (Bitmask_Missing_Numbers == 0) return 0; #ifdef DEBUG printf("[Backtrack] Available numbers for (row %d ; column %d) : ", Row, Column); GridShowBitmask(Bitmask_Missing_Numbers); #endif // Try each available number for (Tested_Number = 0; Tested_Number < Grid_Size; Tested_Number++) { // Loop until an available number is found if (!(Bitmask_Missing_Numbers & (1 << Tested_Number))) { Avoided_Bad_Solutions_Count++; continue; } // Try the number GridSetCellValue(Row, Column, Tested_Number); GridRemoveCellMissingNumber(Row, Column, Tested_Number); CellsStackRemoveTop(); // Really try to fill this cell, removing it for next simulation step Loops_Count++; #ifdef DEBUG printf("[Backtrack] Modified grid :\n"); GridShowDifferences(GRID_COLOR_CODE_BLUE); putchar('\n'); #endif // Simulate next state if (Backtrack() == 1) return 1; // Good solution found, go to tree root // Bad solution found, restore old value GridSetCellValue(Row, Column, GRID_EMPTY_CELL_VALUE); GridRestoreCellMissingNumber(Row, Column, Tested_Number); CellsStackPush(Row, Column); // The cell is available again Bad_Solutions_Found_Count++; #ifdef DEBUG printf("[Backtrack] Restored grid :\n"); GridShowDifferences(GRID_COLOR_CODE_RED); putchar('\n'); #endif } // All numbers were tested unsuccessfully, go back into the tree return 0; }