import 'package:flutter/material.dart';
// Running the Application
void main() {
runApp(const MyApp());
}
// Stateless widget representing the main application
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Tic Tac Toe', // Application title
debugShowCheckedModeBanner: false, // Disable debug banner
home: TicTacToePage(), // Set TicTacToePage as the home page
);
}
}
// Stateful widget representing the Tic Tac Toe game page
class TicTacToePage extends StatefulWidget {
const TicTacToePage({super.key});
@override
State<TicTacToePage> createState() => _TicTacToePageState();
}
// State class for the Tic Tac Toe game logic and UI
class _TicTacToePageState extends State<TicTacToePage> {
// List to store the moves on the board
List<String> moves = List.filled(9, "-");
// Variable to track the current move
String currentMove = "X";
// Variable to count the number of moves made
int count = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
'Tic Tac Toe',
style: TextStyle(fontSize: 28, fontWeight: FontWeight.w600),
), // AppBar title
centerTitle: true, // Center the title
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Current Move: $currentMove", // Display the current move
style: const TextStyle(fontSize: 25, fontWeight: FontWeight.w600),
),
const SizedBox(height: 20), // Spacer
SizedBox(
height: 300,
width: 300,
child: GridView.builder(
primary: true,
padding: const EdgeInsets.all(6),
itemCount: 9, // Number of items in the grid
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
), // 3x3 grid
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
if (moves[index] == "-") {
setState(() {
// Update the move
moves[index] = currentMove;
// Switch to the next move
currentMove = currentMove == "O" ? "X" : "O";
// Increment the move count
count++;
// Check for a winner or draw
if (_checkWinner()) {
_showDialog(
context,
"Winner!",
"The winner is ${moves[index]}",
);
} else if (count == 9) {
_showDialog(context, "Draw!", "Match is DRAW");
}
});
}
},
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black), // Cell border
color:
moves[index] == "-"
? Colors
.white // Empty cell color
: (moves[index] == "X"
? Colors
.blue
.shade100 // X cell color
: Colors.red.shade100), // O cell color
),
child: Center(
child: Text(
moves[index], // Display the move
style: const TextStyle(
color: Colors.black,
fontSize: 40,
fontWeight: FontWeight.bold,
),
),
),
),
);
},
),
),
const SizedBox(height: 20), // Spacer
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.black,
foregroundColor: Colors.white,
),
onPressed: _resetGame, // Restart game button
child: const Text("Restart Game"),
),
],
),
),
);
}
// Method to reset the game state
void _resetGame() {
setState(() {
moves = List.filled(9, "-"); // Reset moves
currentMove = "X"; // Reset to initial move
count = 0; // Reset move count
});
}
// Method to check for a winning combination
bool _checkWinner() {
List<List<int>> winningCombinations = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
for (var combo in winningCombinations) {
if (moves[combo[0]] != "-" &&
moves[combo[0]] == moves[combo[1]] &&
moves[combo[1]] == moves[combo[2]]) {
return true;
}
}
return false;
}
// Method to display a dialog with the game result
void _showDialog(BuildContext context, String title, String content) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text(title), // Dialog title
content: Text(content), // Dialog content
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(); // Close the dialog
_resetGame(); // Reset the game
},
child: const Text("Play Again"),
),
],
);
},
);
}
}