C# 3 X 3 TicTacToe Tutorial


You can find the code to the popular game TicTacToe in C# language using the .Net Framework 4.5. The highlights include the following:
  • Perfectly Written Flawless Code in .Net Framework C# 5 language using WinForms
  • Programmer level only Beginner required. NOT Intermediate. NOT Expert. 
  • The code is explained immediately before being written. 
  • The game's basic functionality is that it has two players put their letters, the X and O in 9 available grid boxes one by one and the player to make a straight line with 3 letters wins. 
  • The Game Counts scores of the individual players and a Reset of the scores is also possible. 
  • Players may reset the current game and start a new game whenever needed. 
  • Please recommend and comment if it worked for you. Thank You for Visiting :) 



using System;
using System.Text;
using System.Windows.Forms;

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

        }

The integer variable pturn remembers which player plays next. The value 1 means that player 1 plays next. Similarly, the value 2 means that player 2 plays next. This variable will have one of these two values. 

        int pturn;

The variable current_started remembers which player has played the latest/currently ongoing game. So that when the game ends, it is the opposite player to take the first turn. This makes sure the players get equal number of chances to start first. "First Turns" can easily decide a winner in this particular game, therefore tracking it is absolutely necessary. 

        int current_started;

The X's and O's are stored in a 2D array. You may think that the values are stored in the Text value of each button. But storing them in this way makes it super easy to retrieve and check values. This 2D array will be used later to check the straight line win for a player. 

        public int[,] gridvalues = new int[3, 3];

        private void Form1_Load(object sender, EventArgs e)
        {

Set the Player 1 to play first when the form loads i.e. when the game starts up. 

            pturn = 1;
        }

The Function below helps to start a new game. It enables all the buttons to be pressed again and sets their Text values to blank meaning they are available to use. 

        private void start_new_game()
        {
            b11.Enabled = true; b11.Text = "";
            b12.Enabled = true; b12.Text = "";
            b13.Enabled = true; b13.Text = "";
            b21.Enabled = true; b21.Text = "";
            b22.Enabled = true; b22.Text = "";
            b23.Enabled = true; b23.Text = "";
            b31.Enabled = true; b31.Text = "";
            b32.Enabled = true; b32.Text = "";
            b33.Enabled = true; b33.Text = "";

This below for loop sets the 2D Array Values to 0. Grid values with 0 mean they are not clicked, unused, and available(waiting) for use by any player. 

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    gridvalues[i, j] = 0;
                }
            }

The code below checks for the player who started the current game and makes sure the mext game is started by the next player. 

            if (current_started == 1)
            {
                current_started = 2;
                pturn = 2;
            }
            else             
                if(current_started == 2)
            {
                current_started = 1;
                pturn = 1;
            }
        }

There are two diagonals in this square grid. The function below checks the two diagonals for a potential Win from any player. The two variables countforP1 and countforP2 counts the number of (particular) player visits in each diagonal. The two for loops allow us to check each cell in the 2D Grid Array. 

















        
The "i == j" checks for cells with equal values of row and column. The diagonals have row and column values same i.e (1,1), (2,2) and (3,3). 

When the first player visits a grid cell, the value of the 2D Array grid cell is set to 1. When the second player visits a grid cell, the value of the 2D Array grid cell is set to 2.


private void check_all_diagonals()
        {           
            int countforP1 = 0;
            int countforP2 = 0;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (i == j && gridvalues[j, i] == 1)
                    {
                        countforP1++;
                    }

                    if (i == j && gridvalues[j, i] == 2)
                    {
                        countforP2++;
                    }

                    if (countforP1 == 3)
                    {
                        MessageBox.Show("Player 1 Wins !!");
                        p1score.Text = Convert.ToString(Convert.ToUInt16(p1score.Text) + 1);
                        start_new_game();
                        break;
                    }
                    if (countforP2 == 3)
                    {
                        MessageBox.Show("Player 2 Wins !!");
                        p2score.Text = Convert.ToString(Convert.ToUInt16(p2score.Text) + 1);
                        start_new_game();
                        break;
                    }
                }
            }
        }

        private void check_all_rows()
        {
            int countforP1 = 0;
            int countforP2 = 0;

            for (int i = 0; i < 3; i++)
            {
                countforP1 = 0;
                countforP2 = 0;
                for (int j = 0; j < 3; j++)
                {
                    if (gridvalues[i, j] == 1)
                    {
                        countforP1++;
                    }
                    if (gridvalues[i, j] == 2)
                    {
                        countforP2++;
                    }

                    if (countforP1 == 3)
                    {
                        MessageBox.Show("Player 1 Wins !!");
                        p1score.Text = Convert.ToString(Convert.ToUInt16(p1score.Text)+1);
                        start_new_game();
                        break;
                    }
                    if (countforP2 == 3)
                    {
                        MessageBox.Show("Player 2 Wins !!");
                        p2score.Text = Convert.ToString(Convert.ToUInt16(p2score.Text) + 1);
                        start_new_game();
                        break;
                    }
                }
            }
        }

