AI System Design
AI System Overview
The Liar's Dice AI system uses a flexible strategy pattern that allows for multiple AI implementations with varying difficulty levels and play styles. The system is designed to be extensible, testable, and configurable.
AI Architecture
Strategy Pattern Implementation
The AI system is built around the Strategy pattern with the following components:
- IAIStrategy: Pure virtual interface defining the contract for all AI strategies
- AIStrategyFactory: Singleton factory using type erasure for strategy creation
- AIDecision: Variant type for type-safe decision representation
- AIDecisionContext: Comprehensive game state information for decision making
class IAIStrategy { public: virtual ~IAIStrategy() = default; virtual AIDecision make_decision(const AIDecisionContext& context) = 0; virtual std::string get_name() const = 0; virtual std::unique_ptr<IAIStrategy> clone() const = 0; };
AI Decision Types
AI players can make two types of decisions:
- AIGuessAction: Make a new guess about dice counts
- AICallLiarAction: Challenge the previous player's guess
using AIDecision = std::variant<AIGuessAction, AICallLiarAction>;
AI Strategy Implementations
Easy AI Strategy
Simple heuristic-based AI with configurable parameters:
Features:**
- Basic probability calculations
- Conservative play style
- Configurable risk tolerance (0.0 - 1.0)
Simple bluff detection
Configuration:**
struct EasyConfig { double risk_tolerance = 0.2; double bluff_frequency = 0.1; double call_threshold = 0.8; bool use_statistical_analysis = false; unsigned int think_time_ms = 500; };
Decision Logic:**
- Calculate probability of current guess being true
- If probability < call_threshold, call liar
- Otherwise, make conservative guess based on own dice
Medium AI Strategy
Statistical AI with pattern recognition and opponent modeling:
Features:**
- Bayesian probability calculations
- Opponent behavior tracking
- Pattern recognition using game history
- Bluff detection with statistical analysis
Adaptive play style
Configuration:**
struct MediumConfig { double risk_tolerance = 0.4; double bluff_frequency = 0.2; double call_threshold = 0.7; double pattern_weight = 0.3; unsigned int history_size = 20; unsigned int think_time_ms = 1000; };
Advanced Features:**
- Probability Calculation:
- Uses binomial distribution for exact probabilities
- Accounts for wild dice (1s count as any value)
- Considers revealed information from previous rounds
Opponent Modeling:
struct OpponentPattern { std::deque<Guess> recent_guesses; std::unordered_map<unsigned int, double> face_frequency; double bluff_rate = 0.0; double aggression_level = 0.0; };
- Pattern Recognition:
- Tracks sequences of actions (e.g., "guess-guess-call")
- Identifies bluffing patterns
- Adapts strategy based on opponent behavior
Hard AI Strategy (Future)
Advanced AI with machine learning capabilities:
Planned Features:**
- Neural network for decision making
- Monte Carlo tree search
- Advanced game theory concepts
- Perfect information tracking
- Multi-level reasoning
Decision Making Process
Context Analysis
The AI receives comprehensive context for decision making:
struct AIDecisionContext { const Game* game; // Game state access unsigned int player_id; // AI player ID unsigned int total_dice; // Total dice in play boost::optional<Guess> last_guess; // Previous guess GameHistory history; // Historical data };
Decision Flow
- Information Gathering
- Analyze current game state
- Review historical patterns
- Calculate probabilities
- Strategy Selection
- Determine if defensive or aggressive play is needed
- Consider risk tolerance and game phase
- Evaluate bluffing opportunities
- Action Generation
- Generate candidate actions
- Score each action based on expected value
- Select optimal action with randomization
- Learning and Adaptation
- Update opponent models
- Store patterns for future reference
- Adjust strategy parameters
AI Configuration
Runtime Configuration
AI behavior can be configured through JSON files:
{ "ai": { "easy": { "risk_tolerance": 0.2, "bluff_frequency": 0.1, "call_threshold": 0.8 }, "medium": { "risk_tolerance": 0.4, "pattern_weight": 0.3, "history_size": 20 } } }
Difficulty Scaling
AI difficulty can be adjusted by modifying:
- Risk Tolerance: Higher values make AI more aggressive
- Bluff Frequency: Controls how often AI bluffs
- Call Threshold: Lower values make AI more skeptical
- Think Time: Simulates human thinking delay
AI Testing
Unit Testing
Each AI strategy has comprehensive unit tests:
- Decision making in various scenarios
- Edge case handling
- Configuration validation
- Performance benchmarks
Integration Testing
AI strategies are tested in full games:
- Win rate analysis
- Behavioral consistency
- Performance under pressure
- Multi-AI interactions
Statistical Validation
AI behavior is validated through:
- Monte Carlo simulations
- Statistical analysis of decisions
- Comparison with optimal play
- A/B testing of strategies
Performance Considerations
Optimizations
- Probability calculations are cached
- Pattern matching uses trie data structure
- Historical data uses circular buffers
- SIMD operations for batch calculations
Performance Benchmarks
| AI Level | Decision Time | Memory Usage | Cache Efficiency |
|---|---|---|---|
| Easy | < 1ms | 1KB | 95% |
| Medium | < 5ms | 8KB | 90% |
| Hard | < 20ms | 64KB | 85% |
Extending the AI System
Adding a New Strategy
- Create new class inheriting from IAIStrategy
- Implement required virtual methods
- Register with AIStrategyFactory
- Add configuration support
- Create unit tests
Example:
class CustomAIStrategy : public IAIStrategy { public: AIDecision make_decision(const AIDecisionContext& context) override { // Custom logic here } std::string get_name() const override { return "custom"; } std::unique_ptr<IAIStrategy> clone() const override { return std::make_unique<CustomAIStrategy>(*this); } }; // Register with factory AIStrategyFactory::instance().register_strategy("custom", []() { return std::make_unique<CustomAIStrategy>(); });
AI Tournaments
The system supports AI vs AI tournaments for strategy evaluation:
// Run tournament between different AI strategies TournamentRunner runner; runner.add_strategy("easy"); runner.add_strategy("medium"); runner.run_games(1000); auto results = runner.get_statistics();