1.11M Members

Hi, I'm currently trying to program a sudoku solver.

As a beginner I wrote pseudocode to establish what I'd have to do. One of the first things was to make sure each number in each of the 3 x 3 grids aren't equal to any of the others. Here is my attempt. I'm pretty sure I've gone the long way around tackling this but it was the only way I was fairly confident I knew how to do, haha. txt1_2 means that it's the second number in the first 3 x 3 grid (from left to right). At the moment, even if I put in different numbers, it comes up with two of the 'error' message boxes. This code only focuses on the first 3 x 3 grid. Any help would be much appreciated!

Thanks

``````Public Class Form1

Private Sub btnSolve_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSolve.Click
Dim Group1(8) As String
Dim Group2(8) As Integer
Dim x As Integer

Group1(0) = txt1_1.Text
Group1(1) = txt1_2.Text
Group1(2) = txt1_3.Text
Group1(3) = txt1_4.Text
Group1(4) = txt1_5.Text
Group1(5) = txt1_6.Text
Group1(6) = txt1_7.Text
Group1(7) = txt1_8.Text
Group1(8) = txt1_9.Text

For x = 0 To 8
Select Case x
Case Is = 8
If Group1(x) = Group1(0) Or Group1(1) Or Group1(2) Or Group1(3) Or Group1(4) Or Group1(5) Or Group1(6) Or Group1(7) Then
MessageBox.Show("Error!")
Else
End If
Case x = 7
If Group1(x) = Group1(0) Or Group1(1) Or Group1(2) Or Group1(3) Or Group1(4) Or Group1(5) Or Group1(6) Or Group1(8) Then
MessageBox.Show("Error!")
Else
End If
Case x = 6
If Group1(x) = Group1(0) Or Group1(1) Or Group1(2) Or Group1(3) Or Group1(4) Or Group1(5) Or Group1(7) Or Group1(8) Then
MessageBox.Show("Error!")
Else
End If
Case x = 5
If Group1(x) = Group1(0) Or Group1(1) Or Group1(2) Or Group1(3) Or Group1(4) Or Group1(7) Or Group1(6) Or Group1(8) Then
MessageBox.Show("Error!")
End If
Case x = 4
If Group1(x) = Group1(0) Or Group1(1) Or Group1(2) Or Group1(3) Or Group1(7) Or Group1(5) Or Group1(6) Or Group1(8) Then
MessageBox.Show("Error!")
Else
End If
Case x = 3
If Group1(x) = Group1(0) Or Group1(1) Or Group1(2) Or Group1(7) Or Group1(4) Or Group1(5) Or Group1(6) Or Group1(8) Then
MessageBox.Show("Error!")
Else
End If
Case x = 2
If Group1(x) = Group1(0) Or Group1(1) Or Group1(7) Or Group1(3) Or Group1(4) Or Group1(5) Or Group1(6) Or Group1(8) Then
MessageBox.Show("Error!")
Else
End If
Case x = 1
If Group1(x) = Group1(0) Or Group1(7) Or Group1(2) Or Group1(3) Or Group1(4) Or Group1(5) Or Group1(6) Or Group1(8) Then
MessageBox.Show("Error!")
Else
End If
Case x = 0
If Group1(x) = Group1(7) Or Group1(1) Or Group1(2) Or Group1(3) Or Group1(4) Or Group1(5) Or Group1(6) Or Group1(8) Then
MessageBox.Show("Error!")
Else
End If
End Select
Next

End Sub
End Class``````

I wrote something like that quite a while back and I used an 3x3x3x3 array of textboxes. By picking various combinations of indexes I was able to check for duplicates in any of the required directions.

If you are interested, there is a very good book by Wei-Meng Lee (Apress books) titled Programming Sudoku. It covers both generating and solving algorithms.

Thanks, looks a great book! (Looks a lot more complicated I had origianlly anticipated) I sort of want to figure out how to do it by myself, but will definitely look into that - as a prompt. Apress.com looks a good site actually, have never heard of it before :)

Like you, I prefer to solve by logic rather than by brute force. I don't, however, enjoy the drudgery of determining what digits are possible in blank squares. My solver allows you to enter the known digits and displays the remaining possible digits in the other cells (solved cells in large font, unsolved cells in small font). Each time I solve a new cell it recalculates the remaining cells. All of the fun and none of the tedium.

I like that idea. How did you work out what the possible values were?

I've gone a step backwards in my code. Working only with the first row of the grid, I'm trying to work out how to determine if a number is entered in that row, and for the position that number is in,to be displayed in a message box. Take a look at my code... At the moment if I type a number in any of the textboxes, it comes up with infinite message boxes saying "0". Any suggestions?

``````Private Sub btnSolve_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSolve.Click
Dim Group1(8) As String
Dim Group2(8) As Integer
Dim NumberInRow As Integer
Dim Grid(0, 8) As Integer
Dim Row1(8) As String
Dim NoProblem As Boolean

Row1(0) = txt1_1.Text
Row1(1) = txt1_2.Text
Row1(2) = txt1_3.Text
Row1(3) = txt2_1.Text
Row1(4) = txt2_2.Text
Row1(5) = txt2_3.Text
Row1(6) = txt3_1.Text
Row1(7) = txt3_2.Text
Row1(8) = txt3_3.Text

Dim count As Integer
For count = 1 To 9
If Row1(count) = "" Then
NoProblem = True
Else
count = NumberInRow
NoProblem = False
MessageBox.Show(NumberInRow)

End If
Next

End Sub
End Class``````

I start with an array of multiline textbox controls (see attached). It is dimensioned as

Dim Square(2, 2, 2, 2) As System.Windows.Forms.TextBox

It is set up as a 3x3 grid where each unit in the grid is another 3x3 grid.

Each control is sized so that when set to the string "1 2 3 4 5 6 7 8 9", the digits appear over three lines. The dimensions are arranged so that when you vary the last two coordinates (k and l of i,j,k,l) you can access one set of 9 (3x3) cells. By choosing which coordinates to vary you can scan any one 3x3 cell, any row or any column.

In order to eliminate possibilities, every time I enter a single didit in a cell, I rescan and recalculate all remaining cells. If, during a scan a cell is reduced to a single possibility (ie that cell is solved), I rescan the entire grid.

That was my approach anyway. I'm certainly open to other suggestions.

Attachments

Ah I see. That's very logical. I may use you idea of the (2,2,2,2) idea if you don't mind, that's much better than my 2 dimension array. Could you please explain why you've stored it as a textbox, why not store it as integers?

I'm still working on the 'rescanning and recalculating' part. I've tried creating a loop which goes through the impossibilites of a single block, and comparing it to an array containing the possibilites (1,2,3,4...) and deleting it from the possibilites if there are matches. This is my loop... haven't had much luck, haha. I feel I'm slowly giving up to the 'I can go alone' view on this project :S Any ideas?

``````For x = 0 To 8
If Block1Suggestions(x) = RowImposs(0) Or RowImposs(1) Or RowImposs(2) Or RowImposs(3) Or RowImposs(4) Or RowImposs(5) Or RowImposs(6) Or RowImposs(7) Or RowImposs(8) Then
Block1Suggestions(x).Remove(x)
Block1Suggestions = RowPossibilities

MessageBox.Show(RowPossibilities(x))
End If
Next``````

I used a textbox because I hadn't been using VB for that long an it seemed to be an easy control to work with. I didn't feel like doing a lot of research. I just wanted to jump in and have at it. I can see plenty of room for improvement. Probably time for a rewrite.

You