Help with generating sudoku board

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine

Hello,

Im trying to write my own Sudoku game. So far, Ive written almost everything concerning the game itself. Problem is, the function that creates the board itself, meaning, the generator of the numbers.

Some cases it worked. Most cases, it stuck in an endless loop.

If you could guide me or give me some points it would be great.

Basically Im using TLP as my board and created a special class called "textfield" for hosting some extra variables.
Public Class Form1
Dim level As Integer
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim box As textfield
Dim mone, sec As Integer
mone = 0
sec = 1
For i As Integer = 0 To 80
box = New textfield
box.MaxLength = 1
box.Anchor = AnchorStyles.Bottom
box.Anchor = AnchorStyles.Left
box.Anchor = AnchorStyles.Right
box.Anchor = AnchorStyles.Top
box.TextAlign = HorizontalAlignment.Center
box.Font = New Font("Arial", 20)
box.Dock = DockStyle.Fill
box.BorderStyle = BorderStyle.None
AddHandler box.KeyUp, AddressOf check
board.Controls.Add(box)
box.loca.X = board.GetPositionFromControl(box).Row
box.loca.Y = board.GetPositionFromControl(box).Column
box.Text = Nothing
getsection(box)
box.Tag = i
Next
sortme()

End Sub
Public Sub check(sender As System.Object, e As System.EventArgs)
Dim boxclk = DirectCast(sender, textfield)
If boxclk.Text = "" Then
Exit Sub
End If
If Asc(boxclk.Text) > 48 And Asc(boxclk.Text) < 58 Then Checks if is a number
If checkme(boxclk) = 1 Then
MsgBox("Cant write the same number on the same row")
boxclk.Text = ""
End If
If checkme(boxclk) = 2 Then
MsgBox("Cant write the same number on the same column")
boxclk.Text = ""
End If
If checkme(boxclk) = 3 Then
MsgBox("Same section not allowed")
boxclk.Text = ""
End If
Else
Beep()
boxclk.Text = ""
Exit Sub
End If
End Sub
Public Sub sortme()
Dim mone As Integer = 0
Dim used(5) As Integer
Dim txt As textfield
Dim tmp As Integer
Dim rnd As System.Random
rnd = New Random
Randomize()
Do While mone <= 5
txt = board.GetControlFromPosition(rnd.Next(0, 9), rnd.Next(0, 9))
If txt.Text = "" Then
tmp = rnd.Next(1, 10)
For i = 0 To 5
If tmp = used(i) Then
tmp = rnd.Next(1, 10)
End If
Next
txt.Text = tmp
used(mone) = CInt(txt.Text)
txt.BackColor = Color.Gainsboro
txt.Enabled = False
txt.Height = 40
txt.Width = 30
mone += 1
End If
Loop
End Sub
Public Sub sort()
Dim mone As Integer = 0
Dim err As Integer = 0
Dim rnd As System.Random
Dim txt As textfield
Dim tmp As Integer = 0
Dim st As String = ""
Dim i As Integer = 0
rnd = New Random
Randomize()
For Each txt In board.Controls
tmp = rnd.Next(1, 10)
txt.Text = tmp
getnumbers(txt)
Matched(txt, tmp)
While checkme(txt) <> 0
tmp = rnd.Next(1, 10)
txt.Text = tmp
End While
txt.Text = tmp
If txt.moneused > txt.used.Length Then
txt.moneused = txt.used.Length
Else
txt.moneused += 1
End If
Next
End Sub
Public Sub Matched(ByVal txt As textfield, ByVal tmp As Integer)
Dim rnd As System.Random
Rnd = New Random
Randomize()
For i = 1 To txt.moneused
If tmp = txt.used(i - 1) Then
tmp = rnd.Next(1, 10)
txt.used(txt.moneused) = tmp
txt.moneused += 1
End If
If i = txt.moneused Then
If tmp = txt.used(txt.moneused) Then
tmp = rnd.Next(1, 10)
txt.used(txt.moneused) = tmp
txt.moneused += 1
End If
End If
Next
End Sub
Public Function checkme(ByVal box As textfield)
Dim txt As textfield
For i = 0 To 8
txt = board.GetControlFromPosition(i, box.loca.X)
If txt.Text = box.Text And i <> box.loca.Y Then ROW
Return 1
End If
Next
For i = 0 To 8
txt = board.GetControlFromPosition(box.loca.Y, i)
If txt.Text = box.Text And i <> box.loca.X Then COLUMN
Return 2
End If
Next
Select Case box.section
Case 1 : For i = 0 To 2
For j As Integer = 0 To 2
If box.Text = board.GetControlFromPosition(i, j).Text And i <> box.loca.Y And j <> box.loca.X Then
Return 3
End If
Next
Next
Case 2 : For i = 3 To 5
For j As Integer = 0 To 2
If box.Text = board.GetControlFromPosition(i, j).Text And i <> box.loca.Y And j <> box.loca.X Then
Return 3
End If
Next
Next
Case 3 : For i = 6 To 8
For j As Integer = 0 To 2
If box.Text = board.GetControlFromPosition(i, j).Text And i <> box.loca.Y And j <> box.loca.X Then
Return 3
End If
Next
Next
Case 4 : For i = 0 To 2
For j As Integer = 3 To 5
If box.Text = board.GetControlFromPosition(i, j).Text And i <> box.loca.Y And j <> box.loca.X Then
Return 3
End If
Next
Next
Case 5 : For i = 3 To 5
For j As Integer = 3 To 5
If box.Text = board.GetControlFromPosition(i, j).Text And i <> box.loca.Y And j <> box.loca.X Then
Return 3
End If
Next
Next
Case 6 : For i = 6 To 8
For j As Integer = 3 To 5
If box.Text = board.GetControlFromPosition(i, j).Text And i <> box.loca.Y And j <> box.loca.X Then
Return 3
End If
Next
Next
Case 7 : For i = 0 To 2
For j As Integer = 6 To 8
If box.Text = board.GetControlFromPosition(i, j).Text And i <> box.loca.Y And j <> box.loca.X Then
Return 3
End If
Next
Next
Case 8 : For i = 3 To 5
For j As Integer = 6 To 8
If box.Text = board.GetControlFromPosition(i, j).Text And i <> box.loca.Y And j <> box.loca.X Then
Return 3
End If
Next
Next
Case 9 : For i = 6 To 8
For j As Integer = 6 To 8
If box.Text = board.GetControlFromPosition(i, j).Text And i <> box.loca.Y And j <> box.loca.X Then
Return 3
End If
Next
Next
End Select
Return 0
End Function
Public Sub getsection(ByVal box As textfield)
Dim ro As Integer = box.loca.X
Dim co As Integer = box.loca.Y
If ro >= 0 And ro < 3 And co >= 0 And co < 3 Then
box.section = 1
End If
If ro >= 0 And ro < 3 And co > 2 And co < 6 Then
box.section = 2
End If
If ro >= 0 And ro < 3 And co > 5 And co <= 8 Then
box.section = 3
End If
If ro >= 3 And ro < 6 And co >= 0 And co < 3 Then
box.section = 4
End If
If ro >= 3 And ro < 6 And co > 2 And co < 6 Then
box.section = 5
End If
If ro >= 3 And ro < 6 And co > 5 And co <= 8 Then
box.section = 6
End If
If ro >= 6 And ro <= 8 And co >= 0 And co < 3 Then
box.section = 7
End If
If ro >= 6 And ro <= 8 And co > 2 And co < 6 Then
box.section = 8
End If
If ro >= 6 And ro <= 8 And co > 5 And co <= 8 Then
box.section = 9
End If
End Sub

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
sort()
End Sub
Public Sub getnumbers(ByVal txt As textfield)
Dim tmp As textfield
For i = 0 To 8
tmp = board.GetControlFromPosition(i, txt.loca.X)
If tmp.Text <> Nothing And i <> txt.loca.Y Then ROW
txt.used(txt.moneused) = System.Convert.ToInt32(board.GetControlFromPosition(i, txt.loca.X).Text)
txt.moneused += 1
End If
Next
For i = 0 To 8
If board.GetControlFromPosition(txt.loca.Y, i).Text <> Nothing And i <> txt.loca.X Then COLUMN
txt.used(txt.moneused) = board.GetControlFromPosition(txt.loca.Y, i).Text
txt.moneused += 1
End If
Next
Select Case txt.section
Case 1 : For i = 0 To 2
For j As Integer = 0 To 2
If board.GetControlFromPosition(i, j).Text <> Nothing And i <> txt.loca.Y And j <> txt.loca.X Then
txt.used(txt.moneused) = board.GetControlFromPosition(i, j).Text
txt.moneused += 1
End If
Next
Next
Case 2 : For i = 3 To 5
For j As Integer = 0 To 2
If board.GetControlFromPosition(i, j).Text <> Nothing And i <> txt.loca.Y And j <> txt.loca.X Then
txt.used(txt.moneused) = board.GetControlFromPosition(i, j).Text
txt.moneused += 1
End If
Next
Next
Case 3 : For i = 6 To 8
For j As Integer = 0 To 2
If board.GetControlFromPosition(i, j).Text <> Nothing And i <> txt.loca.Y And j <> txt.loca.X Then
txt.used(txt.moneused) = board.GetControlFromPosition(i, j).Text
txt.moneused += 1
End If
Next
Next
Case 4 : For i = 0 To 2
For j As Integer = 3 To 5
If board.GetControlFromPosition(i, j).Text <> Nothing And i <> txt.loca.Y And j <> txt.loca.X Then
txt.used(txt.moneused) = board.GetControlFromPosition(i, j).Text
txt.moneused += 1
End If
Next
Next
Case 5 : For i = 3 To 5
For j As Integer = 3 To 5
If board.GetControlFromPosition(i, j).Text <> Nothing And i <> txt.loca.Y And j <> txt.loca.X Then
txt.used(txt.moneused) = board.GetControlFromPosition(i, j).Text
txt.moneused += 1
End If
Next
Next
Case 6 : For i = 6 To 8
For j As Integer = 3 To 5
If board.GetControlFromPosition(i, j).Text <> Nothing And i <> txt.loca.Y And j <> txt.loca.X Then
txt.used(txt.moneused) = board.GetControlFromPosition(i, j).Text
txt.moneused += 1
End If
Next
Next
Case 7 : For i = 0 To 2
For j As Integer = 6 To 8
If board.GetControlFromPosition(i, j).Text <> Nothing And i <> txt.loca.Y And j <> txt.loca.X Then
txt.used(txt.moneused) = board.GetControlFromPosition(i, j).Text
txt.moneused += 1
End If
Next
Next
Case 8 : For i = 3 To 5
For j As Integer = 6 To 8
If board.GetControlFromPosition(i, j).Text <> Nothing And i <> txt.loca.Y And j <> txt.loca.X Then
txt.used(txt.moneused) = board.GetControlFromPosition(i, j).Text
txt.moneused += 1
End If
Next
Next
Case 9 : For i = 6 To 8
For j As Integer = 6 To 8
If board.GetControlFromPosition(i, j).Text <> Nothing And i <> txt.loca.Y And j <> txt.loca.X Then
txt.used(txt.moneused) = board.GetControlFromPosition(i, j).Text
txt.moneused += 1
End If
Next
Next
End Select
End Sub
End Class

Public Class textfield
Inherits TextBox
Public loca As Point
Public section As Integer
Public moneused As Integer = 0
Public used(81) As Integer
End Class

Sort is the main sub for generating and sorting the sudoku board so it could be solvable. Matched is for checking if the number (TMP) appears in the array that Ive created for every single textfield. textfiled is a class that inherits textbox plus some extra variables I needed. checkme is basically the main function for checking legal moves. getnumbers is a sub to add to every txt (textfield) the previous numbers in the same row, column and section in a stored array (called used). moneused is an index for the used array. Thanks for the help !!


View the full article
 
Back
Top