|
|
||
|---|---|---|
| docs | ||
| holdem_core | ||
| math/proptest-regressions/evaluator | ||
| target | ||
| Cargo.toml | ||
| README.md | ||
Poker Testbed - Java-Compatible Hand Evaluator for Bot Testing
A comprehensive poker bot testing framework with Java-compatible hand evaluation. This library implements the Meerkat API algorithm with full Java compatibility, specifically designed for automated poker bot testing, development, and integration with existing poker tools.
Recent Updates
- Input Validation: Added comprehensive validation to
Card::new()ensuring rank (0-12) and suit (0-3) are within valid ranges - Enhanced Documentation: All public methods now include working code examples and panic condition documentation
- Error Handling: Improved error handling throughout the codebase with proper
Resulttypes
Features
- Java-Compatible: Full compatibility with Java Meerkat API for seamless tool integration
- Bot Testing Framework: Specifically designed for automated poker bot testing and development
- Blazing Fast: O(1) hand evaluation using perfect hash lookup tables
- Memory Efficient: ~128MB for complete evaluation tables
- Standards Compliant: Based on proven poker evaluation algorithms with Java compatibility
- Multi-Hand Support: Evaluate 5, 6, or 7-card poker hands with Java-compatible results
- Texas Hold'em Ready: Optimized for Texas Hold'em bot analysis and testing
- Comprehensive Testing: Extensive test suite with millions of verification cases
- Deterministic Results: Consistent hand evaluation for reproducible bot testing
- Tool Integration: Compatible with existing Java poker tools and frameworks
Performance
| Hand Type | Evaluation Time | Combinations Evaluated |
|---|---|---|
| 5-Card | ~10-20ns | Direct lookup |
| 6-Card | ~50-80ns | 6 combinations |
| 7-Card | ~150-250ns | 21 combinations |
Documentation
For detailed project information, see:
- VISION.md - Project goals and architectural vision
- ACHIEVEMENTS.md - Completed milestones and success metrics
- ROADMAP.md - Future development phases and implementation plan
Installation
Add this to your Cargo.toml:
[dependencies]
poker-api = "0.1.0"
Quick Start - Bot Testing
use holdem_core::hand_evaluator::LookupHandEvaluator;
use holdem_core::api::{hand::Hand, card::Card};
// Initialize Java-compatible evaluator for bot testing
let evaluator = LookupHandEvaluator::new().unwrap();
// Create hole cards for bot analysis
let mut hole_cards = Hand::new();
hole_cards.add_card(Card::from_string("As").unwrap()).unwrap();
hole_cards.add_card(Card::from_string("Ks").unwrap()).unwrap();
// Evaluate hand strength for bot decision making
let rank = evaluator.rank_hand(&hole_cards);
println!("Hole card rank: {}", rank); // Lower = stronger hand
// Use rank for bot strategy decisions
if rank < 1000 { // Strong hand threshold
println!("Bot: This is a premium starting hand!");
}
Bot Testing Capabilities
This framework provides specialized capabilities for poker bot testing and development:
Automated Bot Testing
- Standardized Evaluation: Java-compatible hand evaluation for consistent bot testing
- Performance Benchmarking: Fast evaluation for large-scale bot performance testing
- Range Analysis: Efficient hand range evaluation for bot strategy analysis
- Decision Tree Testing: Quick hand strength calculation for bot decision trees
Java Tool Integration
- Cross-Platform Compatibility: Works seamlessly with existing Java poker tools
- Consistent Results: Identical hand rankings to Java Meerkat API
- Tool Chain Integration: Compatible with Java-based poker analysis frameworks
- Bot Framework Support: Integrates with popular Java poker bot frameworks
Bot Development Features
- Hole Card Analysis: Fast evaluation of starting hand strength for pre-flop bots
- Post-Flop Analysis: Efficient board texture and hand strength analysis
- Incremental Evaluation: Multi-street hand evaluation for complex bot scenarios
- Memory Efficient: Optimized for bot testing environments with limited resources
Algorithm Overview
This library implements the Java-compatible Meerkat algorithm, a perfect hash-based approach optimized for poker bot testing:
- Java-Style Card Encoding: Each card uses Java Meerkat's 8-bit encoding (rrrr-sss format)
- Perfect Hash: Cards are mapped to unique indices using Java-compatible mathematical functions
- Table Lookup: Precomputed ranking tables provide instant hand strength values matching Java API
- Best Hand Selection: For 6-7 card hands, finds optimal 5-card combination using Java logic
Table Generation
The first time an evaluator is created, it generates evaluation tables:
// Tables are generated automatically on first use
let evaluator = LookupHandEvaluator::new().unwrap();
// Output: "Generating state table..." (first run only)
// Output: "Hand evaluation tables saved to math/data/"
Tables are saved to math/data/ directory as separate files and reused for subsequent runs:
5_card_table.lut(~10 MB)6_card_table.lut(~80 MB)7_card_table.lut(~535 MB)
Hand Types
The evaluator recognizes all standard poker hand types:
| Hand Type | Description | Example |
|---|---|---|
| Straight Flush | Five cards in sequence, same suit | A♠ K♠ Q♠ J♠ T♠ |
| Four of a Kind | Four cards of same rank | A♠ A♥ A♦ A♣ K♦ |
| Full House | Three of a kind + one pair | K♠ K♥ K♦ Q♠ Q♥ |
| Flush | Five cards of same suit | A♠ J♠ 8♠ 5♠ 2♠ |
| Straight | Five cards in sequence | A♦ K♣ Q♥ J♠ T♦ |
| Three of a Kind | Three cards of same rank | Q♠ Q♥ Q♦ A♣ 7♦ |
| Two Pair | Two different pairs | J♠ J♥ 7♦ 7♣ A♦ |
| One Pair | Two cards of same rank | A♠ A♥ K♦ Q♣ 7♦ |
| High Card | No matching cards | A♠ K♥ Q♦ J♣ 9♦ |
Bot Testing Examples
Texas Hold'em Bot Analysis
use holdem_core::hand_evaluator::LookupHandEvaluator;
use holdem_core::api::{card::Card, hand::Hand};
let evaluator = LookupHandEvaluator::new().unwrap();
// Bot analyzes hole cards + flop for decision making
let hole_card1 = Card::from_string("As").unwrap().index() as u32;
let hole_card2 = Card::from_string("Ks").unwrap().index() as u32;
let mut board = Hand::new();
board.add_card(Card::from_string("Td").unwrap()).unwrap();
board.add_card(Card::from_string("Jc").unwrap()).unwrap();
board.add_card(Card::from_string("Qh").unwrap()).unwrap();
// Bot evaluates complete hand strength
let hand_strength = evaluator.rank_hand_with_hole_cards(hole_card1, hole_card2, &board);
println!("Hand strength after flop: {}", hand_strength);
// Bot uses this for post-flop decision making
if hand_strength < 2000 { // Strong hand
println!("Bot: Continuing with strong hand");
}
Bot Range Analysis
use holdem_core::hand_evaluator::LookupHandEvaluator;
use holdem_core::api::card::Card;
let evaluator = LookupHandEvaluator::new().unwrap();
// Bot analyzes range of starting hands for pre-flop strategy
let premium_hands = vec![
(Card::from_string("AA").unwrap(), Card::from_string("KK").unwrap()),
(Card::from_string("QQ").unwrap(), Card::from_string("JJ").unwrap()),
(Card::from_string("AK").unwrap(), Card::from_string("AQ").unwrap()),
];
for (card1, card2) in premium_hands {
let mut hand = Hand::new();
hand.add_card(card1).unwrap();
hand.add_card(card2).unwrap();
let strength = evaluator.rank_hand(&hand);
println!("Bot range analysis - {}: {}", hand.to_string(), strength);
}
Advanced Usage
7-Card Hand Evaluation for Bot Testing
use holdem_core::hand_evaluator::LookupHandEvaluator;
use holdem_core::api::card::Card;
let evaluator = LookupHandEvaluator::new().unwrap();
// Texas Hold'em complete hand: 2 hole cards + 5 community cards
let hole_cards = [
Card::from_string("As").unwrap().index(),
Card::from_string("Ks").unwrap().index(),
];
let community_cards = [
Card::from_string("Td").unwrap().index(),
Card::from_string("Jc").unwrap().index(),
Card::from_string("Qh").unwrap().index(),
Card::from_string("9s").unwrap().index(),
Card::from_string("2d").unwrap().index(),
];
// Bot evaluates best possible hand from all cards
let all_cards: Vec<u32> = hole_cards.iter().chain(community_cards.iter()).cloned().collect();
let best_rank = evaluator.rank_hand7(&all_cards);
println!("Bot best hand rank: {}", best_rank);
Custom Table Generation
use holdem_core::evaluator_generator::state_table_generator::StateTableGenerator;
let mut generator = StateTableGenerator::new();
generator.generate_tables(); // ~1-2 seconds
generator.save_tables().unwrap(); // Save to disk
Testing
Run the comprehensive test suite:
cargo test
Run performance benchmarks:
cargo test --release hand_eval_integration_test -- --nocapture
Mathematical Foundation
Perfect Hash Algorithm
The evaluator uses a perfect hash function that maps each possible card combination to a unique index:
Hash = f(card₁, card₂, ..., cardₙ)
Index = Hash % TABLE_SIZE
Rank = TABLE[Index]
Card Encoding
Each card is encoded using multiple techniques:
- Prime Numbers: Unique primes for rank identification (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41)
- Bit Patterns: Suit detection using bit manipulation
- Binary Representation: Compact 8-bit card encoding
Hand Strength Calculation
Hand strength is calculated using:
- Flush Detection: Bitwise suit comparison
- Rank Analysis: Prime product uniqueness
- Pattern Matching: Specialized algorithms per hand type
- Relative Ranking: Comparison against all possible hands
References
- Meerkat API: Original Java implementation by Ray Wotton (full compatibility maintained)
- C Implementation: Paul Senzee's optimized C version (algorithm foundation)
- Perfect Hash: Kevin Suffecool's hashing algorithm (core mathematical approach)
- Poker Standards: 2+2 Poker hand ranking standards (ranking reference)
- Poker Testbed: Framework designed for automated bot testing and analysis
- Java Integration: Compatible with existing Java poker tools and frameworks
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Areas for improvement:
- Hardware acceleration (SIMD optimizations)
- Additional poker variants (Omaha, Stud, etc.)
- Memory-mapped table loading
- Distributed table generation
- Advanced benchmarking tools
Support
For questions, issues, or contributions, please:
- Check existing documentation
- Review test cases for usage examples
- Open GitHub issues for bugs or feature requests
- Submit pull requests with comprehensive tests
Performance Note: First run includes ~1-2 second table generation. Subsequent runs load precomputed tables in ~100-200ms.