tictactoe
Overview
Tictactoe (also known as noughts and crosses) is a two player game, in this case you versus your computer. In this version there are no levels of difficulty, and it is very tough to beat.
I originally wrote this game in Java, but I decided to convert it to C# and then to VB.Net, to share it here on MSDN. The Java code is very similar to very simple C#, so it was fairly easily converted, but it is simple C# (and VB), containing no LINQ, and as such it will, within my knowledge, work in any version of VS from 2005-13 (and probably earlier too).
To play, you just click a cell. When it is the computer’s turn to play, the game grid is strategically assessed and each cell is assigned a priority value according to its strategic value in the game. After rating all of the cells, the computer plays either the highest rated cell, or in the case of jointly rated cells, a random cell chosen from the joint highest rated cells. The used cells will never be chosen in this decision making algorithm as they are always assigned a rating of -1 which will always make them the lowest rated cells.
This has been a fun program to write, and converting between languages always leads to greater understanding and programming knowledge.
The code –The Form
The form code is very simple. Just a Button_Click event is handled...
Public Class game
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
Grid1.newGame()
End Sub
End Class
The code – cell Class
The cell Class is again very simple, just holding 3 member variables...
Public Class cell
Public display As Char = " "c
Public color As Color = Color.Black
Public priority As Integer = -1
End Class
**The code –grid Class **
The grid Class inherits from Panel – it is an extended Panel. It holds some Class level variables that are used throughout the Class during game play...
Private matrix As cell()() = New cell(2)() {}
Private first As Char = "X"c
Private current As Char = "X"c
Private gameOver As Boolean = False
Private moveCounter As Integer = 0
Sub new sets the size of the Panel and initializes the matrix array...
Public Sub New()
Me.Size = New Size(210, 210)
For r As Integer = 0 To 2
matrix(r) = New cell(2) {}
Next
For r As Integer = 0 To 2
For c As Integer = 0 To 2
matrix(r)(c) = New cell()
matrix(r)(c).display = " "c
matrix(r)(c).color = Color.Black
Next
Next
End Sub
There are two overridden events handled in the extended Panel Class. These are the MouseClick event and the Paint event...
Protected Overrides Sub OnMouseClick(e As System.Windows.Forms.MouseEventArgs)
If Not gameOver Then
Dim r As Integer = CInt(Math.Floor(CDbl(e.Y) / 70))
Dim c As Integer = CInt(Math.Floor(CDbl(e.X) / 70))
If matrix(r)(c).display = " "c Then
matrix(r)(c).display = current
current = "0"c
Me.Invalidate()
moveCounter += 1
gameOver = checkLines()
If Not gameOver AndAlso moveCounter < 9 Then
playMove()
moveCounter += 1
End If
End If
End If
MyBase.OnMouseClick(e)
End Sub
Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
e.Graphics.DrawLine(Pens.Black, 70, 0, 70, 210)
e.Graphics.DrawLine(Pens.Black, 140, 0, 140, 210)
e.Graphics.DrawLine(Pens.Black, 0, 70, 210, 70)
e.Graphics.DrawLine(Pens.Black, 0, 140, 210, 140)
For r As Integer = 0 To 2
For c As Integer = 0 To 2
If matrix(r)(c).display <> " "c Then
e.Graphics.DrawString(matrix(r)(c).display.ToString(), New Font("Times New Roman", 20, FontStyle.Bold), New SolidBrush(matrix(r)(c).color), CSng((c * 70) + 25), CSng((r * 70) + 25))
End If
Next
Next
End Sub
The newGame procedure resets the Class level variables for a new game...
Public Sub newGame()
gameOver = False
For r As Integer = 0 To 2
For c As Integer = 0 To 2
matrix(r)(c).display = " "c
matrix(r)(c).color = Color.Black
Next
Next
first = If((first = "X"c), "0"c, "X"c)
current = first
Me.Invalidate()
moveCounter = 0
If current = "0"c Then
playMove()
End If
End Sub
The playMove procedure is the AI part of this program, where the computer chooses its move...
Public Sub playMove()
For r As Integer = 0 To 2
For c As Integer = 0 To 2
If matrix(r)(c).display = " "c Then
matrix(r)(c).priority = 0
Else
matrix(r)(c).priority = -1
End If
Next
Next
If matrix(1)(1).display = " "c Then
matrix(1)(1).priority = 2
End If
If matrix(0)(0).display = " "c Then
matrix(0)(0).priority = 1
End If
If matrix(0)(2).display = " "c Then
matrix(0)(2).priority = 1
End If
If matrix(2)(0).display = " "c Then
matrix(2)(0).priority = 1
End If
If matrix(2)(2).display = " "c Then
matrix(2)(2).priority = 1
End If
For r As Integer = 0 To 2
If matrix(r)(0).display <> " "c AndAlso matrix(r)(0).display = matrix(r)(1).display AndAlso matrix(r)(2).display = " "c Then
matrix(r)(2).priority += 3
End If
If matrix(r)(0).display <> " "c AndAlso matrix(r)(0).display = matrix(r)(2).display AndAlso matrix(r)(1).display = " "c Then
matrix(r)(1).priority += 3
End If
If matrix(r)(1).display <> " "c AndAlso matrix(r)(1).display = matrix(r)(2).display AndAlso matrix(r)(0).display = " "c Then
matrix(r)(0).priority += 3
End If
Next
For c As Integer = 0 To 2
If matrix(0)(c).display <> " "c AndAlso matrix(0)(c).display = matrix(1)(c).display AndAlso matrix(2)(c).display = " "c Then
matrix(2)(c).priority += 3
End If
If matrix(0)(c).display <> " "c AndAlso matrix(0)(c).display = matrix(2)(c).display AndAlso matrix(1)(c).display = " "c Then
matrix(1)(c).priority += 3
End If
If matrix(1)(c).display <> " "c AndAlso matrix(1)(c).display = matrix(2)(c).display AndAlso matrix(0)(c).display = " "c Then
matrix(0)(c).priority += 3
End If
Next
If matrix(0)(0).display <> " "c AndAlso matrix(0)(0).display = matrix(1)(1).display AndAlso matrix(2)(2).display = " "c Then
matrix(2)(2).priority += 3
End If
If matrix(0)(0).display <> " "c AndAlso matrix(0)(0).display = matrix(2)(2).display AndAlso matrix(1)(1).display = " "c Then
matrix(1)(1).priority += 3
End If
If matrix(1)(1).display <> " "c AndAlso matrix(1)(1).display = matrix(2)(2).display AndAlso matrix(0)(0).display = " "c Then
matrix(0)(0).priority += 3
End If
If matrix(0)(2).display <> " "c AndAlso matrix(0)(2).display = matrix(1)(1).display AndAlso matrix(2)(0).display = " "c Then
matrix(2)(0).priority += 3
End If
If matrix(0)(2).display <> " "c AndAlso matrix(0)(2).display = matrix(2)(0).display AndAlso matrix(1)(1).display = " "c Then
matrix(1)(1).priority += 3
End If
If matrix(1)(1).display <> " "c AndAlso matrix(1)(1).display = matrix(2)(0).display AndAlso matrix(0)(2).display = " "c Then
matrix(0)(2).priority += 3
End If
'int maxC=-1;
Dim maxC As New List(Of Integer)()
'int maxR=-1;
Dim maxR As New List(Of Integer)()
Dim maxPriority As Integer = -1
For r As Integer = 0 To 2
For c As Integer = 0 To 2
If matrix(r)(c).priority > maxPriority Then
maxPriority = matrix(r)(c).priority
End If
Next
Next
For r As Integer = 0 To 2
For c As Integer = 0 To 2
If matrix(r)(c).priority = maxPriority Then
maxC.Add(c)
maxR.Add(r)
End If
Next
Next
Dim rnd As New Random()
Dim index As Integer = rnd.[Next](maxC.Count())
matrix(maxR(index))(maxC(index)).display = "0"c
current = "X"c
gameOver = checkLines()
Me.Invalidate()
End Sub
Finally the checkLines Function, which checks for a win in any of the eight possible lines.
This returns a Boolean True or False depending on the state of play. Also any winning line is highlighted with red text...
Public Function checkLines() As Boolean
For r As Integer = 0 To 2
If matrix(r)(0).display <> " "c AndAlso matrix(r)(0).display = matrix(r)(1).display AndAlso matrix(r)(0).display = matrix(r)(2).display Then
matrix(r)(0).color = Color.Red
matrix(r)(1).color = Color.Red
matrix(r)(2).color = Color.Red
Return True
End If
Next
For c As Integer = 0 To 2
If matrix(0)(c).display <> " "c AndAlso matrix(0)(c).display = matrix(1)(c).display AndAlso matrix(0)(c).display = matrix(2)(c).display Then
matrix(0)(c).color = Color.Red
matrix(1)(c).color = Color.Red
matrix(2)(c).color = Color.Red
Return True
End If
Next
If matrix(0)(0).display <> " "c AndAlso matrix(0)(0).display = matrix(1)(1).display AndAlso matrix(0)(0).display = matrix(2)(2).display Then
matrix(0)(0).color = Color.Red
matrix(1)(1).color = Color.Red
matrix(2)(2).color = Color.Red
Return True
End If
If matrix(0)(2).display <> " "c AndAlso matrix(0)(2).display = matrix(1)(1).display AndAlso matrix(0)(2).display = matrix(2)(0).display Then
matrix(0)(2).color = Color.Red
matrix(1)(1).color = Color.Red
matrix(2)(0).color = Color.Red
Return True
End If
Return False
End Function
**See Also **
Download: here
C# 2013 version
Play online
Articles related to game programming
VB.Net - WordSearch
VB.Net - Vertex
VB.Net - Perspective
VB.Net - MasterMind
VB.Net - OOP BlackJack
VB.Net - Numbers Game
VB.Net - HangMan
Console BlackJack - VB.Net | C#
OOP Conway's Game of Life - VB.Net | C#
OOP Sudoku - VB.Net | C#
OctoWords VB.Net | C#
OOP Buttons Guessing Game VB.Net | C#
OOP Tangram Shapes Game VB.Net | C#
VB.Net - Three-card Monte
VB.Net - Split Decisions
VB.Net - Pascal's Pyramid
VB.Net - Random Maze Games
(Office) Wordsearch Creator
VB.Net - Event Driven Programming - LockWords Game
C# - Crack the Lock
VB.Net - Totris