- Introduction
- Features
- Usage
- Technology Stack
- Database Schema
- API Endpoints
- Socket.IO Events
- Setup and Installation
- Configuration
- License
This project is a multiplayer Tic-Tac-Toe game implemented using Flask for the backend, Socket.IO for real-time communication, and MongoDB for data persistence. It allows users to register, login, play games against each other in real-time, and track their performance on a leaderboard.
- User authentication (register, login, logout)
- Real-time multiplayer gameplay
- Leaderboard system
- Game history tracking
- Responsive design for various screen sizes
The Tic-Tac-Toe game can be played in three different modes: Local, Multiplayer, and AI. Below are the details for each mode:
In Local Mode, two players can play the game on the same device. Each player takes turns to make a move. The game board is displayed on the screen, and players can click on the cells to place their markers (X or O). The game continues until one player wins or the game ends in a draw.
To play in Local Mode:
- Open the game on your device.
- Select the "Local" option from the main menu.
- The game board will be displayed, and Player X will make the first move.
- Players take turns to make their moves by clicking on the cells.
- The game will automatically detect a win or a draw and display the result.
In Multiplayer Mode, players can play the game against each other online. The game uses Socket.IO for real-time communication between players. Each player needs to be connected to the internet and logged in to play in this mode.
To play in Multiplayer Mode:
- Open the game on your device.
- Select the "Multiplayer" option from the main menu.
- Log in with your credentials or register if you don't have an account.
- The game will search for an available opponent. If an opponent is found, the game will start.
- Players take turns to make their moves. The game board will be updated in real-time for both players.
- The game will automatically detect a win or a draw and display the result.
In AI Mode, players can play the game against an AI algorithm. The AI uses the Minimax algorithm to make its moves. Players can choose the difficulty level (easy, medium, or difficult) before starting the game.
To play in AI Mode:
- Open the game on your device.
- Select the "AI" option from the main menu.
- Choose the difficulty level (easy, medium, or difficult).
- The game board will be displayed, and Player X will make the first move.
- Players take turns to make their moves by clicking on the cells. The AI will make its move after the player.
- The game will automatically detect a win or a draw and display the result.
Each mode provides a unique experience, allowing players to enjoy the game in different ways. Whether you want to play with a friend on the same device, challenge someone online, or test your skills against an AI, this Tic-Tac-Toe game has you covered.
- Backend: Flask (Python)
- Database: MongoDB
- Real-time Communication: Socket.IO
- Frontend: React, TypeScript, Vite
- Styling: Tailwind CSS
- Authentication: Flask sessions
- WSGI Server: Gunicorn
- Web Server: Nginx (for production deployment)
- Containerization: Docker
Refer to the schema documentation for detailed information about the database collections and their schemas.
Refer to the API routes documentation for detailed information about the available API endpoints, their descriptions, request bodies, and responses.
- Description: Triggered when a client connects to the server.
- Behavior:
- Retrieves the player's ID from the session.
- If the player is not logged in, emits an error message and denies the connection.
- Checks if the player is already in a waiting or ongoing game. If so, emits an error message and denies the connection.
- If the player is successfully connected, prints a connection message.
- Description: Triggered when a client disconnects from the server.
- Behavior:
- Retrieves the player's ID from the session.
- Handles the disconnection by updating the game state.
- If the player was in a game, emits a
game_over
event indicating the opponent's win due to disconnection. - Updates the user's win/loss statistics.
- Description: Triggered when a player joins a game.
- Behavior:
- Retrieves the player's ID from the session.
- Checks if the player is already in a waiting or ongoing game. If so, emits an error message.
- Searches for a waiting game. If found, the player joins the game and the game starts.
- If no waiting game is found, creates a new game and the player joins it, waiting for an opponent.
- Description: Triggered when a player makes a move in the game.
- Behavior:
- Retrieves the game ID, player ID, and move position from the data.
- Validates the game state and the player's turn.
- Processes the move and updates the game board.
- Emits a
move_made
event to update the game state for all players. - If the game ends event and updates the user and leaderboard statistics accordingly.
- Description: Triggered when the game ends.
- Behavior:
- This event is emitted internally by the server when a game concludes due to a win, loss, or draw.
- Updates the game state and user statistics.
- Notifies all players in the game room about the game result.
To set up and run the application using Docker Compose, follow these steps:
-
Ensure you have Docker and Docker Compose installed on your system.
-
Clone the repository:
git clone https://github.com/hackersa3edy/tic_tac_toe.git cd tic-tac-toe
-
Create a
.env
file in the server directory to add your environment variables. Refer to the example file. -
Run the application using Docker Compose:
docker-compose -f docker-compose.yml up --build
Using Docker Compose is preferred because:
- Consistency: Ensures the application runs in the same environment across different machines.
- Isolation: Keeps the application dependencies isolated from the host system.
- Ease of Setup: Simplifies the setup process by handling dependencies and configurations automatically.
- Scalability: Makes it easier to scale services and manage multiple containers.
If you prefer not to use Docker, follow these steps:
-
Clone the repository:
git clone https://github.com/hackersa3edy/tic_tac_toe.git cd tic-tac-toe
-
Set up a virtual environment:
python -m venv venv source venv/bin/activate # On Windows use venv\Scripts\activate
For me, I'm using virtualenvwrapper. It's cool. Give it a try: virtualenvwrapper
-
Install the required packages:
pip install -r requirements.txt
-
Set up MongoDB:
- Install MongoDB on your system.
- Initialize it with a username and password, if needed.
-
Set up environment variables: Create a
.env
file in the server directory to add your environment variables. Refer to the example file. -
Build the client:
cd Client npm install npm run build cd ..
-
Copy the built static files to the server to be served.
cp -r Client/dist/* server/static
-
Run the application:
For development:
cd server python app.py
For production:
cd server gunicorn --worker-class eventlet -w 1 app:app --bind 0.0.0.0:3000
Configuration settings are managed in config.py
. Different configurations are available for development, testing, and production environments.
- Noor Amjad - GitHub / Twitter / LinkedIn
- Amr Abdelfattah - GitHub / Twitter / LinkedIn
- Ahmed Shalaby - GitHub / Twitter / LinkedIn
- Ahmed Aboalesaad - GitHub / Twitter / LinkedIn
- Abdelrahman Mohamed - GitHub / Twitter / LinkedIn
- Kedir Jabir - GitHub / Twitter / LinkedIn
Copyright (C) 2024 Licensed under the GPLv3 License