Programming Tic-Tac-Toe In Visual Basic.NET

Written By: Kevin Jordan

- 10 Feb 2006 -
















Description: We'll start by using the visual editor to set up our interface and take it all the way into programming the artificial intelligence of the computer opponent.

  1. Creating the User Interface
  2. Starting a Game and Making a Menu
  3. Programming the Game Logic
  4. An Intelligent Opponent

Game Actions

In every game there needs to be a way to start a new game, an opponent, a win/lose condition, and the ability to quit. The first thing I decided to create was the beginning and the end. Then I'll move on to programming the interesting stuff: the opponent and the ability to win or lose (and in tic-tac-toe, obviously draw).

Starting the Game

There are two events that will trigger a new game. The first one is when the application first opens. The second will be when someone goes to Options ? New Game from the menu. For this part of the process there will be some actual coding instead of the drag and drop "programming".

We're going to need a few variables throughout the duration of the program.

Public Shared arrGrid(3, 3) As Integer
Public Shared intAIDifficulty As Integer
Public Shared intWhosTurn As Integer
Public Shared intWhosWinner As Integer

arrGrid is a 3x3 array that represents the game board, a 0 in the board will mean that the spot is still available. A 1 will mean that the player has possession of the space, while a 2 means that the computer opponent does. intAIDifficulty will store difficulty level which will be used when we started adding in the computer opponent. intWhosTurn knows whose turn it is, player 1 or 2. And, intWhosWinner will store a value between 0-3 representing if anybody has won yet. 0 means the game is still going on, while 3 means the game is a tie.

Private Enum Difficulty
        Easy = 0
        Medium = 1
        Hard = 2
End Enum

I also decided to enumerate the difficulty level. The Enum Difficulty isn't required, but if the program got long and the difficulty value was used a lot, it would save a few headaches. Some people might also want to enumerate the players or who's winning; it's up to you.

Below the Window Form Designer generated code I added the following lines:

Private Sub frmTicTacToe_Load(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
        Call InitGrid()
        Call SetDifficulty(Difficulty.Medium)
        intWhosTurn = 1
End Sub ' frmTicTacToe_Load 

The frmTicTacToe_Load() subroutine may already be there, but if not, you'll definitely need to add it. This is what is executed when the program is first loaded (the programs first starting condition). Because there hasn't been any user input yet, I'll need to set up all the defaults and clear the grid.

Drawing The Grid

I created two subroutines and also let the system know that the player should have the first move. InitGrid() will simply set every value in our 3x3 array to 0, and then clear the game board. SetDifficulty() will not only set a difficulty variable, but also put a pretty check on next to difficulty selected.

Private Sub InitGrid()
        ' Sets all values in the grid array to 0
        For i As Integer = 0 To 2
                For j As Integer = 0 To 2
                        arrGrid(i, j) = 0
                Next
        Next
        Call DrawGrid()
End Sub ' InitGrid 

The first thing that happens in the program is to ensure all values in the array are set to 0. I accomplished this by using a nested for loop. It travels down each row setting the values to 0 and before it calls DrawGrid(). DrawGrid() will make the board representative of the array by replacing 1s with Os and 2s with Xs.

Private Sub DrawGrid()
        If arrGrid(0, 0) = 1 Then
                Me.lblGrid00.Text = "O"
        ElseIf arrGrid(0, 0) = 2 Then
                Me.lblGrid00.Text = "X"
        Else
                Me.lblGrid00.Text = ""
        End If
 
End Sub ' DrawGrid 

This is part of the DrawGrid() sub. For each position in the array, it'll check the value and set the label to its corresponding character. Nine of these condition statements are required to draw the whole board.

Setting The Difficulty

Private Sub SetDifficulty(ByVal intDifficulty As Integer)
        intAIDifficulty = intDifficulty
        Select Case intDifficulty
                Case 0
                        Me.menuEasy.Checked = True
                        Me.menuMedium.Checked = False
                        Me.menuHard.Checked = False
                Case 1
                        Me.menuEasy.Checked = False
                        Me.menuMedium.Checked = True
                        Me.menuHard.Checked = False
                Case 2
                        Me.menuEasy.Checked = False
                        Me.menuMedium.Checked = False
                        Me.menuHard.Checked = True
        End Select
End Sub ' SetDifficulty 

Whenever we called SetDifficult() with Difficulty.Medium, it stuck a 1 there and set intAIDifficulty to 1. I also wanted the players to know what level opponent they were competing against so Me.menuMedium.Check = True puts a little check to the left of Medium on our menu. Setting the other values to false ensure that there aren't any extra checks.

Now that the defaults are set up, all the program does is waits for a player to click a square. Using many of the routines already programmed with can set up the board for when a player calls a new game from the menu.

Using the Options Menu

I programmed a behavior for each item on the Options menu: new game, difficulty, and quit.

Private Sub menuNewGame_Click(ByVal sender _
As System.Object, ByVal e As System.EventArgs) Handles menuNewGame.Click
        Call InitGrid()
        intWhosWinner = 0
        If intWhosTurn = 2 Then
                Call AIMove()
        End If
End Sub ' menuNewGame_Click 

New game is similar to when the program starts, except that it will reset the intWhosWinner variable, and tell the computer opponent move if it is its turn. If you wanted the game to be two players, you could remove the AIMove() call.

Private Sub menuEasy_Click(ByVal sender _
As System.Object, ByVal e As System.EventArgs) Handles menuEasy.Click
        Call SetDifficulty(Difficulty.Easy)
End Sub ' menuEasy_Click 

For each difficulty level I added the following to the program. These lines use the SetDifficulty subroutine we set up earlier.

Private Sub menuQuit_Click(ByVal sender _
As System.Object, ByVal e As System.EventArgs) Handles menuQuit.Click
        Application.Exit()
End Sub ' menuQuit_Click 

To quit I just used the built-in Application.Exit() function. Wasn't that easy?

Private Sub menuAboutTTT_Click(ByVal sender _
As System.Object, ByVal e As System.EventArgs) Handles menuAboutTTT.Click
        MessageBox.Show("Tic-Tac-Toe v1.0" & vbCrLf & _
                "See how this and other programs work at" & _
                vbCrLf & "https://scratchprojects.com")
End Sub ' menuAboutTTT_Click 

What program would be complete without shameless self-promotion? It pops up with a link to scratchProjects.com when you go to About from the menu.

<< Previous

Next >>