Private/FindValidSudokuGrid.ps1
<# .SYNOPSIS Main algorithm to generate a random solvable Sudoku board. .DESCRIPTION Picks 10 random numbers and ensures valid placement. Then solves the puzzle and eventually removes a specific number of clues based on the difficulty level. This function is kept private due to the fact that it is not meant to be used outside of the GenerateGrid function call. .PARAMETER Grid The grid to return that will be the main Sudoku board. This starts out as an empty grid initialized with all 0s. .PARAMETER NumClues The number of clues to give the Sudoku board. This number is determined from the difficulty level that is passed from the GenerateGrid function. .EXAMPLE FindValidSudokuGrid -Grid $EmptyGrid -NumClues 23 .EXAMPLE #An example from the calling function GenerateGrid -Difficulty "Hard" #This will return a grid with 23 clues. Reference documentation for GenerateGrid to see how the function is called within it. .INPUTS Takes in an array, and a number of clues. .OUTPUTS Returns a randomly generated solvable Sudoku board with only the number of clues filled out. #> Function FindValidSudokuGrid { param( [parameter(Mandatory=$true)] [System.Object]$Grid, [parameter(Mandatory=$true)] [System.Object]$NumClues ) while ($true) { $ReturnGrid = DeepCopyArray $Grid #Iterate num clues 10 times. Each iteration, picking a random cell, and setting it to a random value. For($i = 0; $i -lt 10; $i++) { [int32]$NumToTry = Get-Random -Minimum 1 -Maximum 9 [int32]$RowToTry = Get-Random -Minimum 0 -Maximum 8 [int32]$ColToTry = Get-Random -Minimum 0 -Maximum 8 #Make sure move is valid and is not in use already if ((IsMoveValid -SudokuGrid $Grid -Row ($RowToTry+1) -Col ($ColToTry+1) -Number $NumToTry) -and ($Grid[$RowToTry][$ColToTry] -eq '-')) { $Grid[$RowToTry][$ColToTry] = $NumToTry #assign the number to the grid $ReturnGrid[$RowToTry][$ColToTry] = $NumToTry #update the return grid $Grid = DeepCopyArray $ReturnGrid #re-copy the current state of the return grid to the grid } } # Stopwatch to track the length of time. I don't want grid generation to take too long. $stopwatch = [system.diagnostics.stopwatch]::StartNew() #If this grid has a valid solution return the grid if (SolveSudoku -SudokuGrid $Grid -StopWatch $stopwatch) { return (RemoveRandomNumsFromGrid -SolvedGrid $Grid -NumClues $NumClues) } #otherwise retry the process else { $Grid = GenerateGrid -Difficulty "Empty" $ReturnGrid = DeepCopyArray $Grid continue } } } |