+
Skip to content

PHPoker/Poker

Repository files navigation

PHPoker

GitHub Workflow Status (master) Total Downloads Latest Version License


PHP's Premier Poker Solution

Requires PHP 8.2+

⚡️ Installation using Composer:

composer require phpoker/poker

✨ Features

  • Base classes for common card + poker related entities
    • Card
    • CardFace
    • CardSuit
    • CardCollection
  • Evaluate
    • Highly optimized 5-card/7-card hand evaluators (port of Kevin "CactusKev" Suffecool's algorithm)

Usage

PHPoker provides a comprehensive toolkit for working with cards, decks, and poker hand evaluation. Below are examples of the main features and how to use them.

Working with Cards

Creating Cards

use PHPoker\Poker\Card;
use PHPoker\Poker\Enum\CardFace;
use PHPoker\Poker\Enum\CardSuit;

// Create a card using enums
$aceOfSpades = Card::make(CardFace::ACE, CardSuit::SPADE);

// Create a card from text notation
$kingOfHearts = Card::fromText('Kh'); // K = King, h = hearts
$queenOfClubs = Card::fromText('Q♣'); // Works with Unicode symbols too

// Create a random card
$randomCard = Card::random();

Card Properties and Methods

// Get card details
echo $aceOfSpades->face->name;  // "ACE"
echo $aceOfSpades->suit->name;  // "SPADE"

// Convert to string
echo $aceOfSpades->toString();       // "As" (default text format)
echo $aceOfSpades->toString(true);   // "A♠" (with Unicode suit symbol)

// Get HTML representation
echo $aceOfSpades->toHtml();         // "[ A<span class="text-white">s</span> ]"
echo $aceOfSpades->toHtml(true);     // "[ A<span class="text-white">♠</span> ]"

// Check card equality
$card1 = Card::fromText('Ah');
$card2 = Card::fromText('Ah');
$card3 = Card::fromText('As');

$card1->isEqualTo($card2); // true - same face and suit
$card1->isEqualTo($card3); // false - different suit
Card::areEqual($card1, $card2); // true - static method alternative

Working with Card Enums

Card Faces

use PHPoker\Poker\Enum\CardFace;

// Accessing face values
CardFace::ACE->value;    // 12
CardFace::KING->value;   // 11
CardFace::QUEEN->value;  // 10
CardFace::JACK->value;   // 9
CardFace::TEN->value;    // 8
CardFace::TWO->value;    // 0

// Get symbol representation
CardFace::ACE->symbol();   // "A"
CardFace::KING->symbol();  // "K"
CardFace::TEN->symbol();   // "T"

// Get face value (numeric values for comparing cards)
CardFace::ACE->faceValue();     // 14 (Ace high by default)
CardFace::ACE->faceValue(true); // 1 (Ace low)
CardFace::KING->faceValue();    // 13
CardFace::TWO->faceValue();     // 2

// Parse from text
$face = CardFace::fromText('Q');  // CardFace::QUEEN
$face = CardFace::fromText('10'); // CardFace::TEN
$face = CardFace::fromText('t');  // CardFace::TEN (case-insensitive)
$face = CardFace::fromText('ace'); // CardFace::ACE (full name works too)

// Get all symbols
$symbols = CardFace::symbols(); // ['2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A']

// Increment a face
$face = CardFace::NINE;
$face->plus(1);  // CardFace::TEN
$face->plus(2);  // CardFace::JACK

Card Suits

use PHPoker\Poker\Enum\CardSuit;

// Accessing suits
CardSuit::CLUB;     // Club enum
CardSuit::DIAMOND;  // Diamond enum
CardSuit::HEART;    // Heart enum
CardSuit::SPADE;    // Spade enum

// Get symbol representation
CardSuit::CLUB->symbol();    // "♣"
CardSuit::DIAMOND->symbol(); // "♦"
CardSuit::HEART->symbol();   // "♥"
CardSuit::SPADE->symbol();   // "♠"

// Get text representation (for short form notation)
CardSuit::CLUB->text();    // "c"
CardSuit::DIAMOND->text(); // "d"
CardSuit::HEART->text();   // "h"
CardSuit::SPADE->text();   // "s"

// Parse from text
$suit = CardSuit::fromText('c');    // CardSuit::CLUB
$suit = CardSuit::fromText('');    // CardSuit::DIAMOND
$suit = CardSuit::fromText('heart'); // CardSuit::HEART
$suit = CardSuit::fromText('SPADE'); // CardSuit::SPADE (case-insensitive)

// Get a random suit
$randomSuit = CardSuit::random();

Working with Card Collections

Card collections allow you to work with groups of cards like hands and decks.

Creating Collections

use PHPoker\Poker\Collections\CardCollection;
use PHPoker\Poker\Card;
use PHPoker\Poker\Enum\CardFace;
use PHPoker\Poker\Enum\CardSuit;

// Create a collection with individual cards
$hand = CardCollection::make([
    Card::make(CardFace::ACE, CardSuit::SPADE),
    Card::make(CardFace::ACE, CardSuit::HEART),
]);

// Create a collection from text notation
$hand = CardCollection::fromText('As Ah Kh Kd 2c');

// Create a collection from array of text
$hand = CardCollection::fromText(['As', 'Ah', 'Kh', 'Kd', '2c']);

// Create a deck (all 52 cards, shuffled)
$deck = CardCollection::createDeck();

Manipulating Collections

// Get unique cards (remove duplicates)
$uniqueCards = $hand->uniqueCards();

// Sort cards by face value
$sortedAscending = $hand->sortByFaceValue();
$sortedDescending = $hand->sortByFaceValueDesc();

// Get cards of a specific face
$aces = $hand->ofFace(CardFace::ACE);

// Get cards of a specific suit
$hearts = $hand->ofSuit(CardSuit::HEART);

// Discard specific cards
$remainingCards = $hand->discard('As Ah'); // By string notation
$remainingCards = $hand->discard(['As', 'Ah']); // By array
$remainingCards = $hand->discard($otherCollection); // By collection

// Check if a collection contains a card, face, or suit
$hasAce = $hand->holding(CardFace::ACE);          // Check for an ace
$hasHearts = $hand->holding(CardSuit::HEART);     // Check for hearts
$hasAceOfSpades = $hand->holding(Card::fromText('As')); // Check for specific card

Collection Hand Evaluation

The library includes a powerful hand evaluation engine based on Kevin "CactusKev" Suffecool's algorithm with perfect-hash improvements by Paul Senzee. This provides fast and accurate poker hand evaluation.

Evaluating a Hand

use PHPoker\Poker\Collections\CardCollection;

// Create a hand from text notation
$royalFlush = CardCollection::fromText('Ah Kh Qh Jh Th');
$fourOfAKind = CardCollection::fromText('Ah Ad As Ac Kh');
$twoPair = CardCollection::fromText('Ah Ad Kh Ks Qc');
$highCard = CardCollection::fromText('Ah Kd Qs Jc 9h');

// Get the hand rank as an enum
$handRank = $royalFlush->evaluate();
echo $handRank->name; // "STRAIGHT_FLUSH" (Royal Flush is a type of Straight Flush)

$handRank = $fourOfAKind->evaluate();
echo $handRank->name; // "FOUR_OF_A_KIND"

$handRank = $twoPair->evaluate();
echo $handRank->name; // "TWO_PAIR"

$handRank = $highCard->evaluate();
echo $handRank->name; // "HIGH_CARD"

Comparing Hands

// Create two hands to compare
$royalFlush = CardCollection::fromText('Ah Kh Qh Jh Th');
$fourOfAKind = CardCollection::fromText('Ah Ad As Ac Kh');

// Get numerical ranks for each hand
$royalFlushRank = $royalFlush->rankHand();
$fourOfAKindRank = $fourOfAKind->rankHand();

// Compare the ranks (lower is better)
if ($royalFlushRank < $fourOfAKindRank) {
    echo "Royal Flush wins!";
} else {
    echo "Four of a Kind wins!";
}
// Output: "Royal Flush wins!"

// Another comparison
$fullHouse = CardCollection::fromText('Ah As Ad Kh Ks');
$flush = CardCollection::fromText('Ah Jh 8h 6h 2h');

if ($fullHouse->rankHand() < $flush->rankHand()) {
    echo "Full House wins!";
} else {
    echo "Flush wins!";
}
// Output: "Full House wins!"

Collection Analysis

// Get collection of unique faces
$uniqueFaces = $hand->faces();

// Get collection of unique suits
$uniqueSuits = $hand->suits();

// Count suits in the collection
$suitCounts = $hand->countSuits(); // Returns Collection with counts

// Count faces in the collection
$faceCounts = $hand->countFaces(); // Returns Collection with counts

// Find the difference between two collections
$remainingCards = $hand->diffCards($cardsToRemove);

Collection Output

// Convert to string (default space-separated)
echo $hand->toString();        // "As Ah Kh Kd 2c"

// Custom separator
echo $hand->toString(',');     // "As,Ah,Kh,Kd,2c"

// Convert to HTML
echo $hand->toHtml();          // HTML representation with colored suits

// Convert cards to their unique integer values
$cardIntegers = $hand->toIntegers();

🛠️ Development & Contributing

All contributions are welcomed -- bug fixes, features, ideas, criticisms, optimizations!

Take advantage of the included development tools:

🧹 Keep a modern codebase with Laravel Pint:

composer lint

✅ Run refactors using Rector

composer refacto

⚗️ Run static analysis using PHPStan:

composer test:types

✅ Run unit tests using PEST

composer test:unit

🚀 Run the entire test suite:

composer test

PHPoker was created by Nick Poulos under the MIT license.

About

The premier poker library for PHP

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Languages

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载