All Projects → ashelly → ACE_eval

ashelly / ACE_eval

Licence: MIT License
7-card Poker Hand Evaluator in 577 bytes

Programming Languages

c
50402 projects - #5 most used programming language
Makefile
30231 projects

Labels

Projects that are alternatives of or similar to ACE eval

Skpokereval
7-card Texas Hold'em hand evaluator
Stars: ✭ 193 (+436.11%)
Mutual labels:  poker
bet
This repository holds the implementation code of Pangea Poker white paper: https://bit.ly/3bdCz0Z
Stars: ✭ 15 (-58.33%)
Mutual labels:  poker
pokerwars.io-starterbot-python
A starter bot written in python for the pokerwars.io platform. To play: pull this code, register on pokerwars.io, get your API token and play!
Stars: ✭ 37 (+2.78%)
Mutual labels:  poker
Pokerrl
Framework for Multi-Agent Deep Reinforcement Learning in Poker
Stars: ✭ 214 (+494.44%)
Mutual labels:  poker
texas-poker-engine
Dummy Texas Poker Engine open source edition
Stars: ✭ 4 (-88.89%)
Mutual labels:  poker
poker-calculator
Poker calculator for Texas Hold’em
Stars: ✭ 22 (-38.89%)
Mutual labels:  poker
Pluribus
Implementation of Pluribus by Noam Brown & Tuomas Sandholm, a Superhuman AI for 6-MAX No-Limit Holdem Poker Bot.
Stars: ✭ 92 (+155.56%)
Mutual labels:  poker
Cards.jl
A package for representing hands of cards (quite compactly)
Stars: ✭ 41 (+13.89%)
Mutual labels:  poker
poinz
Distributed Planning Poker
Stars: ✭ 105 (+191.67%)
Mutual labels:  poker
scrum-planning-poker
Please feel FREE to try it and give feedback by searching Scrum敏捷估算 in WeChat mini program.
Stars: ✭ 30 (-16.67%)
Mutual labels:  poker
Casinosclient
果派德州客户端源代码,使用Unity3D引擎。
Stars: ✭ 217 (+502.78%)
Mutual labels:  poker
pluribus-hand-parser
Parsing the hand histories that poker AI Pluribus played
Stars: ✭ 54 (+50%)
Mutual labels:  poker
holdem
A texas holdem simulator build with WebAssembly and web workers
Stars: ✭ 42 (+16.67%)
Mutual labels:  poker
Qnmahjongserver
房卡麻将棋牌解决方案
Stars: ✭ 196 (+444.44%)
Mutual labels:  poker
41poker
a toolset for Texas Hold'em Poker
Stars: ✭ 13 (-63.89%)
Mutual labels:  poker
Deep Cfr
Scalable Implementation of Deep CFR and Single Deep CFR
Stars: ✭ 158 (+338.89%)
Mutual labels:  poker
easyPokerHUD
This is the official repository for easyPokerHUD.
Stars: ✭ 40 (+11.11%)
Mutual labels:  poker
rs-poker
No description or website provided.
Stars: ✭ 32 (-11.11%)
Mutual labels:  poker
cypherpoker.js
An open source peer-to-peer poker platform with cryptocurrency integration written in JavaScript.
Stars: ✭ 72 (+100%)
Mutual labels:  poker
PokerTexter
SMS App for Poker Odds. Runs on Flask + Twilio + Heroku.
Stars: ✭ 17 (-52.78%)
Mutual labels:  poker

ACE_eval

ACE Card Evaluator

