Noughts and Crosses or Tic-Tac-Toe is a very simple game to play and to create. This tutorial features message boxes, arrays and Drawing using Windows Presentation Foundation (WPF).
Printer Friendly Download Tutorial (236KB) Download Source Code (11.8KB)
Step 1
Start Microsoft Visual Basic 2008 Express Edition, then select File then New Project... Choose WPF Application from the New Project Window, enter a name for the Project and then click OK, see below:
Step 2
A Blank Window named Window1 should then appear, see below:
Step 3
Then from the Controls tab on the Toolbox select the Grid component:
Step 4
Draw a Grid on the Window or in the XAML Pane below the "<Grid>" type the following:
<Grid Margin="29,0,29,42" Name="Grid1" />
See below:
Step 5
Select or click on the Grid then goto the Properties box, change the Name to "BoardLayout" without the quotes, see below:
Step 6
Then from the Controls tab on the Toolbox select the Button component:
Step 7
Draw a Button on the Window, by dragging the Button from the Toolbox onto the Window, or in the XAML Pane above the bottom "</Grid>" type the following:
<Button Margin="102,0,100,12" Name="Button1" Height="23" VerticalAlignment="Bottom">Button</Button>
See below:
Step 8
Select or click on the Button (Button1), then goto the Properties box and change the Name to btnNew and the Content property from Button to New Game, see below:
Step 9
Right Click on the Window or the entry for "Window1" in the Solution Explorer and choose the "View Code" option then below "Class Window1" type the following:
Private WithEvents btn1, btn2, btn3, btn4, _ btn5, btn6, btn7, btn8, btn9 As New Button Dim IsCross As Boolean Dim Nought As String = "O" Dim Cross As String = "X" Dim Won As Boolean Dim Board(3, 3) As String
See Below:
Step 10
While still in the Code View for Window1, above "End Class" type the following:
Private Sub Add(ByRef Grid As Grid, ByRef Button As Button, _ ByRef Row As Integer, ByRef Column As Integer) Button.Margin = New Thickness(5) Grid.Children.Add(Button) Grid.SetColumn(Button, Column) Grid.SetRow(Button, Row) End Sub
See Below:
Step 11
Again while still in the Code View for Window1, below the "End Sub" for "Private Sub Add(...)", type the following:
Private Sub Layout(ByRef Grid As Grid) Grid.ColumnDefinitions.Clear() ' Clear Columns Grid.RowDefinitions.Clear() ' Clear Rows Grid.Children.Clear() ' Clear the Grid Grid.ColumnDefinitions.Add(New ColumnDefinition) Grid.ColumnDefinitions.Add(New ColumnDefinition) Grid.ColumnDefinitions.Add(New ColumnDefinition) Grid.RowDefinitions.Add(New RowDefinition) Grid.RowDefinitions.Add(New RowDefinition) Grid.RowDefinitions.Add(New RowDefinition) Add(Grid, btn1, 0, 0) Add(Grid, btn2, 0, 1) Add(Grid, btn3, 0, 2) Add(Grid, btn4, 1, 0) Add(Grid, btn5, 1, 1) Add(Grid, btn6, 1, 2) Add(Grid, btn7, 2, 0) Add(Grid, btn8, 2, 1) Add(Grid, btn9, 2, 2) For Each Button As Button In Grid.Children Button.Content = Nothing ' Clear Buttons Next End Sub
See Below:
Step 12
While still in the Code View for Window1, below the "End Sub" for "Private Sub Layout(...)", type the following:
Private Function GetPiece(ByRef Button As Button) As String If IsCross Then ' Draw X Dim Line1, Line2 As New LineGeometry Dim Lines As New Path Dim LineGroup As New GeometryGroup Line1.StartPoint = New Point(0, 0) Line1.EndPoint = New Point(50, 50) Line2.StartPoint = New Point(50, 0) Line2.EndPoint = New Point(0, 50) LineGroup.Children.Add(Line1) LineGroup.Children.Add(Line2) Lines.Stretch = Stretch.Uniform Lines.Data = LineGroup Lines.Stroke = Brushes.Red Lines.StrokeThickness = 4.0 Lines.Margin = New Thickness(5) Button.Content = Lines Return Cross Else ' Draw O Dim CircleGeo As New _ EllipseGeometry(New Rect(0, 0, 50, 50)) Dim Circle As New Path Circle.Stretch = Stretch.Uniform Circle.Data = CircleGeo Circle.Stroke = Brushes.Blue Circle.StrokeThickness = 4.0 Circle.Margin = New Thickness(5) Button.Content = Circle Return Nought End If End Function
See Below:
Step 13
Again while still in the Code View for Window1, below the "End Function" for "Private Function GetPiece(...)", type the following:
Private Sub SetPiece(ByRef Grid As Grid, ByRef Button As Button) Dim Piece As String If Button.Content Is Nothing Then Piece = GetPiece(Button) Board(Grid.GetRow(Button), Grid.GetColumn(Button)) = Piece End If End Sub
See Below:
Step 14
While still in the Code View for Window1, below the "End Sub" for "Private Sub SetPiece(...)", type the following:
Private Sub NewGame() Dim Result As MsgBoxResult Dim Piece As String Layout(BoardLayout) ' Reset Grid Board(0, 0) = "" Board(0, 1) = "" Board(0, 2) = "" Board(1, 0) = "" Board(1, 1) = "" Board(1, 2) = "" Board(2, 0) = "" Board(2, 1) = "" Board(2, 2) = "" Won = False Result = MsgBox(Cross & " goes first?", _ MsgBoxStyle.Question + MsgBoxStyle.YesNo, _ "Noughts and Crosses") If Result = MsgBoxResult.Yes Then IsCross = True Piece = Cross Else IsCross = False Piece = Nought End If Me.Title = "Player:" & Piece End Sub
See Below:
Step 15
Again while still in the Code View for Window1, below the "End Sub" for "Private Sub NewGame()", type the following Function and Sub:
Private Function CheckWinner(ByRef Player As String) As Boolean If (Board(0, 0) = Player And Board(0, 1) = Player And Board(0, 2) = Player) Or _ (Board(1, 0) = Player And Board(1, 1) = Player And Board(1, 2) = Player) Or _ (Board(2, 0) = Player And Board(2, 1) = Player And Board(2, 2) = Player) Or _ (Board(0, 0) = Player And Board(1, 0) = Player And Board(2, 0) = Player) Or _ (Board(0, 1) = Player And Board(1, 1) = Player And Board(2, 1) = Player) Or _ (Board(0, 2) = Player And Board(1, 2) = Player And Board(2, 2) = Player) Or _ (Board(0, 0) = Player And Board(1, 1) = Player And Board(2, 2) = Player) Or _ (Board(0, 2) = Player And Board(1, 1) = Player And Board(2, 0) = Player) Then Return True End If End Function Private Sub CheckDraw() If Board(0, 0) <> "" And Board(0, 1) <> "" And Board(0, 2) <> "" _ And Board(1, 0) <> "" And Board(1, 1) <> "" And Board(1, 2) <> "" _ And Board(2, 0) <> "" And Board(2, 1) <> "" And Board(2, 2) <> "" Then If Not Won Then MsgBox("Draw!", MsgBoxStyle.Information, "Noughts and Crosses") Me.Title = "Draw!" NewGame() End If End If End Sub
See Below:
Step 16
Finally while still in the Code View for Window1, below the "End Sub" for "Private Sub CheckDraw()", type the following:
Private Sub OnClick(ByVal sender As System.Object, _ ByVal e As System.Windows.RoutedEventArgs) _ Handles btn1.Click, btn2.Click, btn3.Click, _ btn4.Click, btn5.Click, btn6.Click, btn7.Click, _ btn8.Click, btn9.Click Dim Piece As String = "" If Not Won Then SetPiece(BoardLayout, sender) If CheckWinner(Cross) Then Piece = Cross ElseIf CheckWinner(Nought) Then Piece = Nought End If If Piece <> "" Then Won = True MsgBox("Player " & Piece & " Won!", _ MsgBoxStyle.Information, "Noughts and Crosses") End If CheckDraw() IsCross = Not IsCross If IsCross Then Me.Title = "Player:" & Cross Else Me.Title = "Player:" & Nought End If Else MsgBox("Game Over!", _ MsgBoxStyle.Exclamation, "Noughts and Crosses") NewGame() End If End Sub
See Below:
Step 17
Return to the Design view by selecting the [Design] tab or Right Click on the "View Designer" option in Solution Explorer for Window1. Double Click on the "New Game" Button (btnNew) and type the following in the btnNew_Click() Sub:
NewGame()
See Below:
Step 18
While still in Code View, if not Right Click on the Window or the entry for "Window1" in the Solution Explorer and choose "View Code". The top of this window will have two drop-down boxes one with "(General)" in and the other "(Declarations)", click on the first and select the "(Window1 Events)" Option, then from the drop-down next to this select "Loaded", type the following in the Window1_Loaded Sub:
NewGame()
See Below:
Step 19
Save the Project as you have now finished the application, then click on Start:
When you do it will ask "X goes first?", choose either Yes or No, and the following will appear:
Step 20
Click on the Buttons to place a O or an X continue until you Win, Lose or Draw, see below:
Step 21
Click on the Close button on the top right of Window1 to end the application.
This is a very simple game written using Visual Basic 2008 Express Edition, feel free to amend the game as you with, including writing a Computer-based Player 2, try to beat the computer using random numbers, or change the colours of the Noughts and Crosses, plus try resizing the window and see what happens!