A Python implementation of Othello (Reversi) with multiple AI strategies and a comprehensive testing framework. Features a GUI for playing games and a headless testing system for comparing AI performance.
- Installation
- Playing the Game (GUI)
- Testing AI Strategies
- Analyzing Results
- Available AI Strategies
- Advanced Usage
- Python 3.8+
- pip or uv (package manager)
# Clone or navigate to project directory
cd /path/to/Othelo
# Create virtual environment (recommended)
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install dependencies
pip install -r requirements.txtEdit main.py to configure players:
from src.game.board import Board, Color
from src.game.player import Player
from src.strategies.human import HumanStrategy
from src.strategies.minimax_ai import MinimaxAI
from src.strategies.greedy_ai import GreedyAI
from src.presentation.gui import OthelloGUI
board = Board()
# Human vs AI
player1 = Player(Color.BLACK, HumanStrategy(), "Human")
player2 = Player(Color.WHITE, MinimaxAI(depth=3), "AI")
# Or AI vs AI
# player1 = Player(Color.BLACK, MinimaxAI(depth=3), "AI 1")
# player2 = Player(Color.WHITE, GreedyAI(), "AI 2")
gui = OthelloGUI(board, player1, player2)
gui.run()- Click on a valid square to make a move (human players)
- Valid Moves Button - Toggle showing valid move indicators
- New Game Button - Start a new game
- Close Window - Exit the game
The testing framework runs games without the GUI and stores results in a SQLite database with full metadata (strategy configurations, heuristics, etc.).
| File | Purpose |
|---|---|
test_framework.py |
Core testing engine, classes, pytest tests |
test_configs.py |
Pre-defined test scenarios, easy CLI |
results_analyzer.py |
View and analyze test results |
Pre-defined AI configurations and test scenarios.
# Run all test scenarios (20+ games each)
python test_configs.py all
# Quick test (5 games)
python test_configs.py quick
# Custom matchup between two AIs
python test_configs.py custom minimax_d3 greedy
# See available configurations
python test_configs.py| Config Key | Strategy | Parameters | Description |
|---|---|---|---|
random |
RandomAI | - | Random move selection |
greedy |
GreedyAI | - | Maximizes immediate flips |
minimax_dn |
MinimaxAI | depth=n | Minimax with depth n |
# Run all pytest tests
pytest tests/test_framework.py -v
# Run specific test
pytest tests/test_framework.py::TestOthelloAI::test_minimax_vs_greedy -v
# Run with output
pytest tests/test_framework.py -v -sFor each game, the database stores:
- Game metadata: timestamp, board size, winner, scores, moves, duration
- Player configurations: strategy name, JSON config (depth, heuristics, weights)
- Series information: groups of related games
- Full traceability: every game is linked to its exact AI configuration
Example of stored config:
{
"depth": 3,
"corner_value": 100,
"mobility_weight": 3.0
}python results_analyzer.py test_results.dbMenu Options:
- View all series - List all test series with IDs
- View series details - Detailed results for a specific series
- View strategy rankings - Overall win rates for all strategies
- Compare two strategies - Head-to-head comparison
- Export to CSV - Export all results for external analysis
- Exit
$ python results_analyzer.py
Options:
1. View all series
2. View series details
3. View strategy rankings
4. Compare two strategies
5. Export to CSV
6. Exit
Select option: 3
================================================================================
STRATEGY RANKINGS
================================================================================
Rank Strategy Config W-L-T Win% Games
--------------------------------------------------------------------------------
1 MinimaxAI {'depth': 4} 45-15-2 75.0 60
2 MinimaxAI {'depth': 3} 38-20-4 63.3 60
3 GreedyAI {} 25-30-5 45.5 55
4 RandomAI {} 12-48-2 20.0 60 Selects moves randomly from valid options.
from src.strategies.random_ai import RandomAI
player = Player(Color.BLACK, RandomAI())Chooses the move that flips the most opponent pieces immediately.
from src.strategies.greedy_ai import GreedyAI
player = Player(Color.BLACK, GreedyAI())Uses minimax algorithm with alpha-beta pruning.
from src.strategies.minimax_ai import MinimaxAI
# Configure depth (higher = stronger but slower)
player = Player(Color.BLACK, MinimaxAI(depth=3))Features:
- Alpha-beta pruning for efficiency
- Positional weights (corners valuable, X-squares dangerous)
- Mobility heuristic (values moves that create more options)
- Game phase awareness (early/mid/late game strategies)
- Dynamic board size support (auto-generates weights)
Evaluation factors:
- Positional score - Corner control, edge positions
- Piece count - Raw material advantage
- Mobility - Number of available moves
Create your own AI configs in test_configs.py:
AI_CONFIGS = {
# ... existing configs ...
"minimax_aggressive": AIConfig(
strategy_class_name="MinimaxAI",
params={"depth": 4},
description="Aggressive depth-4 minimax"
),
}Then test it:
python test_configs.py custom minimax_aggressive greedyAdd to TEST_SCENARIOS in test_configs.py:
TEST_SCENARIOS = [
# ... existing scenarios ...
{
"name": "My Custom Test",
"player1": "minimax_d3",
"player2": "greedy",
"num_games": 50,
"description": "Testing my hypothesis"
},
]Problem: ModuleNotFoundError: No module named 'src'
Solution: Always run from project root:
cd /path/to/Othelo
python main.py
python -m tests.results_analyzer
python -m tests.test_configs- Create new file in
src/strategies/ - Inherit from
Strategybase class - Implement
choose_move()method - Add to
test_configs.py
Example:
# src/strategies/my_ai.py
from src.strategies.base import Strategy
from src.game.board import Board, Color
from typing import Optional, Tuple
class MyAI(Strategy):
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
def choose_move(self, board: Board, color: Color) -> Optional[Tuple[int, int]]:
valid_moves = board.get_valid_moves(color)
if not valid_moves:
return None
# Your AI logic here
return valid_moves[0]Then test it:
# In test_configs.py
from src.strategies.my_ai import MyAI
AI_CONFIGS["my_ai"] = AIConfig(
strategy_class_name="MyAI",
params={"param1": 10, "param2": 20},
description="My custom AI"
)MIT License - feel free to use and modify