6/recent/ticker-posts

Tic Tac Toe Game in Flutter

In this comprehensive tutorial, we will walk through the process of creating a Tic-Tac-Toe game using the Flutter framework. Tic-Tac-Toe is a popular two-player game where the objective is to create a line of three matching symbols on a 3x3 grid. By following this step-by-step guide, you will gain a solid understanding of Flutter’s widget system and how to implement game logic, handle user interactions, and create an engaging user interface.

The provided code is an implementation of a Tic-Tac-Toe game using the Flutter framework. Below is a step-by-step documentation and its functionality:

1. Import necessary dependencies:

import 'package:flutter/material.dart';

2. Create a class named TicTocToeGame that extends StatefulWidget:

class TicTocToeGame extends StatefulWidget {
const TicTocToeGame({Key? key});

@override
State<TicTocToeGame> createState()
=> _TicTocToeGameState(); }

3. Create a private class _TicTocToeGameState that extends State<TicTocToeGame>:

class _TicTocToeGameState extends State<TicTocToeGame> {

// Declare necessary variables
bool oTurn = true;
List<String> displayElement = ['', '', '', '', '', '', '', '', '', ''];
int oScore = 0;
int xScore = 0;
int filledBoxes = 0;

// Implement methods and logic for the Tic-Tac-Toe game ...

}

4. Inside the _TicTocToeGameState, implement the _clearBoard method:

void _clearBoard() {  
setState(() {
for (int i = 0; i < 9; i++) {
displayElement[i] = '';
}
});
filledBoxes = 0;
}

5. Implement the _clearScoreBoard method:

void _clearScoreBoard() {
setState(() {
xScore = 0;
oScore = 0;
for (int i = 0; i < 9; i++) {
displayElement[i] = '';
}
});
filledBoxes = 0;
}

6.Implement the _showDrawDialog method:

void _showDrawDialog() {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Draw'),
actions: [
GestureDetector(
child: const Text('Play Again'),
onTap: () {
_clearBoard();
Navigator.of(context).pop();
},
)
],
);
},
);
}

7. Implement the _tapped method to handle user interactions with the game board:

void _tapped(int index) {
setState(() {
if (oTurn && displayElement[index] == '') {
displayElement[index] = 'O';
filledBoxes++;
} else if (!oTurn && displayElement[index] == '') {
displayElement[index] = 'X';
filledBoxes++;
}
oTurn = !oTurn;
_checkWinner();
});
}

8. Implement the _checkWinner method to check for a winning condition after each move:

void _checkWinner() {

// Check all possible winning combinations
if (displayElement[0] == displayElement[1] &&
displayElement[0] == displayElement[2] &&
displayElement[0] != '') {
_showWinDialog(displayElement[0]);
}
// Check other winning combinations
...
// Check if it's a draw if (filledBoxes == 9) {
_showDrawDialog();
}
}

9.Implement the _showWinDialog method to display a dialog when a player wins:

void _showWinDialog(String winner) {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) {
return AlertDialog(
title: Text('\' $winner\' is the winner!'),
actions: [
GestureDetector(
child: const Text('Play Again'),
onTap: () {
_clearBoard();
Navigator.of(context).pop();
},
)
],
);
},
);
// Update the scores based on the winner
if (winner == 'O') {
oScore++;
} else if (winner == 'X') {
xScore++;
}
}

10. Override the build method to create the game UI:

@override Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.indigo[900],
body: Column(
children: [
// Display player scores
Expanded(
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Player X',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
Text(
xScore.toString(),
style: const TextStyle(fontSize: 20, color: Colors.white),
),
],
),
),
// Display player O's score
// ...
],
),
),
),
// Display the Tic-Tac-Toe game board
Expanded(
flex: 4,
child: GridView.builder(
itemCount: 9,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
_tapped(index);
},
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.white),
),
child: Center(
child: Text(
displayElement[index],
style: const TextStyle(color: Colors.white, fontSize: 35),
),
),
),
);
},
),
),
// Button to clear the score board
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: _clearScoreBoard,
child: const Text('Clear Scoreboard'),
),
],
),
),
],
),
);
}

The code sets up a basic Tic-Tac-Toe game UI, tracks player scores, and handles user interactions with the game board. The game logic determines the winner or a draw and displays appropriate dialogs.

Code :

import 'package:flutter/material.dart';

class TicTocToeGame extends StatefulWidget {
const TicTocToeGame({super.key});

@override
State<TicTocToeGame> createState() => _TicTocToeGameState();
}

