# Visual Basic > Games and Graphics Programming > Game Demos >  [VB.Net] TicTacToe

## dday9

This is the source code and the .exe.

Features: 
-Player V Player
-Player V CPU
-Reset Score
-Give up

Notes:
-I accenditally deleted all of my stuff, so I'm trying to rebuild everything I deleted. This was the first thing.

Full Project:
tic-tac-toe.zip

Source:


```
Option Strict On
Option Explicit On
Public Class Form1
    Private grid(2, 2) As Panel
    Private p1turn As Boolean
    Private r As New Random

#Region "New/End game"

    Private Sub newgame()
        For i As Integer = pnl_Grid.Controls.Count - 1 To 0 Step -1
            pnl_Grid.Controls.RemoveAt(i)
        Next

        For x As Integer = 0 To 2
            For y As Integer = 0 To 2
                Dim pnl As New Panel
                With pnl
                    .BackgroundImage = Nothing
                    .BackgroundImageLayout = ImageLayout.Zoom
                    .BorderStyle = BorderStyle.FixedSingle
                    .Enabled = True
                    .Location = New Point(x * 100, y * 100)
                    .Size = New Size(100, 100)
                    .Tag = ""
                End With

                pnl_Grid.Controls.Add(pnl)
                grid(x, y) = pnl

                AddHandler pnl.Click, AddressOf pnl_Click
            Next
        Next

        p1turn = True
    End Sub

    Private Function checkend() As Boolean

        'Horizontal
        If grid(0, 0).Tag.ToString = "p1" AndAlso grid(1, 0).Tag.ToString = "p1" AndAlso grid(2, 0).Tag.ToString = "p1" Then
            MessageBox.Show("Player1 wins")
            Call newgame()
            Return True
        ElseIf grid(0, 0).Tag.ToString = "p2" AndAlso grid(1, 0).Tag.ToString = "p2" AndAlso grid(2, 0).Tag.ToString = "p2" Then
            MessageBox.Show("Player2 wins")
            Call newgame()
            Return True
        ElseIf grid(0, 1).Tag.ToString = "p1" AndAlso grid(1, 1).Tag.ToString = "p1" AndAlso grid(2, 1).Tag.ToString = "p1" Then
            MessageBox.Show("Player1 wins")
            Call newgame()
            Return True
        ElseIf grid(0, 1).Tag.ToString = "p2" AndAlso grid(1, 1).Tag.ToString = "p2" AndAlso grid(2, 1).Tag.ToString = "p2" Then
            MessageBox.Show("Player2 wins")
            Call newgame()
            Return True
        ElseIf grid(0, 2).Tag.ToString = "p1" AndAlso grid(1, 2).Tag.ToString = "p1" AndAlso grid(2, 2).Tag.ToString = "p1" Then
            MessageBox.Show("Player1 wins")
            Call newgame()
            Return True
        ElseIf grid(0, 2).Tag.ToString = "p2" AndAlso grid(1, 2).Tag.ToString = "p2" AndAlso grid(2, 2).Tag.ToString = "p2" Then
            MessageBox.Show("Player2 wins")
            Call newgame()
            Return True

            'Horizontal
        ElseIf grid(0, 0).Tag.ToString = "p1" AndAlso grid(0, 1).Tag.ToString = "p1" AndAlso grid(0, 2).Tag.ToString = "p1" Then
            MessageBox.Show("Player1 wins")
            Call newgame()
            Return True
        ElseIf grid(0, 0).Tag.ToString = "p2" AndAlso grid(0, 1).Tag.ToString = "p2" AndAlso grid(0, 2).Tag.ToString = "p2" Then
            MessageBox.Show("Player2 wins")
            Call newgame()
            Return True
        ElseIf grid(1, 0).Tag.ToString = "p1" AndAlso grid(1, 1).Tag.ToString = "p1" AndAlso grid(1, 2).Tag.ToString = "p1" Then
            MessageBox.Show("Player1 wins")
            Call newgame()
            Return True
        ElseIf grid(1, 0).Tag.ToString = "p2" AndAlso grid(1, 1).Tag.ToString = "p2" AndAlso grid(1, 2).Tag.ToString = "p2" Then
            MessageBox.Show("Player2 wins")
            Call newgame()
            Return True
        ElseIf grid(2, 0).Tag.ToString = "p1" AndAlso grid(2, 1).Tag.ToString = "p1" AndAlso grid(2, 2).Tag.ToString = "p1" Then
            MessageBox.Show("Player1 wins")
            Call newgame()
            Return True
        ElseIf grid(2, 0).Tag.ToString = "p2" AndAlso grid(2, 1).Tag.ToString = "p2" AndAlso grid(2, 2).Tag.ToString = "p2" Then
            MessageBox.Show("Player2 wins")
            Call newgame()
            Return True

            'Diagonal
        ElseIf grid(0, 0).Tag.ToString = "p1" AndAlso grid(1, 1).Tag.ToString = "p1" AndAlso grid(2, 2).Tag.ToString = "p1" Then
            MessageBox.Show("Player1 wins")
            Call newgame()
            Return True
        ElseIf grid(0, 0).Tag.ToString = "p2" AndAlso grid(1, 1).Tag.ToString = "p2" AndAlso grid(2, 2).Tag.ToString = "p2" Then
            MessageBox.Show("Player2 wins")
            Call newgame()
            Return True
        ElseIf grid(0, 2).Tag.ToString = "p1" AndAlso grid(1, 1).Tag.ToString = "p1" AndAlso grid(2, 0).Tag.ToString = "p1" Then
            MessageBox.Show("Player1 wins")
            Call newgame()
            Return True
        ElseIf grid(0, 2).Tag.ToString = "p2" AndAlso grid(1, 1).Tag.ToString = "p2" AndAlso grid(2, 0).Tag.ToString = "p2" Then
            MessageBox.Show("Player2 wins")
            Call newgame()
            Return True
        Else

            Return False
        End If

    End Function

#End Region

#Region "Draw Bitmap and AI"

    Private Function drawpiece() As Bitmap
        drawpiece = New Bitmap(50, 50)
        Dim g As Graphics = Graphics.FromImage(drawpiece)

        'p1 is x
        'cpu is o
        If p1turn Then
            Dim pt1, pt2, pt3, pt4 As Point
            pt1 = New Point(1, 1) 'Upper-Left
            pt2 = New Point(49, 49) 'Lower-Right
            pt3 = New Point(1, 49) 'Lower-Left
            pt4 = New Point(49, 1) 'Upper-Right

            g.DrawLine(Pens.Red, pt1, pt2)
            g.DrawLine(Pens.Red, pt3, pt4)

            g.Save()
        Else
            Dim rect As New Rectangle(1, 1, 48, 48)
            g.DrawEllipse(Pens.Blue, rect)
            g.Save()
        End If

        Return drawpiece
    End Function

    Private Function rndPanel() As Panel
        Dim i As Integer = 0
        Dim templist As New List(Of Panel)

        For Each pnl As Panel In pnl_Grid.Controls.OfType(Of Panel)()
            If pnl.Enabled = True Then
                i += 1
                templist.Add(pnl)
            End If
        Next

        rndPanel = templist.Item(r.Next(0, i))

        Return rndPanel
    End Function

#End Region

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Call newgame()
    End Sub

    Private Sub pnl_Click(sender As Object, e As EventArgs)
        Dim pnl As Panel = DirectCast(sender, Panel)
        pnl.BackgroundImage = drawpiece() : pnl.Tag = "p1" : pnl.Enabled = False
        p1turn = False

        If checkend() = True Then
            Exit Sub
        End If

        Dim randpnl As Panel = rndPanel()
        randpnl.BackgroundImage = drawpiece() : randpnl.Tag = "p2" : randpnl.Enabled = False
        p1turn = True

        If checkend() = True Then
            Exit Sub
        End If
    End Sub

End Class
```

