Open In App

How to Build a Tic Tac Toe Game in Android?

Last Updated : 13 Jul, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will be building a Tic Tac Toe Game Project using Java and XML in Android. The Tic Tac Toe Game is based on a two-player game. Each player chooses between X and O. Player play one move at a time simultaneously. In a move, a player can choose any position from a 3×3 grid. The goal here is to get three consecutive X or O in a horizontal, vertical, or diagonal direction. There will be a single activity in this application. This activity will show a 3×3 grid. The status of the game will be displayed at the bottom. A sample GIF is given below to get an idea about what we are going to do in this article. 

Build a Tic Tac Toe Game in Android Sample GIF

Step by Step Implementation

Step 1: Create a New Project

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language.

Step 2: Before going to the coding section first you have to do some pre-task

Add Images: All the images are listed below. Save them in your drawable folder in resources. Go to the app > res > drawable and paste the following files:

Change the style to NoActionBar in themes.xml file: 

<style name=”AppTheme” parent=”Theme.AppCompat.NoActionBar”>

Step 3: Working with the activity_main.xml file

The XML codes are used to build the structure of the activity as well as its styling part. It contains a TextView at the very top of the activity to display the title. Then it contains an ImageView of the grid and in each box, there is an ImageView. At the bottom of the activity, there is a TextView to display the status of the game. Below is the code for the activity_main.xml file.

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/green"
    tools:context=".MainActivity">
 
    <!--title text-->
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="23dp"
        android:text="GFG Tic Tac Toe"
        android:textSize="45sp"
        android:textStyle="bold"
        app:fontFamily="cursive"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
 
    <!--image of the grid-->
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:contentDescription="Start"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView"
        app:srcCompat="@drawable/grid" />
 
    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="0dp"
        android:layout_height="420dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="@+id/imageView"
        app:layout_constraintEnd_toEndOf="@+id/imageView"
        app:layout_constraintStart_toStartOf="@+id/imageView"
        app:layout_constraintTop_toTopOf="@+id/imageView">
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">
 
            <!--images of the grid boxes-->
            <ImageView
                android:id="@+id/imageView0"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="0" />
 
            <ImageView
                android:id="@+id/imageView1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="1" />
 
            <ImageView
                android:id="@+id/imageView2"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="2" />
        </LinearLayout>
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">
 
            <ImageView
                android:id="@+id/imageView3"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="3" />
 
            <ImageView
                android:id="@+id/imageView4"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="4" />
 
            <ImageView
                android:id="@+id/imageView5"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="5" />
        </LinearLayout>
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">
 
            <ImageView
                android:id="@+id/imageView6"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="6" />
 
            <ImageView
                android:id="@+id/imageView7"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="7" />
 
            <ImageView
                android:id="@+id/imageView8"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="8" />
        </LinearLayout>
 
    </LinearLayout>
 
    <!--game status text display-->
    <TextView
        android:id="@+id/status"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="15sp"
        android:text="Status"
        android:textSize="28sp"
        android:textStyle="italic"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
 
</androidx.constraintlayout.widget.ConstraintLayout>


Step 4: Working with the MainActivity.java file

We will create a two-dimensional array that will store all the winning positions. We will create a function that will run when a box inside the grid is clicked. Inside this function, we will first check if the box selected is empty or not. After that, we will set the image of X if the last move was of O or we will set the image of O if the last move was of X. Then we will check if the move has reached the move position and then reset the game. Below is the code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.

Java




import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
 
import androidx.appcompat.app.AppCompatActivity;
 
public class MainActivity extends AppCompatActivity {
    boolean gameActive = true;
     
    // Player representation
    // 0 - X
    // 1 - O
    int activePlayer = 0;
    int[] gameState = {2, 2, 2, 2, 2, 2, 2, 2, 2};
     