class _TicTocToeGameState extends State<TicTocToeGame> {
bool oTurn = true;
List<String> displayElement = ['', '', '', '', '', '', '', '', '', ''];
int oScore = 0;
int xScore = 0;
int filledBoxes = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.indigo[900],
body: Column(
children: [
Expanded(
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'player X',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white),
),
Text(
xScore.toString(),
style: const TextStyle(fontSize: 20, color: Colors.white),
)
],
),
),
Padding(
padding: const EdgeInsets.all(30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'player Y',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white),
),
Text(
oScore.toString(),
style: const TextStyle(fontSize: 20, color: Colors.white),
)
],
),
),
],
),
)),
Expanded(
flex: 4,
child: GridView.builder(
itemCount: 9,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
_tapped(index);
},
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.white),
),
child: Center(
child: Text(
displayElement[index],
style: const TextStyle(color: Colors.white, fontSize: 35),
),
),
),
);
},
)),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: _clearScoreBoard,
child: const Text('Clear score board'))
],
))
],
),
);
}

void _tapped(int index) {
setState(() {
if (oTurn && displayElement[index] == '') {
displayElement[index] = 'O';
filledBoxes++;
} else if (!oTurn && displayElement[index] == '') {
displayElement[index] = 'X';
filledBoxes++;
}
oTurn = !oTurn;
_checkWinner();
});
}

void _checkWinner() {
if (displayElement[0] == displayElement[1] &&
displayElement[0] == displayElement[2] &&
displayElement[0] != '') {
_showWinDialog(displayElement[0]);
}
if (displayElement[3] == displayElement[4] &&
displayElement[3] == displayElement[5] &&
displayElement[3] != '') {
_showWinDialog(displayElement[3]);
}
if (displayElement[6] == displayElement[7] &&
displayElement[6] == displayElement[8] &&
displayElement[6] != '') {
_showWinDialog(displayElement[6]);
}

if (displayElement[0] == displayElement[3] &&
displayElement[0] == displayElement[6] &&
displayElement[0] != '') {
_showWinDialog(displayElement[0]);
}
if (displayElement[1] == displayElement[4] &&
displayElement[1] == displayElement[7] &&
displayElement[1] != '') {
_showWinDialog(displayElement[1]);
}
if (displayElement[2] == displayElement[5] &&
displayElement[2] == displayElement[8] &&
displayElement[2] != '') {
_showWinDialog(displayElement[2]);
}

if (displayElement[0] == displayElement[4] &&
displayElement[0] == displayElement[8] &&
displayElement[0] != '') {
_showWinDialog(displayElement[0]);
}
if (displayElement[2] == displayElement[4] &&
displayElement[2] == displayElement[6] &&
displayElement[2] != '') {
_showWinDialog(displayElement[2]);
} else if (filledBoxes == 9) {
_showDrawDialog();
}
}

void _showWinDialog(String winner) {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) {
return AlertDialog(
title: Text('\' $winner\' is winner !!!'),
actions: [
GestureDetector(
child: const Text('play Again'),
onTap: () {
_clearBoard();
Navigator.of(context).pop();
},
)
],
);
},
);
if (winner == 'O') {
oScore++;
} else if (winner == 'X') {
xScore++;
}
}

void _showDrawDialog() {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Draw'),
actions: [
GestureDetector(
child: const Text('paly Again'),
onTap: () {
_clearBoard();
Navigator.of(context).pop();
},
)
],
);
},
);
}

void _clearBoard() {
setState(() {
for (int i = 0; i < 9; i++) {
displayElement[i] = '';
}
});
filledBoxes = 0;
}

void _clearScoreBoard() {
setState(() {
xScore = 0;
oScore = 0;
for (int i = 0; i < 9; i++) {
displayElement[i] = '';
}
});
filledBoxes = 0;
}
}

Output:



follow my Instagram account :

https://www.instagram.com/nature.pulse_/

Conclusion:

Congratulations! You have successfully built a fully functional Tic-Tac-Toe game using Flutter. Throughout this tutorial, we covered various essential aspects of Flutter development, including creating a responsive user interface, handling user interactions, and implementing game logic.

By following this step-by-step guide, you have gained valuable experience in using Flutter’s widget system, state management, and UI design principles. Additionally, you have learned how to handle user input, track game state, and display dialog boxes to indicate game results.

Now that you have a solid foundation in Flutter development, you can apply these skills to create more complex and interactive applications. Consider adding additional features to your Tic-Tac-Toe game, such as multiplayer functionality, improved UI elements, or even exploring different game algorithms.

Remember to experiment and personalize your projects to make them unique. Flutter offers a vast range of widgets and customization options, allowing you to create stunning and engaging user experiences.

Keep practicing, exploring Flutter’s capabilities, and building exciting applications. The skills you’ve gained from this tutorial will serve as a strong foundation for your future Flutter projects. Happy coding!


Post a Comment

0 Comments