How To Make A Tic Tac Toe Game Using React Native

how to create tic tac toe game

React Native is one of the most popular frameworks for creating native apps for Android and iOS. Using React Native, you can build cross-platform apps using JavaScript. Not just apps, you can also develop simple games like Tic Tac Toe using React Native framework. In this tutorial, you will learn how to make a tic tac toe game from scratch. The game will also have a reset option, and it will automatically display a pop if there is a game result.

After developing this project, you will learn the basics of React Native development. Now, let’s get started without wasting any time.

Also ReadHow To Use Python For Browser Games Development?

How to make a Tic Tac Toe game using React Native

Step 1: Setting up the development environment

First, let’s set up the development environment.

  1. Install Node.js from here.
  2. After installing Node.js, enter this command in your command line.
npm install expo-cli --global

Your development environment is ready now.

Create a new project using this command and use the App.js file to write the code.

expo init

Now let’s get started.

This is the final code of the app; let’s understand it, part by part.

import React from 'react';
import { StyleSheet, Text, View, Alert, TouchableOpacity } from 'react-native';
import Entypo from "@expo/vector-icons/Entypo"
var board = ["question","question","question","question","question","question","question","question","question"]

export default class App extends React.Component {
  
  constructor(props){
    super(props)
    this.state = {
      isCross:true
    }
  }
  drawItem(number){
   
  
    if(board[number]=="question" && this.winGame()==""){
      if(this.state.isCross)
        board[number] = "cross"
      else  
        board[number] = "circle"


      this.setState({isCross:!this.state.isCross})  
      if(this.winGame()!="")
      Alert.alert(this.winGame()+" Won The Game")   
    }
   
  }

  resetGame = () => {
    this.setState({isCross:true}) 
    board=["question","question","question","question","question","question","question","question","question"]

  }

  chooseItemColor = (number) => {
    if(board[number]=="cross")
      return "#FF3031"
    else if(board[number]=="circle")
      return "#45CE30"
      
    return "#74B9FF"  
  }

  winGame = () => {
    if(board[0] != "question" && board[0] == board[1] && board[1] == board[2]){
      return board[0]
    }else if(board[3] != "question" && board[3] == board[4] && board[4] == board[5]){
      return board[3]
    }else if(board[6] != "question" && board[6] == board[7] && board[7] == board[8]){
      return board[6]
    }else if(board[0] != "question" && board[0] == board[3] && board[3] == board[6]){
      return board[0]
    }else if(board[1] != "question" && board[1] == board[4] && board[4] == board[7]){
      return board[1]
    }else if(board[2] != "question" && board[2] == board[5] && board[5] == board[8]){
      return board[2]
    }else if(board[0] != "question" && board[0] == board[4] && board[4] == board[8]){
      return board[0]
    }else if(board[2] != "question" && board[2] == board[4] && board[4] == board[6]){
      return board[2]
    }else{
      return ""
    }
  }

