|
| 1 | +# Tic-Tac-Toe Architecture Documentation |
| 2 | + |
| 3 | +## Project Definition |
| 4 | + |
| 5 | +This is a command-line Tic-Tac-Toe game implementation written in Rust. It provides an interactive game experience where players can either compete against each other or play against a computer opponent on a classic 3x3 grid. |
| 6 | + |
| 7 | +### Goals |
| 8 | +The main goals of this project are: |
| 9 | +- Provide an intuitive and user-friendly command-line interface for playing Tic-Tac-Toe |
| 10 | +- Offer three game modes: player vs player, player vs random AI, and player vs intelligent AI |
| 11 | +- Implement two AI opponents: one that plays randomly and one using the Minimax algorithm |
| 12 | +- Demonstrate the Minimax algorithm for perfect play in a zero-sum game |
| 13 | +- Implement game logic with proper validation and win detection |
| 14 | +- Demonstrate clean code architecture with separation of concerns |
| 15 | + |
| 16 | +## Components and Modules |
| 17 | + |
| 18 | +The project is structured into two main modules: |
| 19 | + |
| 20 | +### 1. Game Module (`src/game.rs`) |
| 21 | +This module contains the core game logic and data structures. |
| 22 | + |
| 23 | +**Key Components:** |
| 24 | + |
| 25 | +- **`Cell` enum**: Represents the state of a single cell on the board |
| 26 | + - `Empty`: Unoccupied cell |
| 27 | + - `X`: Cell occupied by player X |
| 28 | + - `O`: Cell occupied by player O |
| 29 | + |
| 30 | +- **`TicTacToe` struct**: The main game state container |
| 31 | + - Stores the 3x3 board as a 2D array of `Cell` values |
| 32 | + - Encapsulates all game logic |
| 33 | + |
| 34 | +**Methods:** |
| 35 | + |
| 36 | +- `new()`: Creates a new game with an empty board |
| 37 | +- `display()`: Renders the current board state to the console |
| 38 | +- `place(row, col, player)`: Attempts to place a player's symbol at the specified position |
| 39 | +- `is_full()`: Checks if the board is completely filled |
| 40 | +- `check_winner()`: Analyzes the board to detect if a player has won |
| 41 | +- `get_empty_cells()`: Returns a vector of all available (empty) cell coordinates |
| 42 | +- `unplace(row, col)`: Removes a symbol from a cell (utility function) |
| 43 | +- `evaluate()`: Evaluates the current board state and returns a score (+10 for O win, -10 for X win, 0 for draw) |
| 44 | +- `minimax(is_maximizing)`: Recursive implementation of the Minimax algorithm to find optimal moves |
| 45 | +- `find_best_move()`: Uses Minimax to determine the best possible move for the computer |
| 46 | + |
| 47 | +### 2. Main Module (`src/main.rs`) |
| 48 | +This module handles user interaction and game flow. |
| 49 | + |
| 50 | +**Responsibilities:** |
| 51 | + |
| 52 | +- Presents a menu to choose between three game modes (player vs player, player vs random AI, or player vs Minimax AI) |
| 53 | +- Manages the game loop for all three modes |
| 54 | +- Handles user input and validation |
| 55 | +- Converts user coordinates (1-3) to internal array indices (0-2) |
| 56 | +- Implements two computer opponent strategies: random move selection and Minimax algorithm |
| 57 | +- Alternates between players (or player and computer) |
| 58 | +- Displays game status and results |
| 59 | + |
| 60 | +**Game Modes:** |
| 61 | + |
| 62 | +- **Two Players Mode** (`play_two_players()`): Traditional gameplay where two human players alternate turns |
| 63 | +- **Random Computer Mode** (`play_against_computer()`): Single player mode where the human plays as X and the computer plays as O, selecting random moves from available cells (easy difficulty) |
| 64 | +- **Minimax Computer Mode** (`play_against_minimax()`): Single player mode where the computer uses the Minimax algorithm to play optimally, making it unbeatable (impossible difficulty) |
| 65 | + |
| 66 | +### Architecture Justification |
| 67 | + |
| 68 | +The separation between game logic (`game.rs`) and user interface (`main.rs`) follows the **separation of concerns** principle: |
| 69 | + |
| 70 | +1. **Maintainability**: Game logic can be modified without affecting the UI, and vice versa |
| 71 | +2. **Testability**: The game module can be unit tested independently |
| 72 | +3. **Extensibility**: Easy to add new interfaces (GUI, web) or AI players without modifying core logic |
| 73 | +4. **Reusability**: The game module can be used in different contexts |
| 74 | + |
| 75 | +This modular approach makes the codebase clean, organized, and ready for future enhancements. |
| 76 | + |
| 77 | +## The Minimax Algorithm |
| 78 | + |
| 79 | +### Overview |
| 80 | + |
| 81 | +The Minimax algorithm is a decision-making algorithm used in game theory and artificial intelligence. It's particularly effective for two-player zero-sum games like Tic-Tac-Toe, where one player's gain is the other player's loss. |
| 82 | + |
| 83 | +### How It Works |
| 84 | + |
| 85 | +The algorithm explores all possible game states recursively and assigns scores to terminal states (win, lose, or draw). It then propagates these scores back up the game tree to determine the best move. |
| 86 | + |
| 87 | +**Scoring System:** |
| 88 | +- +10: Computer (O) wins |
| 89 | +- -10: Human player (X) wins |
| 90 | +- 0: Draw or non-terminal state |
| 91 | + |
| 92 | +**Algorithm Steps:** |
| 93 | + |
| 94 | +1. **Base Cases**: If the game is over (win, lose, or draw), return the evaluation score |
| 95 | +2. **Maximizing Player (Computer - O)**: Try all possible moves and choose the one with the highest score |
| 96 | +3. **Minimizing Player (Human - X)**: Try all possible moves and choose the one with the lowest score |
| 97 | +4. **Recursion**: For each possible move, simulate it and recursively call Minimax for the opponent's turn |
| 98 | +5. **Backtracking**: After exploring a move, undo it and try the next one |
| 99 | + |
| 100 | +### Implementation Details |
| 101 | + |
| 102 | +The implementation consists of three key functions: |
| 103 | + |
| 104 | +1. **`evaluate()`**: Evaluates the current board state |
| 105 | + - Returns +10 if O wins |
| 106 | + - Returns -10 if X wins |
| 107 | + - Returns 0 for draw or ongoing game |
| 108 | + |
| 109 | +2. **`minimax(is_maximizing)`**: The core recursive algorithm |
| 110 | + - Takes a boolean indicating whether it's the maximizing player's turn |
| 111 | + - Explores all possible moves recursively |
| 112 | + - Returns the best score achievable from the current state |
| 113 | + |
| 114 | +3. **`find_best_move()`**: Entry point for the AI |
| 115 | + - Tests all available moves |
| 116 | + - Calls `minimax()` for each move |
| 117 | + - Returns the move with the highest score |
| 118 | + |
| 119 | +### Why It's Unbeatable |
| 120 | + |
| 121 | +For a game as simple as Tic-Tac-Toe (3x3 grid with ~255,168 possible games), the Minimax algorithm can explore the entire game tree in milliseconds. This means: |
| 122 | + |
| 123 | +- The computer always knows the outcome of every possible move sequence |
| 124 | +- It will never make a mistake |
| 125 | +- Best case for the human player: Draw (if they also play perfectly) |
| 126 | +- If the human makes any mistake, the computer will exploit it and win |
| 127 | + |
| 128 | +## Usage |
| 129 | + |
| 130 | +### Prerequisites |
| 131 | +- Rust toolchain installed (rustc, cargo) |
| 132 | + |
| 133 | +### Running the Game |
| 134 | + |
| 135 | +1. Navigate to the project directory: |
| 136 | +```bash |
| 137 | +cd topics/tic-tac-toe |
| 138 | +``` |
| 139 | + |
| 140 | +2. Run the game: |
| 141 | +```bash |
| 142 | +cargo run |
| 143 | +``` |
| 144 | + |
| 145 | +### How to Play |
| 146 | + |
| 147 | +1. The game starts with a menu asking you to choose a game mode: |
| 148 | + - **Mode 1**: Two players (human vs human) |
| 149 | + - **Mode 2**: Against the computer with random moves (easy - beatable) |
| 150 | + - **Mode 3**: Against the computer with Minimax algorithm (impossible - unbeatable) |
| 151 | +2. Enter `1`, `2`, or `3` to select your preferred mode |
| 152 | +3. In two-player mode, players X and O alternate turns |
| 153 | +4. In computer modes, you play as X and the computer plays as O |
| 154 | +5. Enter coordinates as two numbers separated by a space: `row column` |
| 155 | +6. Valid coordinates range from 1 to 3 for both row and column |
| 156 | +7. In Mode 2, the computer selects moves randomly from available cells |
| 157 | +8. In Mode 3, the computer uses Minimax to always play the optimal move |
| 158 | + |
| 159 | +### Examples |
| 160 | + |
| 161 | +**Grid Numbering:** |
| 162 | +``` |
| 163 | +(1,1) | (1,2) | (1,3) |
| 164 | +--------- |
| 165 | +(2,1) | (2,2) | (2,3) |
| 166 | +--------- |
| 167 | +(3,1) | (3,2) | (3,3) |
| 168 | +``` |
| 169 | + |
| 170 | +**Sample Game Session (Minimax Mode):** |
| 171 | +``` |
| 172 | +=== Tic-Tac-Toe === |
| 173 | +Choisissez le mode de jeu : |
| 174 | +1. Deux joueurs |
| 175 | +2. Contre l'ordinateur (aléatoire) |
| 176 | +3. Contre l'ordinateur (Minimax - imbattable) |
| 177 | +> 3 |
| 178 | +
|
| 179 | +=== Mode Contre l'Ordinateur (Minimax) === |
| 180 | +Vous êtes X, l'ordinateur est O |
| 181 | +L'ordinateur utilise l'algorithme Minimax - il est imbattable ! |
| 182 | +Entrez les coordonnées comme : ligne colonne (1-3) |
| 183 | +Exemple : 1 1 pour le coin supérieur gauche |
| 184 | +
|
| 185 | +. . . |
| 186 | +--------- |
| 187 | +. . . |
| 188 | +--------- |
| 189 | +. . . |
| 190 | +
|
| 191 | +Votre tour (X), entrez votre coup (ligne colonne) : |
| 192 | +> 2 2 |
| 193 | +
|
| 194 | +L'ordinateur calcule le meilleur coup (Minimax)... |
| 195 | +L'ordinateur joue en (1, 1) |
| 196 | +
|
| 197 | +O . . |
| 198 | +--------- |
| 199 | +. X . |
| 200 | +--------- |
| 201 | +. . . |
| 202 | +
|
| 203 | +... (game continues) |
| 204 | +``` |
| 205 | + |
| 206 | +### Common Commands |
| 207 | + |
| 208 | +- **Place a move**: Enter `row column` (e.g., `1 1` for top-left corner) |
| 209 | +- **Invalid moves**: The game will display an error message and allow you to try again |
| 210 | + |
| 211 | +### Win Conditions |
| 212 | + |
| 213 | +The game automatically detects when: |
| 214 | +- A player gets three symbols in a row (horizontally, vertically, or diagonally) |
| 215 | +- The board is full with no winner (draw) |
| 216 | + |
| 217 | +### Example Winning Scenarios |
| 218 | + |
| 219 | +**Horizontal Win:** |
| 220 | +``` |
| 221 | +X X X <- Player X wins |
| 222 | +--------- |
| 223 | +O O . |
| 224 | +--------- |
| 225 | +. . . |
| 226 | +``` |
| 227 | + |
| 228 | +**Vertical Win:** |
| 229 | +``` |
| 230 | +X O . |
| 231 | +--------- |
| 232 | +X O . <- Player O wins (middle column) |
| 233 | +--------- |
| 234 | +X . . |
| 235 | +``` |
| 236 | + |
| 237 | +**Diagonal Win:** |
| 238 | +``` |
| 239 | +X . O |
| 240 | +--------- |
| 241 | +. X O <- Player X wins (top-left to bottom-right) |
| 242 | +--------- |
| 243 | +O . X |
| 244 | +``` |
| 245 | + |
| 246 | +## Future Enhancements |
| 247 | + |
| 248 | +Potential improvements to the project: |
| 249 | +- Implement alpha-beta pruning to optimize Minimax performance |
| 250 | +- Add difficulty levels (easy, medium, hard) with varying AI strategies |
| 251 | +- Support for different board sizes (4x4, 5x5) |
| 252 | +- Save/load game state functionality |
| 253 | +- Network multiplayer support |
| 254 | +- Graphical user interface (GUI) using a framework like egui or iced |
| 255 | +- Game statistics tracking (wins, losses, draws) |
| 256 | +- Undo/redo move functionality |
| 257 | +- Time limits per move |
| 258 | +- Tournament mode with multiple rounds |
| 259 | + |
| 260 | +## Dependencies |
| 261 | + |
| 262 | +The project uses the following external dependencies: |
| 263 | + |
| 264 | +- **`rand`** (version 0.8): Used for random number generation in the random AI opponent mode |
| 265 | + |
| 266 | +## Performance Notes |
| 267 | + |
| 268 | +- The random AI opponent has instant move selection (O(1) after getting empty cells) |
| 269 | +- The Minimax AI explores the entire game tree but remains fast due to the small state space of Tic-Tac-Toe |
| 270 | +- Typical Minimax computation time: < 100ms even in early game states |
| 271 | +- No optimization techniques (like alpha-beta pruning) are currently implemented, but performance is already excellent for this game size |
| 272 | + |
| 273 | +## Conclusion |
| 274 | + |
| 275 | +This Tic-Tac-Toe implementation demonstrates fundamental concepts in game AI, including the Minimax algorithm for perfect play. The modular architecture allows for easy extension and modification, making it an excellent foundation for learning about game theory and AI decision-making algorithms. |
0 commit comments