Update
See post 8 & 9

----------


## dday9

One thing that I forgot to do when I updated the code was in the resetGame sub I would change typing out all that button.whatever to:


```
For Each Button In Panel1.Controls.OfType(Of Button)()
            Button.Enabled = True
            Button.Text = String.Empty
        Next
```

I was more focused on working with ai rather than coding basics. Just a little tit tat from me.


Edit - Also, take a look at this function if you want the moves to be much more random:


```
Private Function randomBtn() As Button
        Dim list As New List(Of Button)
        For Each btn As Button In Panel1.Controls.OfType(Of Button)()
            If btn.Enabled = True Then
                list.Add(btn)
            End If
        Next
        Dim r As New Random
        Dim i As Integer
        i = r.Next(0, list.Count - 1)
        randomBtn = list.Item(i)

    End Function
```

then in the ai sub, simply comment(or delete) everything in it and replace it with:


```
If player1Turn = False Then
            randomBtn.PerformClick()
            player1Turn = True
        End If
```

----------


## HunterTTP

Maybe for the AI, have the program detect which buttons have already been used; then just have it pick one of the buttons that haven't been used. The only hard part with this is having it "pick". It could randomly generate a number between 1 and 9, (lets say it picks 7) then it checks if button 7 is already occupied, if it is, it generates a new random number (over and over again).

