No description
Find a file
Jan-Peter von Hunnius 5c271b279f Added Documentation
Added Test Cases
Added Comments
2025-10-02 18:33:31 +02:00
core Added Documentation 2025-10-02 18:33:31 +02:00
docs Added Documentation 2025-10-02 18:33:31 +02:00
target Added Documentation 2025-10-02 18:33:31 +02:00
Cargo.toml Added Documentation 2025-10-02 18:33:31 +02:00
README.md Added Documentation 2025-10-02 18:33:31 +02:00

Poker Hand Evaluator

Crates.io Documentation License

A high-performance poker hand evaluation library for Rust, based on the Java Meerkat API algorithm. This library provides lightning-fast poker hand strength evaluation using precomputed lookup tables and perfect hashing.

Features

  • 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
  • Multi-Hand Support: Evaluate 5, 6, or 7-card poker hands
  • Texas Hold'em Ready: Optimized for Texas Hold'em hand evaluation
  • Comprehensive Testing: Extensive test suite with millions of verification cases

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

Installation

Add this to your Cargo.toml:

[dependencies]
poker-api = "0.1.0"

Quick Start

use poker_api::hand_evaluator::LookupHandEvaluator;
use poker_api::api::hand::Hand;

// Create evaluator (generates tables on first use)
let evaluator = LookupHandEvaluator::new().unwrap();

// Create a poker hand
let mut hand = Hand::new();
// ... add cards to hand

// Evaluate hand strength
let rank = evaluator.rank_hand(&hand);
println!("Hand rank: {}", rank);

Algorithm Overview

This library implements the Meerkat algorithm, a perfect hash-based approach to poker hand evaluation:

  1. Card Encoding: Each card is encoded into a compact binary representation
  2. Perfect Hash: Cards are mapped to unique indices using mathematical functions
  3. Table Lookup: Precomputed ranking tables provide instant hand strength values
  4. Best Hand Selection: For 6-7 card hands, finds optimal 5-card combination

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/HandRanks.dat"

Tables are saved to math/HandRanks.dat and reused for subsequent runs.

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♦

Advanced Usage

7-Card Hand Evaluation

use poker_api::hand_evaluator::LookupHandEvaluator;
use poker_api::api::card::Card;

let evaluator = LookupHandEvaluator::new().unwrap();

// Texas Hold'em: 2 hole cards + 5 community cards
let cards = [
    Card::from_string("As").unwrap(),
    Card::from_string("Ks").unwrap(),
    Card::from_string("Td").unwrap(),
    Card::from_string("Jc").unwrap(),
    Card::from_string("Qh").unwrap(),
    Card::from_string("9s").unwrap(),
    Card::from_string("2d").unwrap(),
];

let rank = evaluator.rank_hand7(&cards);
println!("Best 5-card hand rank: {}", rank);

Custom Table Generation

use poker_api::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:

  1. Flush Detection: Bitwise suit comparison
  2. Rank Analysis: Prime product uniqueness
  3. Pattern Matching: Specialized algorithms per hand type
  4. Relative Ranking: Comparison against all possible hands

References

  • Meerkat API: Original Java implementation by Ray Wotton
  • C Implementation: Paul Senzee's optimized C version
  • Perfect Hash: Kevin Suffecool's hashing algorithm
  • Poker Standards: 2+2 Poker hand ranking standards

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:

  1. Check existing documentation
  2. Review test cases for usage examples
  3. Open GitHub issues for bugs or feature requests
  4. Submit pull requests with comprehensive tests

Performance Note: First run includes ~1-2 second table generation. Subsequent runs load precomputed tables in ~100-200ms.