Building Complete Tic-Tac-Toe app in Flutter with Splash Screen


Although this is a pretty simple project with no added dependencies or pulling API requests, there are a couple of things you need, to get started.

How our final product should look

This is our final product UI

This is what we’re aiming to build. It’s a simple Tic Tac Toe application which requires two players to play the game, It has a reset feature which you will be reset game at any time, as your choice

If anyone of the users wants to reset the game midway and try again they can do so by clicking the reset button.

Adding all the assets we’ll need

First things first, let’s add all the images(circle, cross, etc) we’ll be needing during our entire project. Open pubspec.yaml file inside your project folder, and scroll through till you see this.

# To add assets to your application, add an assets section, like this

Now that you’ve added these assets into your project, Flutter will recognize them easily.


Once you are done with adding the assets, go to the lib/main.dart file and delete all the boilerplate code and insert your own themes or app title, etc. Here you’ll link a HomePage class which we’ll create very soon.

in this main file, We used splash Screen package to make more beautiful

Splash Screen

Package Name: splashscreen 1.2.0

  • A small Splash Screen used for an intro for any flutter application easily using For iOS And Android

if you want used the link is here Link

The final outcome of Splash Screen UI like this with a circular progress bar

Now you’ll see a swirly red line at the class declaration and that’s okay to have at this point since we haven’t made that class yet. So let’s go ahead and do that.

Create HomePage.dart File

in this file, we only create a Homepage UI Screen with Drawer bar to make it more beautiful, the UI Screen Like this

FileName: HomePage.dart

Create a Game Play file

File Name: SinglePlayer.dart

Make a new lib/SinglePlayer.dart file, create a Stateful Widget inside of which add three image variables, namely ‘cross’, ‘circle’, ‘empty/edit’ to store all those images we have previously assigned into a variable respectively. Later in this project, we’ll need to return as well as use them for checking purposes so it’s a lot better to store them in a variable beforehand.

Initialize and Reset

Whenever our application loads up for the first time, we want all the boxes to be empty. And the user should be able to tap them and change its state, to do that we need to create a list of strings which should have 9 elements(3 boxes in each row). As we want these elements to be empty whenever the app starts, we need to set the default state to empty.

make sure all in init state

Similarly, create a reset() function which also sets the game state back to empty whenever the user clicks on the Reset Button.

Changing State to Cross or Circle upon user click

To implement this functionality we have implemented a function called playGame(). This function takes the user click as an index number and checks whether the element of the specific index in gameState(lists of String created earlier) is either empty or not.

To set the state to a cross or a circle alternately upon user click we need to initialize a boolean variable which will keep on switching between True and False upon user click.

Whenever it’s true we can set the state to cross and when it’s false we set it to circle or vice versa.

We’ve also created a function of type AssetImage called getImage() — The primary function of this method is to see what is the state of the index in the gameState list(which the user clicks on) and convert that string into an image(circle or cross).

Game Logic

Surprisingly the logic behind this game is actually very simple, and all you have to do is check consecutive indexes and that’s it. Confused? Let me give you an example.

As we’ve already created our list with 9 elements where there are 3 elements in each row, what we actually have to check is whether the 1st element is equal to the 2nd one and whether or not the 2nd element is equal to the next consecutive element, if your answer is true for both the cases! Viola, you’ve got the winner.

Similarly, you should not just check for horizontal elements but also for vertically downward elements as well in which case the index will go like if the 1st element is equal to the 4th and if that is equal to the 7th. It’s all a matter of indexes.

You should keep doing this check for the 3 horizontal rows and also for the 3 vertical columns. Wait a minute! What about the diagonals? We won’t miss that out either, so again we’ll go for index checking of 1,5 and 9 and for the opposite diagonal we go for 3,5 and 7. And that’s it, there is your main game logic.

all the SinglePayer.dart file Here

The UI

In Flutter whenever we want to create something that is boxed or clustered and in a fixed space and size the best option to go for is a Grid Layout. In this project, we use something called GridView.builder(), this builder gives us some properties like itemCount and itemBuilder, which helps us to count the total number of elements which will be present in the grid as well as return specific indexes of those contexts which the user taps on.

source code on Github Link

Thanks for reading through and I hope you liked what you read here. Feel free to comment below your thoughts or any comments/suggestions/feedback on this article or you may also connect with me on Twitter

Passionate Flutter Dev 💙