----------


## dday9

Basically what the edit does in my edit in post #2, is it puts all buttons in the panel that aren't enabled into a list and then choose a random button from there. The problem with that is that if there is an obvious win for player1, the ai may not block it.

----------


## dday9

*UPDATE*
I've made a pretty major update. I've replaced the buttons with panels and draw the x's and o's on the panels. Also there is a difficulty setting and statistics dialog now:

Game:
Attachment 95043

Difficulty:
Attachment 95039

Stats:
Attachment 95041

Game Zip:
Attachment 95045

----------


## .paul.

I wrote a java version. When the PC moves, it first grades all available cells, then chooses randomly from the most advantageous cells. 
It's very difficult to beat. I might rewrite it in .net

----------


## dday9

> I wrote a java version. When the PC moves, it first grades all available cells, then chooses randomly from the most advantageous cells. 
> It's very difficult to beat. I might rewrite it in .net


It's been a while since I've written this, but I think that is how I do it as well. Then again, I wrote this so long ago who knows :P

----------


## dday9

Here is an updated version. I've had to break it up into 2 pieces because of the character limit on Vbforums:


```
Option Strict On
Option Explicit On
Public Class Form1
    'Controls
    Private btnEasy, btnMed, btnHard As Button
    Private lblLoses, lblWins, lblCats As Label
    Private pnlUpperLeft, pnlUpperMiddle, pnlUpperRight As Panel
    Private pnlCenterLeft, pnlCenterMiddle, pnlCenterRight As Panel
    Private pnlLowerLeft, pnlLowerMiddle, pnlLowerRight As Panel

    'Globals
    Private availablePnls As List(Of Panel)
    Private difficulty As Integer
    Private playerTurn As Boolean
    Private r As Random

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'Set the globals
        availablePnls = New List(Of Panel)
        r = New Random

        'Set the form's properties
        With Me
            .ClientSize = New Size(400, 300)
            .StartPosition = FormStartPosition.CenterScreen
            .Text = "Tic Tac Toe"
        End With

        'Create the buttons
        btnEasy = New Button With {.Size = New Size(75, 25), .Left = Me.ClientSize.Width - .Width - 5, .Text = "Easy", .Top = 5}
        btnMed = New Button With {.Left = btnEasy.Left, .Text = "Medium", .Top = btnEasy.Bottom + 5}
        btnHard = New Button With {.Left = btnEasy.Left, .Text = "Hard", .Top = btnMed.Bottom + 5}

        'Create the labels
        lblLoses = New Label With {.AutoSize = True, .Location = New Point(5, 5), .Text = "Loses: 0", .Tag = 0}
        lblWins = New Label With {.AutoSize = lblLoses.AutoSize, .Left = lblLoses.Right + 2, .Text = "Wins: 0", .Tag = 0, .Top = lblLoses.Top}
        lblCats = New Label With {.AutoSize = lblLoses.AutoSize, .Left = lblWins.Right + 2, .Text = "Cats: 0", .Tag = 0, .Top = lblLoses.Top}

        'Create the panels
        pnlUpperLeft = New Panel With {.BackColor = Color.White, .BorderStyle = BorderStyle.FixedSingle, .Left = lblLoses.Left, .Top = lblLoses.Bottom + 5, .Size = New Size(50, 50), .Tag = String.Empty}
        pnlUpperMiddle = New Panel With {.BackColor = pnlUpperLeft.BackColor, .BorderStyle = pnlUpperLeft.BorderStyle, .Left = pnlUpperLeft.Right, .Size = pnlUpperLeft.Size, .Tag = String.Empty, .Top = pnlUpperLeft.Top}
        pnlUpperRight = New Panel With {.BackColor = pnlUpperLeft.BackColor, .BorderStyle = pnlUpperLeft.BorderStyle, .Left = pnlUpperMiddle.Right, .Size = pnlUpperLeft.Size, .Tag = String.Empty, .Top = pnlUpperLeft.Top}

        pnlCenterLeft = New Panel With {.BackColor = pnlUpperLeft.BackColor, .BorderStyle = pnlUpperLeft.BorderStyle, .Left = pnlUpperLeft.Left, .Size = pnlUpperLeft.Size, .Tag = String.Empty, .Top = pnlUpperLeft.Bottom}
        pnlCenterMiddle = New Panel With {.BackColor = pnlUpperLeft.BackColor, .BorderStyle = pnlUpperLeft.BorderStyle, .Left = pnlCenterLeft.Right, .Size = pnlUpperLeft.Size, .Tag = String.Empty, .Top = pnlCenterLeft.Top}
        pnlCenterRight = New Panel With {.BackColor = pnlUpperLeft.BackColor, .BorderStyle = pnlUpperLeft.BorderStyle, .Left = pnlCenterMiddle.Right, .Size = pnlUpperLeft.Size, .Tag = String.Empty, .Top = pnlCenterLeft.Top}

        pnlLowerLeft = New Panel With {.BackColor = pnlUpperLeft.BackColor, .BorderStyle = pnlUpperLeft.BorderStyle, .Left = pnlUpperLeft.Left, .Size = pnlUpperLeft.Size, .Tag = String.Empty, .Top = pnlCenterLeft.Bottom}
        pnlLowerMiddle = New Panel With {.BackColor = pnlUpperLeft.BackColor, .BorderStyle = pnlUpperLeft.BorderStyle, .Left = pnlLowerLeft.Right, .Size = pnlUpperLeft.Size, .Tag = String.Empty, .Top = pnlLowerLeft.Top}
        pnlLowerRight = New Panel With {.BackColor = pnlUpperLeft.BackColor, .BorderStyle = pnlUpperLeft.BorderStyle, .Left = pnlLowerMiddle.Right, .Size = pnlUpperLeft.Size, .Tag = String.Empty, .Top = pnlLowerLeft.Top}

        'Add the controls
        Me.Controls.AddRange({btnEasy, btnMed, btnHard, lblLoses, lblWins, lblCats, pnlUpperLeft, pnlUpperMiddle, pnlUpperRight, pnlCenterLeft, pnlCenterMiddle, pnlCenterRight, pnlLowerLeft, pnlLowerMiddle, pnlLowerRight})

        'Create the click events
        AddHandler btnEasy.Click, AddressOf btnEasy_Click
        AddHandler btnMed.Click, AddressOf btnMed_Click
        AddHandler btnHard.Click, AddressOf btnHard_Click

        AddHandler pnlUpperLeft.Click, AddressOf pnl_Click
        AddHandler pnlUpperMiddle.Click, AddressOf pnl_Click
        AddHandler pnlUpperRight.Click, AddressOf pnl_Click
        AddHandler pnlCenterLeft.Click, AddressOf pnl_Click
        AddHandler pnlCenterMiddle.Click, AddressOf pnl_Click
        AddHandler pnlCenterRight.Click, AddressOf pnl_Click
        AddHandler pnlLowerLeft.Click, AddressOf pnl_Click
        AddHandler pnlLowerMiddle.Click, AddressOf pnl_Click
        AddHandler pnlLowerRight.Click, AddressOf pnl_Click

        'default difficulty is easy
        difficulty = 0
        Call NewGame(difficulty)
    End Sub

    Private Sub btnEasy_Click(ByVal sender As Object, ByVal e As EventArgs)
        If availablePnls.Count = 9 Then
            Call NewGame(0)
        Else

        End If
    End Sub

    Private Sub btnMed_Click(ByVal sender As Object, ByVal e As EventArgs)
        If availablePnls.Count = 9 Then
            Call NewGame(1)
        Else

        End If
    End Sub

    Private Sub btnHard_Click(ByVal sender As Object, ByVal e As EventArgs)
        If availablePnls.Count = 9 Then
            Call NewGame(2)
        Else

        End If
    End Sub

    Private Sub pnl_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim clickedPanel As Panel = DirectCast(sender, Panel)
        If clickedPanel.Enabled Then
            With clickedPanel
                .BackgroundImage = Me.DrawShape()
                .Enabled = False
                .Tag = If(playerTurn, "x", "o")
            End With

            playerTurn = Not playerTurn
            availablePnls.Remove(clickedPanel)
            Call CheckEndGame()
        End If
    End Sub

    Private Sub NewGame(ByVal level As Integer)
        availablePnls.Clear()
        difficulty = level
        playerTurn = True

        availablePnls.AddRange({pnlUpperLeft, pnlUpperMiddle, pnlUpperRight, pnlCenterLeft, pnlCenterMiddle, pnlCenterRight, pnlLowerLeft, pnlLowerMiddle, pnlLowerRight})
        For Each pnl As Panel In availablePnls
            With pnl
                .BackgroundImage = Nothing
                .Enabled = True
                .Tag = String.Empty
            End With
        Next
    End Sub

    Private Function DrawShape() As Bitmap
        Dim b As Bitmap = New Bitmap(pnlUpperLeft.Width, pnlUpperRight.Height)

        Using g As Graphics = Graphics.FromImage(b)

            If playerTurn Then
                'Draw a red X
                Using xBrush As Pen = New Pen(Color.Red)
                    g.DrawLine(xBrush, New Point(0, 0), New Point(b.Width, b.Height))
                    g.DrawLine(xBrush, New Point(0, b.Height), New Point(b.Width, 0))
                End Using

            Else
                'Draw a blue O
                Using oBrush As Pen = New Pen(Color.Blue)
                    g.DrawEllipse(oBrush, New Rectangle(0, 0, b.Width - 2, b.Height - 2))
                End Using

            End If

            g.Save()
        End Using

        Return b
    End Function
```

