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.
- Creating the User Interface
- Starting a Game and Making a Menu
- Programming the Game Logic
- 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.