This function checks column-wise the potential win for a player. The first for loop checks for the column number. 


        private void check_all_columns()
        {
            int countforP1 = 0;
            int countforP2 = 0;

            for (int i = 0; i < 3; i++)
            {

The values below reset the visit count for each column. 

                countforP1 = 0;
                countforP2 = 0;

For each column number we check all row values using the j variable. 

                for (int j = 0; j < 3; j++)
                {
                    if (gridvalues[j, i] == 1)
                    {
                        countforP1++;
                    }

                    if (gridvalues[j, i] == 2)
                    {
                        countforP2++;
                    }

                    if (countforP1 == 3)
                    {
                        MessageBox.Show("Player 1 Wins !!");
                        p1score.Text = Convert.ToString(Convert.ToUInt16(p1score.Text) + 1);
                        start_new_game();
                        break;
                    }
                    if (countforP2 == 3)
                    {
                        MessageBox.Show("Player 2 Wins !!");
                        p2score.Text = Convert.ToString(Convert.ToUInt16(p2score.Text) + 1);
                        start_new_game();
                        break;
                    }
                }
            }
        }

When the button is clicked, the button is first disabled to register the visit. Then, we check if it is the first or second player to visit. The 2D Array is set then the Text on the button is set appropriately. After each visit, the rows, columns and diagonals are checked for a potential win. After a win, a new game starts automatically. 

        private void b11_Click(object sender, EventArgs e)
        {
            b11.Enabled = false;
            if (pturn == 1)
            {
                gridvalues[0, 0] = 1;
                b11.Text = "X";
                pturn = 2;
            }
            else
            {
                gridvalues[0, 0] = 2;
                b11.Text = "O";
                pturn = 1;
            }

            check_all_rows(); check_all_columns(); check_all_diagonals();
        }

        private void b12_Click(object sender, EventArgs e)
        {
            b12.Enabled = false;
            if (pturn == 1)
            {
                gridvalues[0, 1] = 1;
                b12.Text = "X";
                pturn = 2;
            }
            else
            {
                gridvalues[0, 1] = 2;
                b12.Text = "O";
                pturn = 1;
            }
            check_all_rows(); check_all_columns(); check_all_diagonals();
        }

        private void b13_Click(object sender, EventArgs e)
        {
            b13.Enabled = false;
            if (pturn == 1)
            {
                gridvalues[0, 2] = 1;
                b13.Text = "X";
                pturn = 2;
            }
            else
            {
                gridvalues[0, 2] = 2;
                b13.Text = "O";
                pturn = 1;
            }
            check_all_rows(); check_all_columns(); check_all_diagonals();
        }

        private void b21_Click(object sender, EventArgs e)
        {
            b21.Enabled = false;
            if (pturn == 1)
            {
                gridvalues[1, 0] = 1;
                b21.Text = "X";
                pturn = 2;
            }
            else
            {
                gridvalues[1, 0] = 2;
                b21.Text = "O";
                pturn = 1;
            }

            check_all_rows(); check_all_columns(); check_all_diagonals();
        }

        private void b22_Click(object sender, EventArgs e)
        {
            b22.Enabled = false;
            if (pturn == 1)
            {
                gridvalues[1, 1] = 1;
                b22.Text = "X";
                pturn = 2;
            }
            else
            {
                gridvalues[1, 1] = 2;
                b22.Text = "O";
                pturn = 1;
            }
            check_all_rows(); check_all_columns(); check_all_diagonals();
        }

        private void b23_Click(object sender, EventArgs e)
        {
            b23.Enabled = false;
            if (pturn == 1)
            {
                gridvalues[1, 2] = 1;
                b23.Text = "X";
                pturn = 2;
            }
            else
            {
                gridvalues[1, 2] = 2;
                b23.Text = "O";
                pturn = 1;
            }
            check_all_rows(); check_all_columns(); check_all_diagonals();
        }

        private void b31_Click(object sender, EventArgs e)
        {
            b31.Enabled = false;
            if (pturn == 1)
            {
                gridvalues[2, 0] = 1;
                b31.Text = "X";
                pturn = 2;
            }
            else
            {
                gridvalues[2, 0] = 2;
                b31.Text = "O";
                pturn = 1;
            }
            check_all_rows(); check_all_columns(); check_all_diagonals();
        }

        private void b32_Click(object sender, EventArgs e)
        {
            b32.Enabled = false;
            if (pturn == 1)
            {
                gridvalues[2, 1] = 1;
                b32.Text = "X";
                pturn = 2;
            }
            else
            {
                gridvalues[2, 1] = 2;
                b32.Text = "O";
                pturn = 1;
            }
            check_all_rows(); check_all_columns(); check_all_diagonals();
        }

        private void b33_Click(object sender, EventArgs e)
        {
            b33.Enabled = false;
            if (pturn == 1)
            {
                gridvalues[2, 2] = 1;
                b33.Text = "X";
                pturn = 2;
            }
            else
            {
                gridvalues[2, 2] = 2;
                b33.Text = "O";
                pturn = 1;
            }
            check_all_rows(); check_all_columns(); check_all_diagonals();
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            p1score.Text = "0";
            p2score.Text = "0";
        }

        private void bnewgame_Click(object sender, EventArgs e)
        {
            start_new_game();
        }

        private void bexit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            MessageBox.Show("Please Visit http://www.Code-Kings.blogspot.com//" ,"Have a Nice Day");

        }       
    }
}