C# Tutorial – Create a Tic Tac Toe game with Working AI

In this tutorial we will create a simple tic tac toe game using visual studio 2010 and C# programming language. We will use the windows form application for this tutorial and link a few events to the buttons. More important we will explore the possibility of using a simple AI in this game. Our target is to use a simple AI which will play alongside the user not necessarily programmed to be very challenging to the user.

Lesson objectives –

  1. Create a simple tic tac toe game using visual studio and c#
  2. Using buttons and events
  3. Using TIMER to create an AI (opponent) for the game
  4. Using selection (if statements) to determine the win, lose or Draw
  5. Using loops to enable or disable buttons
  6. Using a function to reset the game for another round

To start open Visual Studio –

Under the Visual C# – Create a new Windows Form Application in visual studio. Call this project tictactoeGame and press ok.

In the properties window change the following –

Size: 650,500

Text: Tic Tac Toe – Moo

Now find the button component in the tool box. [if toolbox isn’t present click VIEW on the top and click toolbox]

Add 10 buttons to the form.

Find the label in the tool box.

Drag and drop the label in the windows form.

Select all 9 of the buttons, look at the properties window.

find the font option and click on the 3 dotted button on the right.

Change the font style to BOLD and Size to 14. CLICK OK

Back in the properties window, insert play into the tag option and show a question mark for the Text option.

This is what they look like now.

Change the button 10 text to Reset.

Click on the label 1

Once again click on the 3 dotted button in the properties window.

Change the font style to BOLD and size to 12. Click OK.

Find the timer object from the tool box and drag and drop it to the form.

Change the following to the timer. Name it AITIMER and change the interval from 100 to 1000. Basically we want to run this timer for 1 second only.

Adding events to the game

Select all 9 buttons, click on the small lightning bolt icon on the properties window, find the CLICK event, type buttonClick and press enter.

This will take you to the code view, you can come back to the design view from there and do the following.

Click on the Timer object

Click on the small lightning icon on the properties window, you see only one option for the timer which is TICK. Type playAI and press enter.

This will take you back to the code view, come back to the design view to do the following

Click on the reset button

Click on the lightning bolt icon on the properties window and find the click option, type resetGame and press enter.

Let’s take a look at the code window.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace tictactoeGame
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void buttonClick(object sender, EventArgs e)
        {

        }

        private void playAI(object sender, EventArgs e)
        {

        }

        private void resetGame(object sender, EventArgs e)
        {

        }
    }
}

Add the following code.

Right under the Form1() function add the public enum Player

        public enum Player
        {
            X,
            O
        }

This sort of class will hold X and O value for us. Knots and Crosses if you will.

This line below will create a new instance of the player class we created earlier. We will decide who is the currently player with this line.

Player currentPlayer;

Below is the button click function we linked with all 9 buttons earlier.

        private void buttonClick(object sender, EventArgs e)
        {
            var button = (Button)sender;
            currentPlayer = Player.X;
            button.Text = currentPlayer.ToString();
            button.Enabled = false;
            button.BackColor = System.Drawing.Color.LightGreen;
            Check();
            AITIMER.Start();
        }

var button = (Button)sender; In this line we are creating a variable called button and giving it a value (Button)sender. Since this event is linked to each button we need to find out which button was clicked.

currentPlayer = Player.X; Since the player can only click on the buttons, we are setting the player to have X symbol.

button.Text = currentPlayer.ToString(); We will change the text on the button with the player X symbol by converting the content to string.

button.Enabled = false; disable the button once clicked.

button.BackColor = System.Drawing.Color.LightGreen; change the back colour to light green.

Check(); run the check function

AITIMER.Start(); this is the AI timer we created earlier and we are going to start the timer when player made their move.

Below is the reset game event. Let’s take a closer look at the code inside.

        private void resetGame(object sender, EventArgs e)
        {
            label1.Text = "??";

            foreach (Control x in this.Controls)
            {

                if (x is Button && x.Tag == "play")
                {
                    ((Button)x).Enabled = true;
                    ((Button)x).Text = "?";
                    ((Button)x).BackColor = default(Color);
                }

            }
        }