  render(){
   
    return (
     
          <View style={styles.container}>
                    <Text style={{color:"#01CBC6",fontSize:50}}>Tic Tac Toe</Text>
              
              <View style={{flexDirection:"row"}}>              
                  <TouchableOpacity style={{margin:30,padding:20}} onPress={() => this.drawItem(0)}>
                      <Entypo name={board[0]} size={32} color={this.chooseItemColor(0)} />
                  </TouchableOpacity>          
                  <TouchableOpacity style={{margin:30,padding:20}}  onPress={() => this.drawItem(1)}>
                      <Entypo name={board[1]} size={32} color={this.chooseItemColor(1)} />
                  </TouchableOpacity>          
                  <TouchableOpacity style={{margin:30,padding:20}} onPress={() => this.drawItem(2)}>
                      <Entypo name={board[2]} size={32} color={this.chooseItemColor(2)} />
                  </TouchableOpacity>          
                  
              </View>              
    
              <View style={{flexDirection:"row"}}>              
                  <TouchableOpacity style={{margin:30,padding:20}} onPress={() => this.drawItem(3)}>
                      <Entypo name={board[3]} size={32} color={this.chooseItemColor(3)} />
                  </TouchableOpacity>          
                  <TouchableOpacity style={{margin:30,padding:20}}  onPress={() => this.drawItem(4)}>
                      <Entypo name={board[4]} size={32} color={this.chooseItemColor(4)} />
                  </TouchableOpacity>          
                  <TouchableOpacity style={{margin:30,padding:20}} onPress={() => this.drawItem(5)}>
                      <Entypo name={board[5]} size={32} color={this.chooseItemColor(5)} />
                  </TouchableOpacity>          
                  
              </View>     
                      
              <View style={{flexDirection:"row"}}>              
                  <TouchableOpacity style={{margin:30,padding:20}} onPress={() => this.drawItem(6)}>
                      <Entypo name={board[6]} size={32} color={this.chooseItemColor(6)} />
                  </TouchableOpacity>          
                  <TouchableOpacity style={{margin:30,padding:20}}  onPress={() => this.drawItem(7)}>
                      <Entypo name={board[7]} size={32} color={this.chooseItemColor(7)} />
                  </TouchableOpacity>          
                  <TouchableOpacity style={{margin:30,padding:20}} onPress={() => this.drawItem(8)}>
                      <Entypo name={board[8]} size={32} color={this.chooseItemColor(8)} />
                  </TouchableOpacity>          
                  
              </View>              
    
              <TouchableOpacity style={{margin:30,flexDirection:"row",padding:20,backgroundColor:"#E74292",width:200,borderRadius:20}} onPress={()=>this.resetGame()}>
                      <Entypo name="controller-jump-to-start" size={32} color="#2B2B52" />
                      <Text style={{color:"#2B2B52",fontSize:20}}>Restart Game</Text>
              </TouchableOpacity>                 
          </View>
      )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Also Read7 Best Online Reputation Management Tools For Your Business.

Step 2: Deciding the turn of players

First, we import the required packages.

import React from 'react';
import { StyleSheet, Text, View, Alert, TouchableOpacity } from 'react-native';
import Entypo from "@expo/vector-icons/Entypo"

Now in the constructor, we create a state object in which we have a boolean named isCross.

constructor(props){ 
    super(props) 
    this.state = { isCross:true }
}

This isCross is true when it’s turn for Cross to play and false if it’s Circle’s turn.

We have also created an array called board, which stores whether a particular board position has been captured by either Cross or Circle or No One. Each of these things is denoted by “cross,” “circle,” or “question,” respectively.

Fortunately, “cross,” “circle,” or “question” are also the names of their vector icons in the Entypo library.

You may ask, what is Entypo? It is a Library in Expo to show vector icons without importing any image file separately and using Entypo’s own Vector Image Gallery.

Ok, now it would be great if we can assign different colors to our Cross and Circle. To do that, we have a method named chooseItemColor.

chooseItemColor = (number) => { 
  if(board[number]=="cross")
     return "#FF3031" 
  else if(board[number]=="circle") 
     return "#45CE30" 
 return "#74B9FF" 
}

For every given array item, it returns red color for Cross, green color for Circle, and blue color for Question mark icon.

Step 3: Capture player’s input

Now we have the function to capture places by each player named drawItem.

drawItem(number){
 if(board[number]=="question" && this.winGame()==""){
    if(this.state.isCross) 
       board[number] = "cross" 
    else 
       board[number] = "circle" 
    this.setState({isCross:!this.state.isCross}) 
    if(this.winGame()!="") 
      Alert.alert(this.winGame()+" Won The Game") 
  } 
}

So, this function accepts a parameter named number, which is essentially the board’s position number.

Now in the first if statement, it is checked whether the given item is “question” or not, or in other words, if it is already captured or not. If it is equal to “question,” it checks the second condition.

In the second condition, a function named winGame is called, which we will explain later. It is used to check whether the game has already been won or not.

Now we check whether it is Cross’s turn or circle’s turn by checking the isCross boolean of our state, and then we assign the respective player to that board number.

After that, we set the turn to the next player’s using this.setState.

Now in the last if statement, we again call the winGame method and check whether if anybody wins the game in this turn. If anyone wins the game, we show a popup using Alert to the user, as shown in the screenshot below.

who won tic tac toe game react native

Step 4: Checking who won the Tic Tac Toe game

Now let’s look at our winGame method.

winGame = () => {
if(board[0] != "question" && board[0] == board[1] && board[1] == board[2]){ 
  return board[0]
}else if(board[3] != "question" && board[3] == board[4] && board[4] == board[5]){ 
  return board[3]
}else if(board[6] != "question" && board[6] == board[7] && board[7] == board[8]){ 
  return board[6] 
}else if(board[0] != "question" && board[0] == board[3] && board[3] == board[6]){ 
  return board[0]
}else if(board[1] != "question" && board[1] == board[4] && board[4] == board[7]){ 
 return board[1] 
}else if(board[2] != "question" && board[2] == board[5] && board[5] == board[8]){ 
 return board[2] 
}else if(board[0] != "question" && board[0] == board[4] && board[4] == board[8]){ 
 return board[0] 
}else if(board[2] != "question" && board[2] == board[4] && board[4] == board[6]){
 return board[2]
}else{
  return "" 
} 
}

In a Tic Tac Toe game, we have 8 patterns to win the game, as shown in the image below.

tic tac toe game patterns

So in this function, using if conditions we check whether any player captures any of these patterns, and then we return that value.

Now, what if the user wants to reset the game? We have a function called resetGame for it also.

This function is quite simple.

resetGame = () => { 
 this.setState({isCross:true})
 board=["question","question","question","question","question","question","question","question","question"] 
}

We set the turn again to Cross, and then we set all board positions to uncaptured or “question.”

Also Read7 Useful Tips To Learn Software Development For Beginners.

Step 5: Designing Tic Tac Toe game interface

Now we have covered all the functionality part, let’s move to the design part of our Tic Tac Toe game.

In the render function, we are returning the main view whose style is named container, and then we have a text for the main title.

<View style={styles.container}> 
  <Text style={{color:"#01CBC6",fontSize:50}}>Tic Tac Toe</Text>
</View>

Now inside that we create a new view for each of the three rows of a Tic Tac Toe board and set it’s flex-direction to row.

Now inside that, we created 3 Entypo icon objects wrapped by TouchableOpacity to make them clickable.

<View style={{flexDirection:"row"}}>
 <TouchableOpacity style={{margin:30,padding:20}} onPress={() => this.drawItem(0)}>
   <Entypo name={board[0]} size={32} color={this.chooseItemColor(0)} />
 </TouchableOpacity> 

 <TouchableOpacity style={{margin:30,padding:20}} onPress={() => this.drawItem(1)}> 
   <Entypo name={board[1]} size={32} color={this.chooseItemColor(1)} />
 </TouchableOpacity> 

 <TouchableOpacity style={{margin:30,padding:20}} onPress={() => this.drawItem(2)}> 
   <Entypo name={board[2]} size={32} color={this.chooseItemColor(2)} />
 </TouchableOpacity>
</View>

Each Entypo object’s icon is set by using the name prop and assigning the board’s value at that position to it so that it shows those respective items. The same has been done for color using chooseItemColor.

This Entypo object is wrapped by a TouchableOpacity whose onPress prop is set to drawItem so that when it is clicked, it is captured by the player whose turn it was when this particular position was clicked.

That was it, and now we create three such rows for a total of 9 positions.

At last, we add a Reset button to reset the game.

<TouchableOpacity style={{margin:30,flexDirection:"row",padding:20,backgroundColor:"#E74292",width:200,borderRadius:20}} onPress={()=>this.resetGame()}> 
    <Entypo name="controller-jump-to-start" size={32} color="#2B2B52" /> 
    <Text style={{color:"#2B2B52",fontSize:20}}>Restart Game</Text>
</TouchableOpacity>

Step 6: Run the app

Now our app is complete; let’s see how it looks.

tic tac toe game react native

You can run this app using npm start command in the command line of your project’s directory.

I hope you enjoyed making this Tic Tac Toe app with us. Now let’s catch up in the next post. Subscribe to our mailing list to get all the latest updates straight in your inbox.

Scroll to Top