How to create a Tic Tac Toe game in Java

Amit Dhanwani on January 23, 2023

Tic Tac Toe game in Java

Introduction

The Tic Tac Toe game is also known as “Noughts and crosses” game. It is one of the most popular two-player pen-and-paper games.

This two-player pen-and-paper game has extremely ancient roots and is popular in many countries.

The game’s rules are straightforward and well-known.

Two players, X and O, will play this game by alternately marking the squares in a 3X3 grid.

The game is won by the person who successfully arranges three of their marks in a row that is either horizontal, vertical, or diagonal.

Only one symbol may be placed by each player at every turn, after which the turn is passed to the other player.

Game approach

  • Wins: Each player attempts to arrange three symbols in three adjacent cells that are either horizontally, vertically, or diagonally spaced. The winner is the one who accomplishes this alignment first. The second player attempts to obstruct Player 1’s alignment by inserting his symbols between Player 1’s symbols.
  • Lose: You lose if your rival achieves the necessary symbol alignment faster.
  • Draw: If none of the players achieves the necessary alignment, all nine grip cells are marked.. A draw or tie is the outcome. In this scenario, none of the players receives a point. Throughout the game, this circumstance occurs frequently and is quite entertaining.

Tic-tac-toe is an ideal educational game for teaching youngsters the development of logic and sportsmanship because of its simplicity.

A n x n version of the traditional 3 x 3 game of tic-tac-toe may be created in which the two players alternately put their symbols on a n × n board to line up d of their symbols in a row that is either vertical, horizontal, or diagonal.

In this blog, we’ll use Java programming to create a game Tic Tac Toe console version.

The fundamental concept is to manage the game board using a two-dimensional array or board. This array’s cells contain values that specify whether they are empty or have an X or an O.

Consider a 3 x 3 board so the player board will look like the image below.

 Tic Tac Toe

 Tic Tac Toe board

 

And the board array will look something like the below image.

tic-tac-toe

Two-Dimensional board array

The center row of the 3 x 3 matrix board has the cells board[1][0], board[1][1], and board[1][2], where the first number represents the row number and the second number represents the column number of the board.

Specific aspects to consider about the game in Java

  • The program outputs a 3×3 board with dashes, which stand for vacant spaces.
  • The board is again printed with the x or o in the appropriate position after each turn by asking either player 1 or player 2 to input a row and col index representing where they wish to place their x and o.
  • Our application alerts the player and asks them to enter another row and col if the place they entered is “off the board” or already contains an x or o.
  • The program prints out the final board and notifies players 1 or 2 that they have won after they obtain 3 symbols in a row, column, or diagonal.

General implementation order

  • Dashes should be placed on a Tic Tac Toe board.
  • Create a function that squares up the board.
  • The player’s turn and the symbol they are using should be noted.
  • Ask for a row and a col repeatedly until they are appropriate.
  • Set the appropriate symbol in the relevant place on the board.
  • Make a function that determines who won the game.
  • Test to see if there was a tie in the game.
  • To keep the game alive, use a loop.

Steps to implement the orders

Step I: To simulate the tic tac toe board, make a 3×3 array and fill it with dashes

char[][] board = new char[n][n];

This line of code is used to create a 3×3 character array.

for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
board[i][j] = '-';
}
}

Each point on the board is iterated through using a nested for loop. We may put board[i][j] equal to a dash within both for loops.

Step II: Make a function that prints the board as a 3×3 square after the board is drawn

For the function to be able to print the board 2D array, we must supply it. Since the function only prints the board, we don’t need to return anything.

We need to print out each place on our board inside of our function.

Step III: Print the appropriate player’s turn, then save the player’s character (x or o)

 In our game, we need a means to keep track of which player is taking turns.

boolean player1 = true;

We will use a boolean variable named player1 that is true when player 1 is doing the turn and false when player 2 is.

Step IV: Ask for a row and a col repeatedly until they are appropriate

System.out.print("Enter a row number: ");
row = in.nextInt();
System.out.print("Enter a column number: ");
col = in.nextInt();

Use the Scanner to obtain the user’s input and store it in a variable named row after printing a message asking for a row; do the same for a variable called col.