----------


## dday9

Continued...


```
    Private Sub CheckEndGame()

        If pnlUpperLeft.Tag.ToString = "x" AndAlso pnlUpperMiddle.Tag.ToString = "x" AndAlso pnlUpperRight.Tag.ToString = "x" Then
            lblWins.Tag = CInt(lblWins.Tag) + 1
            lblWins.Text = "Wins: " & lblWins.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlUpperLeft.Tag.ToString = "o" AndAlso pnlUpperMiddle.Tag.ToString = "o" AndAlso pnlUpperRight.Tag.ToString = "o" Then
            lblLoses.Tag = CInt(lblLoses.Tag) + 1
            lblLoses.Text = "Loses: " & lblLoses.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlCenterLeft.Tag.ToString = "x" AndAlso pnlCenterMiddle.Tag.ToString = "x" AndAlso pnlCenterRight.Tag.ToString = "x" Then
            lblWins.Tag = CInt(lblWins.Tag) + 1
            lblWins.Text = "Wins: " & lblWins.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlCenterLeft.Tag.ToString = "o" AndAlso pnlCenterMiddle.Tag.ToString = "o" AndAlso pnlCenterRight.Tag.ToString = "o" Then
            lblLoses.Tag = CInt(lblLoses.Tag) + 1
            lblLoses.Text = "Loses: " & lblLoses.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlLowerLeft.Tag.ToString = "x" AndAlso pnlLowerMiddle.Tag.ToString = "x" AndAlso pnlLowerRight.Tag.ToString = "x" Then
            lblWins.Tag = CInt(lblWins.Tag) + 1
            lblWins.Text = "Wins: " & lblWins.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlLowerLeft.Tag.ToString = "o" AndAlso pnlLowerMiddle.Tag.ToString = "o" AndAlso pnlLowerRight.Tag.ToString = "o" Then
            lblLoses.Tag = CInt(lblLoses.Tag) + 1
            lblLoses.Text = "Loses: " & lblLoses.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlUpperLeft.Tag.ToString = "x" AndAlso pnlCenterLeft.Tag.ToString = "x" AndAlso pnlLowerLeft.Tag.ToString = "x" Then
            lblWins.Tag = CInt(lblWins.Tag) + 1
            lblWins.Text = "Wins: " & lblWins.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlUpperLeft.Tag.ToString = "o" AndAlso pnlCenterLeft.Tag.ToString = "o" AndAlso pnlLowerLeft.Tag.ToString = "o" Then
            lblLoses.Tag = CInt(lblLoses.Tag) + 1
            lblLoses.Text = "Loses: " & lblLoses.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlUpperMiddle.Tag.ToString = "x" AndAlso pnlCenterMiddle.Tag.ToString = "x" AndAlso pnlLowerMiddle.Tag.ToString = "x" Then
            lblWins.Tag = CInt(lblWins.Tag) + 1
            lblWins.Text = "Wins: " & lblWins.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlUpperMiddle.Tag.ToString = "o" AndAlso pnlCenterMiddle.Tag.ToString = "o" AndAlso pnlLowerMiddle.Tag.ToString = "o" Then
            lblLoses.Tag = CInt(lblLoses.Tag) + 1
            lblLoses.Text = "Loses: " & lblLoses.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlUpperRight.Tag.ToString = "x" AndAlso pnlCenterRight.Tag.ToString = "x" AndAlso pnlLowerRight.Tag.ToString = "x" Then
            lblWins.Tag = CInt(lblWins.Tag) + 1
            lblWins.Text = "Wins: " & lblWins.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlUpperRight.Tag.ToString = "o" AndAlso pnlCenterRight.Tag.ToString = "o" AndAlso pnlLowerRight.Tag.ToString = "o" Then
            lblLoses.Tag = CInt(lblLoses.Tag) + 1
            lblLoses.Text = "Loses: " & lblLoses.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlUpperLeft.Tag.ToString = "x" AndAlso pnlCenterMiddle.Tag.ToString = "x" AndAlso pnlLowerRight.Tag.ToString = "x" Then
            lblWins.Tag = CInt(lblWins.Tag) + 1
            lblWins.Text = "Wins: " & lblWins.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlUpperLeft.Tag.ToString = "o" AndAlso pnlCenterMiddle.Tag.ToString = "o" AndAlso pnlLowerRight.Tag.ToString = "o" Then
            lblLoses.Tag = CInt(lblLoses.Tag) + 1
            lblLoses.Text = "Loses: " & lblLoses.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlUpperRight.Tag.ToString = "x" AndAlso pnlCenterMiddle.Tag.ToString = "x" AndAlso pnlLowerLeft.Tag.ToString = "x" Then
            lblWins.Tag = CInt(lblWins.Tag) + 1
            lblWins.Text = "Wins: " & lblWins.Tag.ToString
            Call NewGame(difficulty)
        ElseIf pnlUpperRight.Tag.ToString = "o" AndAlso pnlCenterMiddle.Tag.ToString = "o" AndAlso pnlLowerLeft.Tag.ToString = "o" Then
            lblLoses.Tag = CInt(lblLoses.Tag) + 1
            lblLoses.Text = "Loses: " & lblLoses.Tag.ToString
            Call NewGame(difficulty)
        ElseIf availablePnls.Count = 0 Then
            lblCats.Tag = CInt(lblCats.Tag) + 1
            lblCats.Text = "Cats: " & lblCats.Tag.ToString
            Call NewGame(difficulty)
        ElseIf Not playerTurn Then
            Call AI()
        End If

    End Sub

    Private Sub AI()
        Dim pnl As Panel = Nothing

        If difficulty = 0 OrElse (difficulty = 1 AndAlso CBool(DateTime.Now.Millisecond Mod 2)) OrElse (difficulty = 2 AndAlso Not CanBlock_or_Win(pnl)) Then
            Call pnl_Click(availablePnls.Item(r.Next(0, availablePnls.Count)), EventArgs.Empty)
        Else
            If pnl IsNot Nothing Then
                Call pnl_Click(pnl, EventArgs.Empty)
            End If
        End If

    End Sub

    Private Function CanBlock_or_Win(ByRef pnl As Panel) As Boolean

        If pnlUpperLeft.Tag.ToString = "o" AndAlso pnlUpperMiddle.Tag.ToString = "o" AndAlso String.IsNullOrWhiteSpace(pnlUpperRight.Tag.ToString) Then
            pnl = pnlUpperRight
            Return True
        ElseIf pnlCenterLeft.Tag.ToString = "o" AndAlso pnlCenterMiddle.Tag.ToString = "o" AndAlso String.IsNullOrWhiteSpace(pnlCenterRight.Tag.ToString) Then
            pnl = pnlCenterRight
            Return True
        ElseIf pnlLowerLeft.Tag.ToString = "o" AndAlso pnlLowerMiddle.Tag.ToString = "o" AndAlso String.IsNullOrWhiteSpace(pnlLowerRight.Tag.ToString) Then
            pnl = pnlLowerRight
            Return True
        ElseIf pnlUpperLeft.Tag.ToString = "o" AndAlso pnlCenterLeft.Tag.ToString = "o" AndAlso String.IsNullOrWhiteSpace(pnlLowerLeft.Tag.ToString) Then
            pnl = pnlLowerLeft
            Return True
        ElseIf pnlUpperMiddle.Tag.ToString = "o" AndAlso pnlCenterMiddle.Tag.ToString = "o" AndAlso String.IsNullOrWhiteSpace(pnlLowerMiddle.Tag.ToString) Then
            pnl = pnlLowerMiddle
            Return True
        ElseIf pnlUpperRight.Tag.ToString = "o" AndAlso pnlCenterRight.Tag.ToString = "o" AndAlso String.IsNullOrWhiteSpace(pnlLowerRight.Tag.ToString) Then
            pnl = pnlLowerRight
            Return True
        ElseIf pnlUpperLeft.Tag.ToString = "o" AndAlso pnlCenterMiddle.Tag.ToString = "o" AndAlso String.IsNullOrWhiteSpace(pnlLowerRight.Tag.ToString) Then
            pnl = pnlLowerRight
            Return True
        ElseIf pnlUpperRight.Tag.ToString = "o" AndAlso pnlCenterMiddle.Tag.ToString = "o" AndAlso String.IsNullOrWhiteSpace(pnlLowerLeft.Tag.ToString) Then
            pnl = pnlLowerLeft
            Return True
        ElseIf pnlUpperLeft.Tag.ToString = "x" AndAlso pnlUpperMiddle.Tag.ToString = "x" AndAlso String.IsNullOrWhiteSpace(pnlUpperRight.Tag.ToString) Then
            pnl = pnlUpperRight
            Return True
        ElseIf pnlCenterLeft.Tag.ToString = "x" AndAlso pnlCenterMiddle.Tag.ToString = "x" AndAlso String.IsNullOrWhiteSpace(pnlCenterRight.Tag.ToString) Then
            pnl = pnlCenterRight
            Return True
        ElseIf pnlLowerLeft.Tag.ToString = "x" AndAlso pnlLowerMiddle.Tag.ToString = "x" AndAlso String.IsNullOrWhiteSpace(pnlLowerRight.Tag.ToString) Then
            pnl = pnlLowerRight
            Return True
        ElseIf pnlUpperLeft.Tag.ToString = "x" AndAlso pnlCenterLeft.Tag.ToString = "x" AndAlso String.IsNullOrWhiteSpace(pnlLowerLeft.Tag.ToString) Then
            pnl = pnlLowerLeft
            Return True
        ElseIf pnlUpperMiddle.Tag.ToString = "x" AndAlso pnlCenterMiddle.Tag.ToString = "x" AndAlso String.IsNullOrWhiteSpace(pnlLowerMiddle.Tag.ToString) Then
            pnl = pnlLowerMiddle
            Return True
        ElseIf pnlUpperRight.Tag.ToString = "x" AndAlso pnlCenterRight.Tag.ToString = "x" AndAlso String.IsNullOrWhiteSpace(pnlLowerRight.Tag.ToString) Then
            pnl = pnlLowerRight
            Return True
        ElseIf pnlUpperLeft.Tag.ToString = "x" AndAlso pnlCenterMiddle.Tag.ToString = "x" AndAlso String.IsNullOrWhiteSpace(pnlLowerRight.Tag.ToString) Then
            pnl = pnlLowerRight
            Return True
        ElseIf pnlUpperRight.Tag.ToString = "x" AndAlso pnlCenterMiddle.Tag.ToString = "x" AndAlso String.IsNullOrWhiteSpace(pnlLowerLeft.Tag.ToString) Then
            pnl = pnlLowerLeft
            Return True
        ElseIf availablePnls.Count = 0 Then
            lblCats.Tag = CInt(lblCats.Tag) + 1
            lblCats.Text = "Cats: " & lblCats.Tag.ToString
            Call NewGame(difficulty)
            Return False
        End If

        Return False
    End Function

End Class
```

----------


## Mallard8

Just come across this and found it interesting the way everything is done in code instead of in designer.

----------

