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 Read: How 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.
- Install Node.js from here.
- 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 Read: 7 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.
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.
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 Read: 7 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.
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.
Avid Android developer with 2 years of experience. Reading books and stay updated with the latest development trends is all I do :)