The PHPoker Extension provides fast poker hand evaluation and equity calculation directly from PHP. It is a direct C implementation of Kevin Suffecool's poker hand evaluator algorithm (also known as the "Two Plus Two" evaluator), which uses perfect hashing and lookup tables to achieve O(1) performance for hand evaluation.
- Evaluate 5 or 7 card poker hands
- Calculate equity percentages between multiple players
- Support for specifying board cards and dead cards
- Fast C implementation as a PHP extension
PHPoker must be compiled specifically for your system's PHP version and architecture. Pre-compiled binaries are not provided in the repository.
- PHP 7.0 or higher (development files)
- C compiler (gcc/clang)
- phpize and php-config
- make
sudo apt-get install php-dev build-essential
sudo yum install php-devel gcc make
brew install [email protected] # or your PHP version
-
Clone the repository:
git clone https://github.com/yourusername/phpoker.git cd phpoker
-
Build the extension:
./build.sh
-
If the build script doesn't work for you, you can manually build with:
mkdir -p build cp src/*.c src/*.h src/config.m4 build/ cd build phpize ./configure --enable-phpoker make sudo make install
-
Enable the extension in your php.ini:
extension=phpoker.so
-
Verify the extension is loaded:
php -m | grep phpoker
If you want to test the extension in a Docker environment, you can use this sample Dockerfile:
FROM php:8.1-cli
# Install dependencies
RUN apt-get update && apt-get install -y git
# Clone and build PHPoker
WORKDIR /tmp
RUN git clone https://github.com/PHPoker/PHPoker-Extension.git \
&& cd phpoker \
&& mkdir -p build \
&& cp src/*.c src/*.h src/config.m4 build/ \
&& cd build \
&& phpize \
&& ./configure --enable-phpoker \
&& make \
&& make install
# Enable the extension
RUN echo "extension=phpoker.so" > /usr/local/etc/php/conf.d/phpoker.ini
# Verify installation
RUN php -m | grep phpoker
# Set working directory
WORKDIR /app
<?php
// Evaluate a 5-card hand
$result = poker_evaluate_hand('Ah Kh Qh Jh Th');
var_dump($result);
// Evaluate a 7-card hand (finds the best 5-card hand)
$result = poker_evaluate_hand('Ah Kh Qh Jh Th 2c 3d');
var_dump($result);
Sample output:
array(4) {
["value"]=>
int(1)
["rank"]=>
int(1)
["name"]=>
string(14) "Straight Flush"
["cards"]=>
int(5)
}
The return array contains:
- value: A numeric evaluation value (lower is better)
- rank: Hand rank (1-9, where 1 is a straight flush and 9 is high card)
- name: String representation of the hand (e.g., "Straight Flush", "Four of a Kind")
- cards: Number of cards in the hand
<?php
// Calculate equity between two hands preflop
$result = poker_calculate_equity(['Ah Ad', 'Kh Kd'], [], 10000);
var_dump($result);
// Calculate equity with a flop
$result = poker_calculate_equity(['Ah Kd', '2c 2h'], ['Kc 7d 2s'], 10000);
var_dump($result);
// With dead cards
$result = poker_calculate_equity(['9h 9d', 'Ad Kh'], [], 10000, ['As']);
var_dump($result);
Sample output:
array(2) {
[0]=>
array(3) {
["equity"]=>
float(82.45)
["wins"]=>
int(8245)
["ties"]=>
int(0)
}
[1]=>
array(3) {
["equity"]=>
float(17.55)
["wins"]=>
int(1755)
["ties"]=>
int(0)
}
}
The poker_calculate_equity
function accepts:
- An array of hole cards (strings, one per player)
- An array of board cards (optional)
- Number of iterations for the Monte Carlo simulation (optional, default 10,000)
- An array of dead cards to remove from the deck (optional)
It returns an array with each player's equity and win/tie statistics.
Cards are represented as a two-character string:
- First character is the rank:
2
,3
,4
,5
,6
,7
,8
,9
,T
,J
,Q
,K
, orA
- Second character is the suit:
c
(clubs),d
(diamonds),h
(hearts), ors
(spades)
Example: Ah
= Ace of hearts, Tc
= Ten of clubs
Cards in a hand are separated by spaces: Ah Kd Qc Js Th
The extension includes test scripts that demonstrate its functionality:
php test_poker_evaluate_hand.php
php test_poker_calculate_equity.php
The Two Plus Two evaluator uses a clever algorithm that can evaluate any poker hand in constant time (O(1)) using lookup tables. The evaluation process:
- Represents each card with a unique prime number for its rank
- For non-flush hands, multiplies these prime numbers to get a unique product
- Uses perfect hashing to map the product to a unique hand value
- For flush and straight hands, uses bit manipulation and table lookups
The evaluation returns a numeric value where lower numbers indicate stronger hands.
The C implementation makes this extension extremely fast compared to pure PHP implementations:
- Evaluating a single hand takes less than a microsecond
- Monte Carlo equity calculations can process tens of thousands of hands per second
Since this is a compiled extension, there are some important considerations for distribution:
-
Source Code Distribution:
- This project is distributed as source code that needs to be compiled for each specific environment
- This ensures compatibility across different PHP versions and platforms
- The build script handles most of the complexity for end users
-
NOT available via PECL:
- This extension is not currently distributed through PECL
- Users must compile from source
-
Versioning:
- Version changes are reflected in the
PHP_PHPOKER_VERSION
constant inphpoker.h
- The GitHub repository uses semantic versioning (MAJOR.MINOR.PATCH)
- Version changes are reflected in the
-
Extension Compatibility:
- Compiled extensions are specific to the PHP version they were built for
- Users need to rebuild when upgrading PHP versions
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a new branch (
git checkout -b feature/your-feature
) - Make your changes
- Run tests to ensure everything works
- Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin feature/your-feature
) - Create a new Pull Request
For development, you'll need:
- PHP development environment
- C compiler and build tools
- Knowledge of PHP extension development or C programming
The main files to modify:
phpoker.c
- Main extension codephpoker.h
- Header filearrays.h
- Contains lookup tables for hand evaluation
- Make code changes: Edit the source files in the
src/
directory - Build for testing: Run
./build.sh
to compile - Test your changes: Run the test scripts to verify functionality
- Memory testing: Consider using Valgrind to check for memory leaks
-
Adding a new function:
- Add function prototype to
phpoker.h
- Implement function in
phpoker.c
- Add to
phpoker_functions
array inphpoker.c
- Create appropriate argument info
- Add function prototype to
-
Modifying the algorithm:
- Most core algorithm functions are in
phpoker.c
- The lookup tables are in
arrays.h
- Most core algorithm functions are in
-
Version bump:
- Update
PHP_PHPOKER_VERSION
inphpoker.h
when making changes
- Update
This project is based on:
- Kevin Suffecool's poker hand evaluator algorithm
- The "Two Plus Two" evaluation approach
- Paul Senzee's perfect hash algorithm for hand evaluation
This project is licensed under the PHP License 3.01 - see the LICENSE file for details or visit the official PHP License page.