A high-quality implementation of the SET card game with an intelligent LLM agent that can play the game using visual board representations.
This project implements the classic SET card game with:
- Visual Game Environment: High-quality Cairo-rendered graphics with clear card identification
- LLM Agent: GPT-5 powered agent that analyzes board images and makes strategic decisions
- 1-Based Indexing: Natural card numbering that matches what humans see (no mental conversion required)
- Complete Game Logic: Full SET rule validation, board management, and game flow
SET is a pattern recognition card game where you identify groups of three cards that form a "Set". Each card has four attributes:
- Number: 1, 2, or 3 shapes
- Color: Red, Green, or Purple
- Shape: Diamond, Squiggle, or Oval
- Shading: Solid, Striped, or Open
Three cards form a valid Set if, for each attribute, the values are either all the same or all different across the three cards.
- Initial 12-card board guaranteed to contain at least one valid Set
- Dynamic board layout with 3 cards per column
- High-quality Cairo graphics with anti-aliasing
- Card numbering from 1-12+ (human-friendly, matches visual display)
- Maximum board size of 21 cards
- Automatic board refilling after successful Sets
- Uses OpenAI GPT-5 for intelligent gameplay
- Processes board images to identify valid Sets
- Uses 1-based indexing matching the visual card labels
- Automatic conversion to 0-based indexing internally
- Structured JSON output for reliable action parsing
- Comprehensive logging for debugging and analysis
- Semi-transparent numbered labels for easy card identification
- Optimal spacing to prevent shape overlap
- Dynamic grid layout maintaining 3 cards per column
- Clear distinction between different card attributes
-
Install dependencies:
pip install -r requirements.txt # or using uv: uv sync -
Set up OpenAI API key:
export OPENAI_API_KEY="your-api-key-here"
python -m Set.agent --seed 42 --save-prefix demoThis will:
- Create a game with optional seed for reproducibility
- Generate initial board image (
demo_initial.png) - Have the LLM agent analyze and make a move
- Save the result image (
demo_after.png) - Print the action taken and result
from Set.env import SetEnv
# Create a new game
env = SetEnv(seed=42)
# Get the board as an image
board_image = env.get_board_image()
# Select three cards (using 0-based indices in code)
message, result_image = env.select((0, 4, 8)) # Cards 1, 5, 9
# Deal three more cards
message, result_image = env.deal_three()The LLM agent now uses natural 1-based indexing that matches the visual card labels:
- Before: LLM had to convert card "5" → index 4
- After: LLM can directly use "5" as shown on the card
- Internal conversion happens automatically in the code
- Cairo-based rendering with anti-aliasing
- 50% larger symbols for improved visibility
- Clear color distinction and optimal spacing
- Professional-quality visual output
Set/
├── agent.py # LLM agent implementation
├── env.py # Game environment and logic
├── type.py # Card type definitions and utilities
├── templates/
│ └── system_prompt_template.j2 # LLM system prompt template
└── Utils/
└── generate_board.py # Cairo graphics rendering
Assets/ # Game documentation and examples
Specs/ # Technical specifications
- pycairo: High-quality graphics rendering
- Pillow: Image processing and format conversion
- openai: GPT-5 API integration
- jinja2: Template rendering for prompts
- python-dotenv: Environment variable management
This project focuses on creating an intelligent SET game agent with natural human-like interaction patterns. The 1-based indexing system eliminates cognitive overhead for both human players and LLM agents.
See LICENSE file for details.