How to Build a Sudoku Game in Visual Basic

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

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:

Sudoku
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!

Hannes DuPreez
Hannes DuPreez
Ockert J. du Preez is a passionate coder and always willing to learn. He has written hundreds of developer articles over the years detailing his programming quests and adventures. He has written the following books: Visual Studio 2019 In-Depth (BpB Publications) JavaScript for Gurus (BpB Publications) He was the Technical Editor for Professional C++, 5th Edition (Wiley) He was a Microsoft Most Valuable Professional for .NET (2008–2017).

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read