    // State meanings:
    //    0 - X
    //    1 - O
    //    2 - Null
    // put all win positions in a 2D array
    int[][] winPositions = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8},
            {0, 3, 6}, {1, 4, 7}, {2, 5, 8},
            {0, 4, 8}, {2, 4, 6}};
    public static int counter = 0;
 
    // this function will be called every time a
    // players tap in an empty box of the grid
    public void playerTap(View view) {
        ImageView img = (ImageView) view;
        int tappedImage = Integer.parseInt(img.getTag().toString());
         
        // game reset function will be called
        // if someone wins or the boxes are full
        if (!gameActive) {
            gameReset(view);
            //Reset the counter
            counter = 0;
        }
         
        // if the tapped image is empty
        if (gameState[tappedImage] == 2) {
            // increase the counter
            // after every tap
            counter++;
             
            // check if its the last box
            if (counter == 9) {
                // reset the game
                gameActive = false;
            }
             
            // mark this position
            gameState[tappedImage] = activePlayer;
             
            // this will give a motion
            // effect to the image
            img.setTranslationY(-1000f);
             
            // change the active player
            // from 0 to 1 or 1 to 0
            if (activePlayer == 0) {
                // set the image of x
                img.setImageResource(R.drawable.x);
                activePlayer = 1;
                TextView status = findViewById(R.id.status);
                 
                // change the status
                status.setText("O's Turn - Tap to play");
            } else {
                // set the image of o
                img.setImageResource(R.drawable.o);
                activePlayer = 0;
                TextView status = findViewById(R.id.status);
                 
                // change the status
                status.setText("X's Turn - Tap to play");
            }
            img.animate().translationYBy(1000f).setDuration(300);
        }
        int flag = 0;
        // Check if any player has won if counter is > 4 as min 5 taps are
        // required to declare a winner
        if (counter > 4) {
          for (int[] winPosition : winPositions) {
              if (gameState[winPosition[0]] == gameState[winPosition[1]] &&
                      gameState[winPosition[1]] == gameState[winPosition[2]] &&
                      gameState[winPosition[0]] != 2) {
                  flag = 1;
 
                  // Somebody has won! - Find out who!
                  String winnerStr;
 
                  // game reset function be called
                  gameActive = false;
                  if (gameState[winPosition[0]] == 0) {
                      winnerStr = "X has won";
                  } else {
                      winnerStr = "O has won";
                  }
                  // Update the status bar for winner announcement
                  TextView status = findViewById(R.id.status);
                  status.setText(winnerStr);
              }
          }
          // set the status if the match draw
          if (counter == 9 && flag == 0) {
              TextView status = findViewById(R.id.status);
              status.setText("Match Draw");
          }
        }
    }
 
    // reset the game
    public void gameReset(View view) {
        gameActive = true;
        activePlayer = 0;
        //set all position to Null
        Arrays.fill(gameState, 2);
        // remove all the images from the boxes inside the grid
        ((ImageView) findViewById(R.id.imageView0)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView1)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView2)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView3)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView4)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView5)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView6)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView7)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView8)).setImageResource(0);
 
        TextView status = findViewById(R.id.status);
        status.setText("X's Turn - Tap to play");
    }
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}


Output:



Previous Article
Next Article

Similar Reads

Tic-Tac-Toe Game in Java
In the Tic-Tac-Toe game, you will see the approach of the game is implemented. In this game, two players will be played and you have one print board on the screen where from 1 to 9 number will be displayed or you can say it box number. Now, you have to choose X or O for the specific box number. For example, if you have to select any number then for
6 min read
How to Build Spin the Bottle Game Application in Android?
In this article, we will be building a Spin the Bottle Game Project using Java and XML in Android. The application is based on a multiplayer game. One player spins the bottle and the direction in which the bottle spins will determine the player who gets selected for a task or any other stuff. There will be a single activity in this application. A s
4 min read
How to Build a Simple Reflex Game in Android?
A reflex game is a simple fun game that measures your responding speed. It is quite simple to make and understand. We will be designing a reflex game that will calculate your responding speed. The rules are simple just press the stop button when you see the change in background color, and the time you took in doing so will be your speed. A faster r
4 min read
How to Build a Simple Swiping Game in Android?
In this article, we are going to create a simple swiping game using RecyclerView in android studio. RecyclerView is the ViewGroup that contains the views corresponding to your data. It's a view itself, so you add RecyclerView into your layout the way you would add any other UI element. We are going to use ItemTouchHelper to implement the swiping fe
6 min read
How to Build a Dice Game in Java Android?
In this article, we will be building a Dice Game Project using Java and XML in Android. The Dice Game is based on a two-player game. Both players roll the dice and the player who gets the highest phase value will win the game. There will be a single activity in this application. This activity will show the two player's name and their dice. The resu
5 min read
How to Build a Number Shapes Android App in Android Studio?
Android is a vast field to learn and explore and to make this learning journey more interesting and productive we should keep trying new problems with new logic. So, today we are going to develop an application in android studio which tells us about Numbers that have shapes. We will be covering two types of numbers i.e. triangular and square. So, f
4 min read
How to Build a Decimal to Binary Converter Android App in Android Studio?
This app will convert a Decimal Number into a Binary Number. Some people may also have written a java program to convert a Decimal Number into Binary Number, but while making an app let's see how to do that. Brief Go through We will start by creating a new project with an Empty Activity. After creating a project, we would add the drawable resource
5 min read
How to Build Binary to Decimal Converter Android App in Android Studio?
This app will convert a Binary Number into a Decimal Number. Some people may also have written a java program to convert a Binary Number into a Decimal Number, but while making an app let's see how to do that. Brief Go Through We will start by creating a new project with an Empty Activity. After creating a project, we would add the drawable resourc
5 min read
How to Build Decimal to Hexadecimal Converter Android App in Android Studio?
In this article, we would be learning how to make a Decimal to Hexadecimal Converter App in Java in Android Studio. This app would take an input of a Decimal number, convert it into a Hexadecimal number and then show the output. So let's go through the brief go through of how we would be making the app. Brief Go through We will begin by first creat
5 min read
Gradle Build Tool I Modern Open Source Build Automation
Recall what are the steps involved in the running of a Java program, the program is first compiled and bytecode is created at the compile time. At the runtime, classes are loaded, bytecode is verified and then the interpreter reads the bytecode and executes the instructions. How does this happen? We simply click on Build and then Run, or just Run (
5 min read
Article Tags :
Practice Tags :