(or maybe AShelly's Card Evaluator)

What's this?

It is indeed Yet Another Poker Evaluator. Specifically it is a 7-card hand evaluator implemented in under 600 bytes of C source code. It is not the tiniest evaluator, and certainly not the fastest, but the goal is to make it among the fastest tiny ones, or maybe the tiniest fast one.

How To Use It?.

In 4 simple steps:

  1. Initialize the deck with 52 calls to Card ACE_makecard(int n); This creates the internal card representation
  2. Create an empty hands with Card hand[ACEHAND]={0};
  3. Deal 7 cards to the hand with 7 calls to void ACE_addcard(Card* hand, Card card);
  4. Find the hand value with V = ACE_evaluate(Card* hand);
  • What is the hand value? A 32-bit value with the following layout:
    RRRR..AKQJT98765432akqjt98765432 4-bit Rank, 2 spares, 13 Value Card bits, 13 Kicker bits.

It is arranged so that

  • If V(a) > V(b) then hand a beats hand b. Equal hands have equal values.
  • You can quickly extract both the rank and the cards that make up the hand.

Ranks:

0:"High Card"
1:"One Pair
2""Two Pair",
3:"Three of a Kind",
4:"Straight",
5:"Flush",
6:"Full House",
7:"Four of a Kind",
8:"unused",
9:"Straight Flush"  
(There is no rank for "Royal Flush", since that's just a straight flush with the ace bit set.)

ace_decode.c contains example source to turn it back into a human-readable result

What makes it different?

It's very small, and fairly fast.

It started out as a fairly simple evaluator in Ruby, but morphed into C at some point. I came up with a reasonably efficient card-encoding scheme, and was happy with the results. But then, like so many before me, I came upon the "The Great Poker Hand Evaluator Roundup" on Coding the Wheel, and saw its description of the Two-plus-Two evaluator. So my quest for a super-fast evaluator was over before it really got started. But I was bothered by the 123MB lookup table need by two-plus-two, so I changed my focus to writing a fast but tiny evaluator instead.

Eventually I turned it into a StackOverflow code-golf entry. I recently dug it up and started making some tweaks. In it's tiniest form the evaluator function by itself is now 577 bytes of source code (ace_eval_golf.c).

There are several supporting files that make it into an actual program:

A) The smallest useful example is ace_microeval.c, which adds code to support human-readable string input, and brings the total size to 737 bytes.

Compiling on linux with gcc -s -Os ace_microeval.c creates a 6Kb executable, which you can run with:

>  echo 3C 4C 5C 6H 8D 3D 8H | ./a.out
 20084010
>  echo 3C 4C 5C 6H 8D 3D 8H | ./a.out | ./ace_decode
 2 Pair, Eights and Threes with a Six

B) The code for the original StackOverflow challenge is down to 894 bytes. This takes a list of 9 cards representing a 2-player game, and returns win/lose/draw statistics. (so_handcomp.c)

C) You can verify the results with accuracy_test.c which runs through all possible 7 card hands.

D) Test the speed with speed_test.c. ace_eval_golf.c clocks in at 23.5 Million hands /second. See OPTIMIZATION.md for versions that triple the speed. Fastest so far: ace_eval_decompress.c at 72Mhps.

E) ace_golf_5.c is a version which only handles 5 card hands, reducing the size down to 424 characters. (Plus 160 for the input handling)

So how does it work?

Cards are stored in a 32 bit word which has the following (implied) structure:

    struct card{
       unsigned num_A:2;
       unsigned num_K:2;
       unsigned num_Q:2;
       //....
       unsigned num_2:2;
       unsigned spare:2;
       unsigned spade:1;
       unsigned heart:1;
       unsigned diamond:1;
       unsigned club:1;
       };

or 0a0k0q0j0t09080706050403020..SHDC

A hand is 5 32 bit words, one for each suit, and one which has the hands or'd together, leaving a bit set each card value present.

Hands based on multiple cards are all detected using a single method: Add the four suit words together. This adds all the card counts in parallel. However there's one hitch: 4 of a kind would result in a '4' which is binary 100, which overflows the 2 bits allowed. The solution is simple: subtract the 5th word, which only has a 1 where there is a card. The result now has 'cardcount-1' for each value. This means that the word only has bits set if there is a pair or better.

The hand is further classified by splitting into sets of high(odd) and low(even) bits and doing a few more tests. A 4-of-a-kind has both bits set for the same face value (4-1=3=0b11). A 3-of-a-kind has only one odd bit set in the word: (3-1=2=0b10) A full house has one even and one odd bit set, or 2 odd bits (since 2 triples only counts as a full house). 1-pair has only 1 even bit, and 2-pair has 2 or 3.

Flushes are detected by examining each of the individual suit words: since cards are added into this word, the low 6 bits contains a count, offset by the position of the indicator bit. If the count is greater than or equal to 5, we have a flush, and we will use this suit instead of the whole hand for straight detection.

Straights are indicated by having 5 set bits in a row. So shift the hand one place, and AND with itself four times, and there will only be bits left on if it is a straight. One minor catch is that the Ace bit needs to be copied down to the '1's place for detecting 5-high straights.

That's a fairly small number of operations to get the rank of the hand. Once the rank is determined, the final value is found by selecting the five cards that make up the hand, and separating them into rank cards and kickers, and compressiing both parts down to 13 bits. In general the even or odd words already have the rank cards. The remaining cards are easily determined by XOR'ing those the hand. Taking the correct number of bits from there gives the kicker.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].