In this article, I have mentioned C# Console application code with explanation for Tic-Tac-Toe Game, if you have general C# programming idea about Loops, If-Else, Read Console input and write on it, then you can easily understand the below code.

Before we create tic tac toe in C# Console application, we should know rules of this game:

- The game is played on a grid that's 3 squares by 3 squares.
- X starts first and O later (Player 1 = X, Player 2 = O)
- Only 1 player can play at a time
- The first player to get 3 of her marks in a row (up, down, across, or diagonally) is the winner.
- When all 9 squares are full, the game is over. If no player has 3 marks in a row, the game ends in a tie.

So as you can see from point 4 and 5, if any player has 3 marks in a row, he/she wins. For a draw all 9 squares must be filled but there is no 3 marks in a row (up, down, across, or diagonally).

Based on above rules, here is what our algorithm or steps should be to create tic tac toe in C# Console application

- Create an array where we will store X/ O values
- Start a loop to ask Values from player 1 and player 2 one by one, until a match ends ( We can use flag to check when match ends)
- Check for 3 marks in a row, using array values, if player 1/2 has 3 marks in a row he/she wins.
- If all of the above marks are filled, match ends as a draw.

So here is the code for it.

```
using System;
using System.IO;
using System.Threading;
namespace TicTacToeCsharp
{
public class Program
{
//making array and
//by default passing 9 blank cells
static char[] arr = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };
static int player = 1; //By default player 1 is set
static int choice; //This holds the choice at which position user want to mark
// The checkWon variable checks who has won if it's value is 1 then someone has won the match
//if -1 then Match has Draw if 0 then match is still running
static int checkWon = 0;
static void Main(string[] args)
{
do
{
//Clear screen once loop starts again
Console.Clear();
// X will start first so it will be for player 1
// O will be for player 2
Console.WriteLine("Player 1: X and Player 2: O");
Console.WriteLine();
Console.WriteLine();
if (player % 2 == 0)//checking the chance of the player
{
Console.WriteLine("Player 2 Chance");
}
else
{
Console.WriteLine("Player 1 Chance");
}
Console.WriteLine();
Console.WriteLine();
// calling the board Function
DrawBoard();
//Taking users choice
choice = int.Parse(Console.ReadLine());
// checking that position where user want to run is already marked (with X or O) or not
if (arr[choice] != 'X' && arr[choice] != 'O')
{
if (player % 2 == 0) //if chance is of player 2 then mark O else mark X
{
arr[choice] = 'O';
player++;
}
else
{
arr[choice] = 'X';
player++;
}
}
else
{
//If there is any possition where user want to add X or O
//and that is already marked then show message and load board again
Console.WriteLine("Sorry the row {0} is already marked with {1}", choice, arr[choice]);
Console.WriteLine("\n");
Console.WriteLine("Please wait 1 second board is loading again.....");
Thread.Sleep(1000);
}
// calling of check win
checkWon = CheckWin();
}
while (checkWon != 1 && checkWon != -1);
// This loop will be run until all cell of the grid is not marked
//with X and O or some player is not win
Console.Clear();// clearing the console
DrawBoard();// getting filled board again
if (checkWon == 1)
{
// if flag value is 1 then someone has win or
//Player who played last time won
Console.WriteLine("Player {0} has won", (player % 2) + 1);
}
else
{
// if flag value is -1 the match will be draw and no one is winner
Console.WriteLine("Draw");
}
Console.ReadLine();
}
// Board method which creates board on console
//using array arr, we check if there is any value, X or O, then show it
private static void DrawBoard()
{
Console.WriteLine(" | | ");
Console.WriteLine(" {0} | {1} | {2}", arr[1], arr[2], arr[3]);
Console.WriteLine("_____|_____|_____ ");
Console.WriteLine(" | | ");
Console.WriteLine(" {0} | {1} | {2}", arr[4], arr[5], arr[6]);
Console.WriteLine("_____|_____|_____ ");
Console.WriteLine(" | | ");
Console.WriteLine(" {0} | {1} | {2}", arr[7], arr[8], arr[9]);
Console.WriteLine(" | | ");
}
//Checking that any player has won or not
private static int CheckWin()
{
#region Horzontal Winning Condtion
//Winning Condition For First Row
if ((arr[1] == arr[2] && arr[2] == arr[3]) && (arr[1] != ' ' && arr[2] != ' ' && arr[3] != ' '))
{
return 1;
}
//Winning Condition For Second Row
else if ((arr[4] == arr[5] && arr[5] == arr[6]) && (arr[4] != ' ' && arr[5] != ' ' && arr[6] != ' '))
{
return 1;
}
//Winning Condition For Third Row
else if ((arr[6] == arr[7] && arr[7] == arr[8]) && (arr[6] != ' ' && arr[7] != ' ' && arr[8] != ' '))
{
return 1;
}
#endregion
#region vertical Winning Condtion
//Winning Condition For First Column
else if ((arr[1] == arr[4] && arr[4] == arr[7]) && (arr[1] != ' ' && arr[4] != ' ' && arr[7] != ' '))
{
return 1;
}
//Winning Condition For Second Column
else if ((arr[2] == arr[5] && arr[5] == arr[8]) && (arr[2] != ' ' && arr[5] != ' ' && arr[5] != ' '))
{
return 1;
}
//Winning Condition For Third Column
else if ((arr[3] == arr[6] && arr[6] == arr[9]) && (arr[3] != ' ' && arr[6] != ' ' && arr[9] != ' '))
{
return 1;
}
#endregion
#region Diagonal Winning Condition
else if ((arr[1] == arr[5] && arr[5] == arr[9]) && (arr[1] != ' ' && arr[5] != ' ' && arr[9] != ' '))
{
return 1;
}
else if ((arr[3] == arr[5] && arr[5] == arr[7]) && (arr[3] != ' ' && arr[5] != ' ' && arr[7] != ' '))
{
return 1;
}
#endregion
#region Checking For Draw
// If all the cells or values filled with X or O then any player has won the match
else if (arr[1] != ' ' && arr[2] != ' ' && arr[3] != ' ' && arr[4] != ' ' && arr[5] != ' ' && arr[6] != ' ' && arr[7] != ' ' && arr[8] != ' ' && arr[9] != ' ')
{
return -1;
}
#endregion
else
{
return 0;
}
}
}
}
```

I have explained most parts of the code using comments.

Here is the output when I build and run the project.

If we have an error when a already filled square is selected by player, then we are showing error as below

Once a player wins, we will see the output below

If you will notice code, we are using ' ' empty char values in array when creating it, so when checking a win, we are also checking if value is not empty, that is, it must have a valid value.

You may also like to read:

Useful Visual Studio Shortcuts (comment, remove comment, Collapse code etc )

Clear Text File or Delete File in C#

Iterate Over Dictionary in C# (Various ways)

Catch Multiple Exceptions in C#

Compare JSON using C# and Get difference

How to Edit More than 200 rows in SQL Server

What is shortcut for expand-collapse sections of code in VS Code?

Change VS Code Terminal Font Size