I'm a little stuck. I have a class that I'll be using to generate an entire sudoku puzzle in which right now it's almost completely working, it'll generate a board but there's always an error with it (usually 2 to 10 cells will still have a zero in it because there isn't an available number to be filled in)
Currently here's what I'm doing: I have a 9x9 array of type Integer and I have a 9x9 array of type List(Of Integer) and each element in the list array has the numbers 1 through 9. To fill the 9x9 Integer array I simply start with position 0,0 and work to 8,8 randomly picking a number from the List then a sub will go through and remove that number from the current column, the current row and the current mini-grid.
This is why there's random cells that still have a 0 (zero) in them, it's because there isn't a number available for that cell because of the cells that came before it and this is where I'm stuck.
Here's the code:
Currently here's what I'm doing: I have a 9x9 array of type Integer and I have a 9x9 array of type List(Of Integer) and each element in the list array has the numbers 1 through 9. To fill the 9x9 Integer array I simply start with position 0,0 and work to 8,8 randomly picking a number from the List then a sub will go through and remove that number from the current column, the current row and the current mini-grid.
This is why there's random cells that still have a 0 (zero) in them, it's because there isn't a number available for that cell because of the cells that came before it and this is where I'm stuck.
Here's the code:
VB.NET:
Option Explicit On
Option Strict On
Friend Class SudokuBoard
Private WithEvents bw As New System.ComponentModel.BackgroundWorker
Private m_TheBoard(8I, 8I) As Integer
Private m_Numbers(8, 8) As List(Of Integer)
Friend Event BoardGenerated(ByVal TheBoard(,) As Integer)
#Region " Constructors "
Friend Sub New()
Me.GenerateBoard()
End Sub
#End Region
#Region " GenerateBoard "
Friend Sub GenerateBoard()
Call Me.ClearBoard()
Me.bw.RunWorkerAsync()
End Sub
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork
Dim Rand As New Random
'Dim Index As Integer
For x As Integer = 0I To 8I
For y As Integer = 0I To 8I
m_Numbers(x, y) = New List(Of Integer)
m_Numbers(x, y).AddRange(New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9})
Next y
Next x
For x As Integer = 0I To 8I
For y As Integer = 0I To 8I
Select Case m_Numbers(x, y).Count
Case 0
'No available numbers
Case 1
'Try
m_TheBoard(x, y) = m_Numbers(x, y)(0I)
'Catch
'End Try
Case Is > 1
'Try
'Index = Rand.Next(0I, m_Numbers(x, y).Count)
m_TheBoard(x, y) = m_Numbers(x, y)(Rand.Next(0I, m_Numbers(x, y).Count))
'Catch
'End Try
End Select
RemoveUsedValue(x, y)
Next y
Next x
End Sub
Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
Dim Copy(8, 8) As Integer
For x As Integer = 0I To 8I
For y As Integer = 0I To 8I
Copy(x, y) = m_TheBoard(x, y)
Next y
Next x
RaiseEvent BoardGenerated(Copy)
End Sub
#End Region
#Region " Friend Methods "
Friend Sub ClearBoard()
For x As Integer = 0I To 8I
For y As Integer = 0I To 8I
Me.SetNumber(x, y)
Next y
Next x
End Sub
Friend Sub SetNumber(ByVal Row As Integer, ByVal Col As Integer)
m_TheBoard(Row, Col) = 0I
End Sub
#End Region
#Region " RemoveUsedValue "
Private Sub RemoveUsedValue(ByVal Row As Integer, ByVal Col As Integer)
Dim CurrNumber As Integer = m_TheBoard(Row, Col)
For i As Integer = 0I To 8I
m_Numbers(Row, i).Remove(CurrNumber)
Next i
For i As Integer = 0I To 8I
m_Numbers(i, Col).Remove(CurrNumber)
Next i
Select Case Get3x3(Row, Col)
Case "A1"
'A1, A2, A3
'B1, B2, B3
'C1, C2, C3
m_Numbers(0, 0).Remove(CurrNumber)
m_Numbers(0, 1).Remove(CurrNumber)
m_Numbers(0, 2).Remove(CurrNumber)
m_Numbers(1, 0).Remove(CurrNumber)
m_Numbers(1, 1).Remove(CurrNumber)
m_Numbers(1, 2).Remove(CurrNumber)
m_Numbers(2, 0).Remove(CurrNumber)
m_Numbers(2, 1).Remove(CurrNumber)
m_Numbers(2, 2).Remove(CurrNumber)
Case "A2"
'A4, A5, A6
'B4, B5, B6
'C4, C5, C6
m_Numbers(0, 3).Remove(CurrNumber)
m_Numbers(0, 4).Remove(CurrNumber)
m_Numbers(0, 5).Remove(CurrNumber)
m_Numbers(1, 3).Remove(CurrNumber)
m_Numbers(1, 4).Remove(CurrNumber)
m_Numbers(1, 5).Remove(CurrNumber)
m_Numbers(2, 3).Remove(CurrNumber)
m_Numbers(2, 4).Remove(CurrNumber)
m_Numbers(2, 5).Remove(CurrNumber)
Case "A3"
'A7, A8, A9
'B7, B8, B9
'C7, C8, C9
m_Numbers(0, 6).Remove(CurrNumber)
m_Numbers(0, 7).Remove(CurrNumber)
m_Numbers(0, 8).Remove(CurrNumber)
m_Numbers(1, 6).Remove(CurrNumber)
m_Numbers(1, 7).Remove(CurrNumber)
m_Numbers(1, 8).Remove(CurrNumber)
m_Numbers(2, 6).Remove(CurrNumber)
m_Numbers(2, 7).Remove(CurrNumber)
m_Numbers(2, 8).Remove(CurrNumber)
Case "B1"
'D1, D2, D3
'E1, E2, E3
'F1, F2, F3
m_Numbers(3, 0).Remove(CurrNumber)
m_Numbers(3, 1).Remove(CurrNumber)
m_Numbers(3, 2).Remove(CurrNumber)
m_Numbers(4, 0).Remove(CurrNumber)
m_Numbers(4, 1).Remove(CurrNumber)
m_Numbers(4, 2).Remove(CurrNumber)
m_Numbers(5, 0).Remove(CurrNumber)
m_Numbers(5, 1).Remove(CurrNumber)
m_Numbers(5, 2).Remove(CurrNumber)
Case "B2"
'D4, D5, D6
'E4, E5, E6
'F4, F5, F6
m_Numbers(3, 3).Remove(CurrNumber)
m_Numbers(3, 4).Remove(CurrNumber)
m_Numbers(3, 5).Remove(CurrNumber)
m_Numbers(4, 3).Remove(CurrNumber)
m_Numbers(4, 4).Remove(CurrNumber)
m_Numbers(4, 5).Remove(CurrNumber)
m_Numbers(5, 3).Remove(CurrNumber)
m_Numbers(5, 4).Remove(CurrNumber)
m_Numbers(5, 5).Remove(CurrNumber)
Case "B3"
'D7, D8, D9
'E7, E8, E9
'F7, F8, F9
m_Numbers(3, 6).Remove(CurrNumber)
m_Numbers(3, 7).Remove(CurrNumber)
m_Numbers(3, 8).Remove(CurrNumber)
m_Numbers(4, 6).Remove(CurrNumber)
m_Numbers(4, 7).Remove(CurrNumber)
m_Numbers(4, 8).Remove(CurrNumber)
m_Numbers(5, 6).Remove(CurrNumber)
m_Numbers(5, 7).Remove(CurrNumber)
m_Numbers(5, 8).Remove(CurrNumber)
Case "C1"
'G1, G2, G3
'H1, H2, H3
'I1, I2, I3
m_Numbers(6, 0).Remove(CurrNumber)
m_Numbers(6, 1).Remove(CurrNumber)
m_Numbers(6, 2).Remove(CurrNumber)
m_Numbers(7, 0).Remove(CurrNumber)
m_Numbers(7, 1).Remove(CurrNumber)
m_Numbers(7, 2).Remove(CurrNumber)
m_Numbers(8, 0).Remove(CurrNumber)
m_Numbers(8, 1).Remove(CurrNumber)
m_Numbers(8, 2).Remove(CurrNumber)
Case "C2"
'G4, G5, G6
'H4, H5, H6
'I4, I5, I6
m_Numbers(6, 3).Remove(CurrNumber)
m_Numbers(6, 4).Remove(CurrNumber)
m_Numbers(6, 5).Remove(CurrNumber)
m_Numbers(7, 3).Remove(CurrNumber)
m_Numbers(7, 4).Remove(CurrNumber)
m_Numbers(7, 5).Remove(CurrNumber)
m_Numbers(8, 3).Remove(CurrNumber)
m_Numbers(8, 4).Remove(CurrNumber)
m_Numbers(8, 5).Remove(CurrNumber)
Case "C3"
'G7, G8, G9
'h7, H8, H9
'I7, I8, I9
m_Numbers(6, 6).Remove(CurrNumber)
m_Numbers(6, 7).Remove(CurrNumber)
m_Numbers(6, 8).Remove(CurrNumber)
m_Numbers(7, 6).Remove(CurrNumber)
m_Numbers(7, 7).Remove(CurrNumber)
m_Numbers(7, 8).Remove(CurrNumber)
m_Numbers(8, 6).Remove(CurrNumber)
m_Numbers(8, 7).Remove(CurrNumber)
m_Numbers(8, 8).Remove(CurrNumber)
End Select
End Sub
#End Region
#Region " Get3x3 "
Private Function Get3x3(ByVal x As Integer, ByVal y As Integer) As String
Dim X_Val As Char, Y_Val As Integer
Select Case x
Case 0, 1, 2 : X_Val = "A"c
Case 3, 4, 5 : X_Val = "B"c
Case 6, 7, 8 : X_Val = "C"c
End Select
Select Case y
Case 0, 1, 2 : Y_Val = 1
Case 3, 4, 5 : Y_Val = 2
Case 6, 7, 8 : Y_Val = 3
End Select
Return X_Val & Y_Val
End Function
#End Region
End Class