if(row < 0 || col < 0 || row >= n || col >= n) {
System.out.println("This position is outside the boundaries of the board!x Try again.");

The row and col are invalid if the user enters them in a position that is not on the board. To determine whether the row and col are not larger than 2 and not less than 0, use a conditional.

} else if(board[row][col] != '-') {
System.out.println("Someone has already made a move at this position! Try again.");

The row and col are invalid if the user enters them in a cell that already has an x or an o on it. Check to see if the board location at row and col already has an x or o by using a conditional.

while(true)
{
- - -
}

We want to prompt the user to re-enter a row and col if they input a row and col that is outside of bounds or that already has an x or o on it. For this, we will use the while loop which will work great! And it will break out of the loop once the player has entered a valid row and col.

Step V: Set the appropriate symbol in the relevant place on the board

board[row][col] = c;

We are clear that we have an appropriate row and col outside of the while loop.

By doing board[row][col], we may obtain the desired location on the board.

Now that we have put the player’s character in the variable c, we can set this position to equal that value.

Step VI: Make a function that determines who won the game

A player in the game of tic tac toe wins if they line up three of their symbols in a row, column, or diagonal.

Start off with rows. To iterate through each row we may use a for loop.

We may use a conditional within the for loop to determine if board[i][0] equals board[i][1] and whether board[i][1] equals board[i][2]. Remember that in order to prevent winning if there are three consecutive empty places, we must additionally verify that board[i][0] does not equal a dash. We can return the value of board[i][0] if everything is true.

Similar procedures may be used for columns.

On the board, there are two diagonals that need to be examined. Similar to the if statements we used for rows and columns, we can use two if statements to verify the two diagonals.

When our function is complete, it indicates that no one has won. Then let’s return space in this case.

Step VII: Test to see if there was a tie in the game

for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[i].length; j++) {
if(board[i][j] == '-') {
return false;
}
}
}
return true;

If no one has won and the board is full, tic tac toe is a tie. We have already determined who the winner is. The board must now be checked to see if it is full.

Let’s write a function that, when the board is complete, returns true and, while the board still has vacant spaces, returns false. A dash is when a space is vacant.

To iterate through all of the positions on the board, we may use nested for loops. We may use a conditional within the inner for loop to see whether board[i][j] equals – and then return true.

We will know that the board is full after we have completed the nested for loops and discovered that no location on the board equals a dash, at which point we may return true.

Step VIII: To keep the game alive, use a loop

 We may make a boolean named gameEnded and set it to false at the beginning. We may set gameEnded to true inside the if statement, which is where we determine if a player has won or whether it is a tie.

In order for the program to continue requesting a player to enter a row and a column until a winner or a tie is determined, we may create a while loop with the condition simply being gameEnded.

We can draw the board one last time once the while loop is finished so that both players can view the board’s final configuration.

Program:

import java.util.Scanner;

class Main {

public static void main(String[] args) {

// Variable to represent the size of our tic tac toe board
int n = 3;

// nxn array that represents our tic tac toe board
char[][] board = new char[n][n];

//Initialize our board with dashes (empty positions)
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
board[i][j] = '-';
}
}

//Create a Scanner for asking the players for their names
Scanner in = new Scanner(System.in);
System.out.println("Tic Tac Toe is ready for play!\n");
System.out.print("What is your name?, player 1: ");
String p1 = in.nextLine();
System.out.print(" What is your name?, player 2:");
String p2 = in.nextLine();

//Create a player1 boolean that is true if it is player 1's turn and false if it is player 2's turn
boolean player1 = true;

//Create a gameEnded boolean and use it as the condition in the while loop
boolean gameEnded = false;
while(!gameEnded) {

//Draw the board
drawBoard(board);

//Print whose turn it is
if(player1) {
System.out.println(p1 + "'s Turn (x):");
} else {
System.out.println(p2 + "'s Turn (o):");
}

//Create a char variable that stores either 'x' or 'o' based on what player's turn it is
char c = '-';
if(player1) {
c = 'x';
} else {
c = 'o';
}

//Create row and col variables which represent indexes that correspond to a position on our board
int row = 0;
int col = 0;

//Only break out of the while loop once the user enters a valid position
while(true) {

//Ask the user for what position they want to place their x or o
System.out.print("Enter a row number: ");
row = in.nextInt();
System.out.print("Enter a column number: ");
col = in.nextInt();

//Check if the row and col are outside of the board
if(row < 0 || col < 0 || row >= n || col >= n) {
System.out.println("This position is off the bounds of the board! Try again.");

//Check if the position on the board the user entered is empty (has a -) or not
} else if(board[row][col] != '-') {
System.out.println("Someone has already made a move at this position! Try again.");

//Otherwise, the position is valid so break out of the while loop
} else {
break;
}
}

//Set the position on the board at row, col to c
board[row][col] = c;

//Check to see if either player has won
if(playerHasWon(board) == 'x') {
System.out.println(p1 + " has won!");
gameEnded = true;
} else if(playerHasWon(board) == 'o') {
System.out.println(p2 + " has won!");
gameEnded = true;
} else {

//If neither player has won, check to see if there has been a tie (if the board is full)
if(boardIsFull(board)) {
System.out.println("It's a tie!");
gameEnded = true;
} else {

//If player1 is true, make it false, and vice versa; this way, the players alternate each turn
player1 = !player1;
}
}
}

