Introduction
Hello, and welcome to my article. Today, I want to talk about how easy it is to create a Sudoku game with Visual Basic.
What Is Sudoku?
Sudoku is a logic-based, combinatorial number-placement puzzle. The objective is to fill a 9X9 grid with digits so that each column, each row, and each of the nine 3X3 sub-grids that compose the grid contain all of the digits from 1 to 9. The puzzle setter provides a partially completed grid, which for a well-posed puzzle has a unique solution. For more information about Sudoku, read this article.
Our Project
I have taken the very long and tedious route to create this project. This means that you have a lot of work to do today, especially on the Design part. Let’s jump straight in, shall we?
Design
Start a new Visual Basic Windows Forms project and design your form to look like Figure 1:
Figure 1: Design
By the looks of the design, you can see that we will be busy today!
Code
Add the following objects that you will use during the course of your program:
Private blnSolution As Boolean = False Private arrGrid(81) As Integer Private arrTemp(81) As String Private arrSolution(81) As String Private arrButtons(81) As Button Private rndNumber As New _ System.Random(CType(Now.Ticks _ Mod Int32.MaxValue, Integer))
I created a Boolean (on/off) flag that will determine whether or not a solution has been found. I then created four arrays identifying each button’s text as well as the grid blocks, as you will see later. The last object holds a random number value that we will use to populate the buttons’ text properties on the grid.
Add the Form_Load event:
Private Sub SudokuForm_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim i, j, k As Integer Dim row, col As Integer arrButtons(1) = Button1 arrButtons(2) = Button2 arrButtons(3) = Button3 arrButtons(4) = Button4 arrButtons(5) = Button5 arrButtons(6) = Button6 arrButtons(7) = Button7 arrButtons(8) = Button8 arrButtons(9) = Button9 arrButtons(10) = Button10 arrButtons(11) = Button11 arrButtons(12) = Button12 arrButtons(13) = Button13 arrButtons(14) = Button14 arrButtons(15) = Button15 arrButtons(16) = Button16 arrButtons(17) = Button17 arrButtons(18) = Button18 arrButtons(19) = Button19 arrButtons(20) = Button20 arrButtons(21) = Button21 arrButtons(22) = Button22 arrButtons(23) = Button23 arrButtons(24) = Button24 arrButtons(25) = Button25 arrButtons(26) = Button26 arrButtons(27) = Button27 arrButtons(28) = Button28 arrButtons(29) = Button29 arrButtons(30) = Button30 arrButtons(31) = Button31 arrButtons(32) = Button32 arrButtons(33) = Button33 arrButtons(34) = Button34 arrButtons(35) = Button35 arrButtons(36) = Button36 arrButtons(37) = Button37 arrButtons(38) = Button38 arrButtons(39) = Button39 arrButtons(40) = Button40 arrButtons(41) = Button41 arrButtons(42) = Button42 arrButtons(43) = Button43 arrButtons(44) = Button44 arrButtons(45) = Button45 arrButtons(46) = Button46 arrButtons(47) = Button47 arrButtons(48) = Button48 arrButtons(49) = Button49 arrButtons(50) = Button50 arrButtons(51) = Button51 arrButtons(52) = Button52 arrButtons(53) = Button53 arrButtons(54) = Button54 arrButtons(55) = Button55 arrButtons(56) = Button56 arrButtons(57) = Button57 arrButtons(58) = Button58 arrButtons(59) = Button59 arrButtons(60) = Button60 arrButtons(61) = Button61 arrButtons(62) = Button62 arrButtons(63) = Button63 arrButtons(64) = Button64 arrButtons(65) = Button65 arrButtons(66) = Button66 arrButtons(67) = Button67 arrButtons(68) = Button68 arrButtons(69) = Button69 arrButtons(70) = Button70 arrButtons(71) = Button71 arrButtons(72) = Button72 arrButtons(73) = Button73 arrButtons(74) = Button74 arrButtons(75) = Button75 arrButtons(76) = Button76 arrButtons(77) = Button77 arrButtons(78) = Button78 arrButtons(79) = Button79 arrButtons(80) = Button80 arrButtons(81) = Button81 For i = 1 To 81 arrButtons(i).Enabled = False Next i End Sub
This is quite straightforward and may seem to be a bit of an overkill. There is method in my madness, however. I didn’t create an array of buttons and calculate each button’s location independently. So, the button array we created holds each button’s (that we created) properties.
Add the next code under the ‘New Game’ button:
Private Sub btnNewGame_Click(ByVal sender _ As System.Object, _ ByVal e As System.EventArgs) _ Handles btnNewGame.Click CreateGrid() btnShowSolution.Enabled = True End Sub
A sub procedure named CreateGrid gets called and the ‘Show Solution’ button becomes enabled. Let’s create the CreatGrid sub procedure now:
Private Sub CreateGrid() Dim i, j, k As Integer Dim intRandom As Integer Dim brnButton As Button Dim ValIsOK(9) As Boolean Dim valsOK As Integer = 0 Cursor.Current = Cursors.WaitCursor For i = 1 To 81 brnButton = arrButtons(i) brnButton.Text = "" brnButton.BackColor = _ System.Drawing.Color.LightGray brnButton.Visible = False arrSolution(i) = "" Next i For i = 1 To 81 If True Then brnButton = arrButtons(i) valsOK = GetValidValues(i, ValIsOK) If valsOK <= 0 Then ' Return False Exit Sub End If intRandom = rndNumber.Next(0, valsOK) + 1 k = 0 For j = 1 To 9 If ValIsOK(j) Then k = k + 1 If k = intRandom Then Exit For End If End If Next j brnButton.Text = j.ToString() brnButton.BackColor = _ System.Drawing.Color.Gray End If Next i For i = 1 To 81 brnButton = arrButtons(i) arrSolution(i) = brnButton.Text intRandom = rndNumber.Next(0, 6 + 1) + 1 If intRandom > 1 Then brnButton.Text = "" brnButton.BackColor = _ System.Drawing.Color.LightGray brnButton.Enabled = True Else brnButton.Enabled = False End If brnButton.Visible = True Next i Cursor.Current = Cursors.Default End Sub
Add the GetValidValues function that checks to see if the current number is a mathematically valid number to be put in the grid:
Private Function GetValidValues(ByVal Location As Integer, _ ByRef ValidVals As Boolean()) As Integer Dim i, j, k As Integer Dim row, col As Integer Dim strNumber As String Dim blnValidNumber As Boolean Dim intReturn As Integer = 0 For i = 1 To 9 blnValidNumber = True strNumber = i.ToString() For j = 1 To 9 k = (Int((Location - 1) / 9) * 9) + j If arrButtons(k).Text = strNumber Then blnValidNumber = False Exit For End If Next j If blnValidNumber Then For j = 1 To 9 k = (((Location - 1) Mod 9) + 1) + _ ((j - 1) * 9) If arrButtons(k).Text = strNumber Then blnValidNumber = False Exit For End If Next j End If If blnValidNumber Then row = Int(Int((Location - 1) / 9) / 3) col = Int(((Location - 1) Mod 9) / 3) For j = 1 To 9 k = (((row * 3) + Int((j - 1) / 3)) * 9) + _ (col * 3) + ((j - 1) Mod 3) + 1 If arrButtons(k).Text = strNumber Then blnValidNumber = False Exit For End If Next j End If ValidVals(i) = blnValidNumber If blnValidNumber Then intReturn = intReturn + 1 End If Next i Return intReturn End Function
Add the remaining events:
Private Sub btnExit_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnExit.Click Close() End Sub Private Sub SudokuButton_Click(ByVal sender _ As System.Object, ByVal e As System.EventArgs) _ Handles Button1.Click, Button2.Click, Button3.Click, _ Button4.Click, Button5.Click, Button6.Click, _ Button7.Click, Button8.Click, Button9.Click, _ Button10.Click, Button11.Click, Button12.Click, _ Button13.Click, Button14.Click, Button15.Click, _ Button16.Click, Button17.Click, Button18.Click, _ Button19.Click, Button20.Click, Button21.Click, _ Button22.Click, Button23.Click, Button24.Click, _ Button25.Click, Button26.Click, Button27.Click, _ Button28.Click, Button29.Click, Button30.Click, _ Button31.Click, Button32.Click, Button33.Click,_ Button34.Click, Button35.Click, Button36.Click, _ Button37.Click, Button38.Click, Button39.Click, _ Button40.Click, Button41.Click, Button42.Click, _ Button43.Click, Button44.Click, Button45.Click, _ Button46.Click, Button47.Click, Button48.Click, _ Button49.Click, Button50.Click, Button51.Click, _ Button52.Click, Button53.Click, Button54.Click, _ Button55.Click, Button56.Click, Button57.Click, _ Button58.Click, Button59.Click, Button60.Click, _ Button61.Click, Button62.Click, Button63.Click, _ Button64.Click, Button65.Click, Button66.Click, _ Button67.Click, Button68.Click, Button69.Click, _ Button70.Click, Button71.Click, Button72.Click, _ Button73.Click, Button74.Click, Button75.Click, _ Button76.Click, Button77.Click, Button78.Click, _ Button79.Click, Button80.Click, Button81.Click Dim i As Integer Dim blnFound As Boolean = True Dim btnButton As Button = CType(sender, Button) If btnButton.Text = "" Then btnButton.Text = "1" ElseIf btnButton.Text = "9" Then btnButton.Text = "" Else btnButton.Text = Trim(Str(CInt(btnButton.Text) + 1)) End If For i = 1 To 81 If arrButtons(i).Text <> arrSolution(i) Then blnFound = False Exit For End If Next i End Sub Private Sub btnShowSolution_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnShowSolution.Click Dim i As Integer If blnSolution Then For i = 1 To 81 arrButtons(i).Text = arrTemp(i) Next i btnShowSolution.Text = "Show Solution" Else For i = 1 To 81 arrTemp(i) = arrButtons(i).Text arrButtons(i).Text = arrSolution(i) Next i btnShowSolution.Text = "Hide Solution" End If blnSolution = Not blnSolution End Sub
Conclusion
Sudoku is quite a fun game, but being as curious as I am, I just had to see if I could figure out the logic of it. I sincerely hope that you have enjoyed this article. Until next time, cheers!