label1.Text = “??”; — change the label text to double question mark.

foreach (Control x in this.Controls) — starting a for each loop, inside the brackets we set the condition for the loop as in what to check, we are creating a Control variable called X in this controls meaning in this form. This will loop through each component active in form for example buttons, labels, text boxes, picture boxes etc.

if (x is Button && x.Tag == “play”) — this line is checking if X is a button AND it has the tag of play. The reason we are doing this is because we have 10 buttons on the screen, 1 for reset and 9 for the game. So we don’t want to effect the reset button only the play buttons, this is why we added the tag play to these buttons earlier in the tutorial.

((Button)x).Enabled = true; — We are enabling the button.

((Button)x).Text = “?”; — we are changing the text of the button to question mark ?

((Button)x).BackColor = default(Color); — finally we are changing the back colour of the button to the default colour.

        private void playAI(object sender, EventArgs e)
        {
            foreach (Control x in this.Controls)
            {
                if (x is Button && x.Text == "?" && x.Enabled)
                {
                    x.Enabled = false;
                    currentPlayer = Player.O;
                    x.Text = currentPlayer.ToString();
                    x.BackColor = System.Drawing.Color.LightGoldenrodYellow;
                    AITIMER.Stop();
                    Check();
                    break;
                }
                else
                {
                    AITIMER.Stop();
                }
            }
        }

foreach (Control x in this.Controls) — this line is starting the for each loop, we are starting to loop through all of the components or controls in this windows form. Loops are usually started with a condition and curly brackets and ending with a curly brackets.

if (x is Button && x.Text == “?” && x.Enabled) — this line is checking if that x control variable we created earlier in the loop condition. In this if statement we are checking if x is a button AND it has the text ? question mark and x is enabled to be clicked on then we will execute the following actions.

x.Enabled = false; — first we disabling the x button

currentPlayer = Player.O; — currently player is changed to O

x.Text = currentPlayer.ToString(); — Set the button text O by converting the current player to string.

x.BackColor = System.Drawing.Color.LightGoldenrodYellow; — change the background of the button to light golden colour.

AITIMER.Stop(); — stop the AI timer

Check(); — run the check function

break; — break the loop

else — else meaning if none of the conditions in the if statement are met we simply run the following line

AITIMER.Stop(); — stop the timer

        private void Check()
        {
            if (
            button1.Text == "X" && button2.Text == "X" && button3.Text == "X" ||
            button4.Text == "X" && button5.Text == "X" && button6.Text == "X" ||
            button7.Text == "X" && button8.Text == "X" && button9.Text == "X" ||
            button1.Text == "X" && button4.Text == "X" && button7.Text == "X" ||
            button2.Text == "X" && button5.Text == "X" && button8.Text == "X" ||
            button3.Text == "X" && button6.Text == "X" && button9.Text == "X" ||
            button1.Text == "X" && button5.Text == "X" && button9.Text == "X" ||
            button3.Text == "X" && button5.Text == "X" && button7.Text == "X"
                )
            {
                WON();
                label1.Text = "X Wins";
            }
            else if (
            button1.Text == "O" && button2.Text == "O" && button3.Text == "O" ||
            button4.Text == "O" && button5.Text == "O" && button6.Text == "O" ||
            button7.Text == "O" && button8.Text == "O" && button9.Text == "O" ||
            button1.Text == "O" && button4.Text == "O" && button7.Text == "O" ||
            button2.Text == "O" && button5.Text == "O" && button8.Text == "O" ||
            button3.Text == "O" && button6.Text == "O" && button9.Text == "O" ||
            button1.Text == "O" && button5.Text == "O" && button9.Text == "O" ||
            button3.Text == "O" && button5.Text == "O" && button7.Text == "O"
                )
            {
                WON();
                label1.Text = "O Wins";
            }
        }

 

Check function is created to check whether the player or opponent won the game. We are going to use the if statement to check these conditions. We didn’t change the names of the buttons so they are called