//Draw the board at the end of the game
drawBoard(board);
}

//Make a function to draw the tic tac toe board
public static void drawBoard(char[][] board) {
System.out.println("Board:");
for(int i = 0; i < board.length; i++) {

//The inner for loop prints out each row of the board
for(int j = 0; j < board[i].length; j++) {
System.out.print(board[i][j]);
}

//This print statement makes a new line so that each row is on a separate line
System.out.println();
}
}

//Make a function to see if someone has won and return the winning char
public static char playerHasWon(char[][] board) {

// Checking each row
for(int i = 0; i < board.length; i++) {

// The boolean inARow is true if a player has won by putting n of their chars in row i and false otherwise
boolean inARow = true;

// The char value is one of the chars in row i; we can use this to check if every other char in row i is equal to value
char value = board[i][0];

// First we have to check if the value is not -, because if it is, that means that there is an empty spot in the row so we can automatically say that inARow is false
if(value == '-') {
inARow = false;

// Otherwise, we can use a nested for loop to check each position in the row starting at index 1 (since index 0 is our value and we don't need to check if board[i][0] equals value) and check if that position equals value
} else {
for(int j = 1; j < board[i].length; j++) {

// If board[i][j] doesn't equal value, then we know that inARow is false; we can also break out of the nested for loop because we don't need to look at the rest of this row
if(board[i][j] != value) {
inARow = false;
break;
}
}
}

// If inARow is true, then we know that each position in row i had a char equal to value which was not a -. In other words, a player has won so we can return value (the char of the winner)
if(inARow) {
return value;
}
}

// We can use the same construction to check each column
for(int j = 0; j < board[0].length; j++) {
boolean inACol = true;
char value = board[0][j];

if(value == '-') {
inACol = false;
} else {

for(int i = 1; i < board.length; i++) {
if(board[i][j] != value) {
inACol = false;
break;
}
}
}

if(inACol) {

return value;
}
}

// We can use a similar construction to check the diagonals
// Check the diagonal going from upper left to bottom right: [0][0], [1][1], [2][2]...
boolean inADiag1 = true;
char value1 = board[0][0];
if(value1 == '-') {
inADiag1 = false;
} else {
for(int i = 1; i < board.length; i++) {
if(board[i][i] != value1) {
inADiag1 = false;
break;
}
}
}

if(inADiag1) {
return value1;
}

// Check the diagonal going from upper right to bottom left: [0][n-1], [1][n-2], [2][n-3]...
boolean inADiag2 = true;
char value2 = board[0][board.length-1];

if(value2 == '-') {
inADiag2 = false;
} else {
for(int i = 1; i < board.length; i++) {
if(board[i][board.length-1-i] != value2) {
inADiag2 = false;
break;
}
}
}

if(inADiag2) {
return value2;
}

//Otherwise nobody has not won yet
return ' ';
}

//Make a function to check if all of the positions on the board have been filled
public static boolean boardIsFull(char[][] board) {
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[i].length; j++) {
if(board[i][j] == '-') {
return false;
}
}
}
return true;
}
}
Output:

Tic Tac Toe is ready for play!

What is your name?, player 1: Codingal

What is your name?, player 2:Penguin

Board:

---

---

---

Codingal's Turn (x):

Enter a row number: 0

Enter a column number: 0

Board:

x--

---

---

Penguin's Turn (o):

Enter a row number: 1

Enter a column number: 1

Board:

x--

-o-

---

Codingal's Turn (x):

Enter a row number: 0

Enter a column number: 1

Board:

xx-

-o-

---

Penguin's Turn (o):

Enter a row number: 0

Enter a column number: 2

Board:

xxo

-o-

---

Codingal's Turn (x):

Enter a row number: 1

Enter a column number: 0

Board:

xxo

xo-

---

Penguin's Turn (o):

Enter a row number: 1

Enter a column number: 2

Board:

xxo

xoo

---

Codingal's Turn (x):

Enter a row number: 2

Enter a column number: 0

Codingal has won!

Board:

xxo

xoo

x--

Conclusion:

In this blog, we learned how to implement the fundamental tic-tac-toe game in Java. We have used the two-dimensional array, boolean variables, loops, conditional statements and many more concepts of Java.

Learning to code can give your child the foundational skills for future success. Basic programming knowledge can change the way kids interact with the technologies they use daily. It’s a basic literacy–one we can’t afford to overlook.
Coding for kids not only helps improve their logical thinking, critical thinking, problem-solving skills, creativity, mathematics and writing skills but also gives them valuable skills in life and at the workplace. Try a free class today!

 

Sign up to our newsletter

Get the latest blogs, articles, and updates delivered straight to your inbox.

Share with your friends

Try a free class