button1, button2, button3, button4, button5, button6, button7, button8 and button9

Once any of these conditions are met in the if statement we run the won function to stop the whole game and disable all buttons. The same theory is being used for the O player.

If any of these statements are true then we run the WON function and change the Label text to show who won the game.

        private void WON()
        {
            foreach (Control x in this.Controls)
            {

                if (x is Button && x.Tag == "play")
                {
                    ((Button)x).Enabled = false;
                    ((Button)x).BackColor = default(Color);

                }

            }
        }

foreach (Control x in this.Controls) — we run a for each loop in this function

if (x is Button && x.Tag == “play”) — we check if x is a button and has the tag of PLAY

((Button)x).Enabled = false; — then we run the loop and disable all the buttons

((Button)x).BackColor = default(Color); — we restore the buttons to the default system colour.

Final Project –

Full Code For the game.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace tictactoeGame
{
    public partial class Form1 : Form
    {
        Player currentPlayer;

        public Form1()
        {
            InitializeComponent();
        }

        public enum Player
        {
            X,
            O
        }

        private void buttonClick(object sender, EventArgs e)
        {
            var button = (Button)sender;
            currentPlayer = Player.X;
            button.Text = currentPlayer.ToString();
            button.Enabled = false;
            button.BackColor = System.Drawing.Color.LightGreen;
            Check();
            AITIMER.Start();
        }

        private void playAI(object sender, EventArgs e)
        {
            foreach (Control x in this.Controls)
            {
                if (x is Button && x.Text == "?" && x.Enabled)
                {
                    x.Enabled = false;
                    currentPlayer = Player.O;
                    x.Text = currentPlayer.ToString();
                    x.BackColor = System.Drawing.Color.LightGoldenrodYellow;
                    AITIMER.Stop();
                    Check();
                    break;
                }
                else
                {
                    AITIMER.Stop();
                }
            }
        }

        private void resetGame(object sender, EventArgs e)
        {
            label1.Text = "??";

            foreach (Control x in this.Controls)
            {

                if (x is Button && x.Tag == "play")
                {
                    ((Button)x).Enabled = true;
                    ((Button)x).Text = "?";
                    ((Button)x).BackColor = default(Color);
                }

            }
        }

        private void Check()
        {
            if (
            button1.Text == "X" && button2.Text == "X" && button3.Text == "X" ||
            button4.Text == "X" && button5.Text == "X" && button6.Text == "X" ||
            button7.Text == "X" && button8.Text == "X" && button9.Text == "X" ||
            button1.Text == "X" && button4.Text == "X" && button7.Text == "X" ||
            button2.Text == "X" && button5.Text == "X" && button8.Text == "X" ||
            button3.Text == "X" && button6.Text == "X" && button9.Text == "X" ||
            button1.Text == "X" && button5.Text == "X" && button9.Text == "X" ||
            button3.Text == "X" && button5.Text == "X" && button7.Text == "X"
                )
            {
                WON();
                label1.Text = "X Wins";
            }
            else if (
            button1.Text == "O" && button2.Text == "O" && button3.Text == "O" ||
            button4.Text == "O" && button5.Text == "O" && button6.Text == "O" ||
            button7.Text == "O" && button8.Text == "O" && button9.Text == "O" ||
            button1.Text == "O" && button4.Text == "O" && button7.Text == "O" ||
            button2.Text == "O" && button5.Text == "O" && button8.Text == "O" ||
            button3.Text == "O" && button6.Text == "O" && button9.Text == "O" ||
            button1.Text == "O" && button5.Text == "O" && button9.Text == "O" ||
            button3.Text == "O" && button5.Text == "O" && button7.Text == "O"
                )
            {
                WON();
                label1.Text = "O Wins";
            }
        }

        private void WON()
        {
            foreach (Control x in this.Controls)
            {

                if (x is Button && x.Tag == "play")
                {
                    ((Button)x).Enabled = false;
                    ((Button)x).BackColor = default(Color);

                }

            }
        }
    }
}

 

 




Comments are closed.