Skip to main content

Python poker library

Project description

pokerlib

PyPI version

A lightweight Python poker library, focusing on simplifying a Texas hold'em poker game implementation, when its io is supplied. It includes modules that help with hand parsing and poker game continuation.

To install, run

pip install pokerlib

If experiencing issues, specify the latest version as

pip install pokerlib==2.2.6

Usage

Library consists of a module for parsing cards, which can be used separately, and modules that aid in running a poker game.

HandParser

This module takes care of hand parsing. A hand usually consists of 2 dealt cards plus 5 on the board, and HandParser is heavily optimized to work with up to 7 cards (with more than 7 cards, this is no longer Texas hold'em). A card is defined as a pair of two enums - Rank and Suit. All of the enums used are of IntEnum type, so you can also freely interchange them for integers. Below is an example of how to construct two different hands and then compare them.

from pokerlib import HandParser
from pokerlib.enums import Rank, Suit

hand1 = HandParser([
    (Rank.KING, Suit.SPADE),
    (Rank.ACE, Suit.SPADE)
])

hand2 = HandParser([
    (Rank.NINE, Suit.SPADE),
    (Rank.TWO, Suit.CLUB)
])

board = [
    (Rank.EIGHT, Suit.SPADE),
    (Rank.TEN, Suit.SPADE),
    (Rank.JACK, Suit.SPADE),
    (Rank.QUEEN, Suit.SPADE),
    (Rank.TWO, Suit.HEART)
]

# add new cards to each hand
hand1 += board # add the board to hand1
hand2 += board # add the board to hand2

print(hand1.handenum) # Hand.STRAIGHTFLUSH
print(hand2.handenum) # Hand.STRAIGHTFLUSH
print(hand1 > hand2) # True

note: In the previous version, each hand had to be parsed manually with hand.parse(), now calling any of the methods requiring the hand to be parsed, triggers parsing automatically. This only happens once, except if the cards in a given hand change. The only way cards in a hand should change is through the __iadd__ method. If this method is called with hand already parsed, the hand is considered unparsed.

It is also possible to fetch hand's kickers.

hand = HandParser([
    (Rank.TWO, Suit.DIAMOND),
    (Rank.ACE, Suit.CLUB),
    (Rank.TWO, Suit.SPADE),
    (Rank.THREE, Suit.DIAMOND),
    (Rank.TEN, Suit.HEART),
    (Rank.SIX, Suit.HEART),
    (Rank.KING, Suit.CLUB)
])

print(list(hand.kickercards))
# [
#   (<Rank.ACE: 12>, <Suit.CLUB: 1>),
#   (<Rank.KING: 11>, <Suit.CLUB: 1>),
#   (<Rank.TEN: 8>, <Suit.HEART: 3>)
# ]

Using HandParser, we can estimate the probability of a given hand winning the game with given known cards on the table (as implemented in another python cli-app here). We do this by repeatedly random-sampling hands, then averaging the wins. Mathematically, this process converges to the probability by the law of large numbers.

Poker Game

A poker table can be established by providing its configuration. A poker table object responds to given input with appropriate output, which can be customized by overriding the two functions producing it.

from pokerlib import Table, Player, PlayerSeats

# table that prints outputs
class MyTable(Table):
    def publicOut(self, out_id, **kwargs):
        print(out_id, kwargs)
    def privateOut(self, player_id, out_id, **kwargs):
        print(out_id, kwargs)

# define a new table
table = MyTable(
    table_id = 0,
    seats = PlayerSeats([None] * 9),
    buyin = 100,
    small_blind = 5,
    big_blind = 10
)

We could have seated players on the seats inside MyTable constructor, but let's add them to the defined table.

player1 = Player(
    table_id = table.id,
    _id = 1,
    name = 'alice',
    money = table.buyin
)
player2 = Player(
    table_id = table.id,
    _id = 2,
    name = 'bob',
    money = table.buyin
)
# seat player1 at the first seat
table += player1, 0
# seat player2 at the first free seat
table += player2

Communication with the table object is established through specified enums, which can be modified by overriding table's publicIn method. Using enum IO identifiers, we can implement a poker game as shown below.

from pokerlib.enums import RoundPublicInId, TablePublicInId

table.publicIn(player1.id, TablePublicInId.STARTROUND)
table.publicIn(player1.id, RoundPublicInId.CALL)
table.publicIn(player2.id, RoundPublicInId.CHECK)
table.publicIn(player1.id, RoundPublicInId.CHECK)
table.publicIn(player2.id, RoundPublicInId.RAISE, raise_by=50)
table.publicIn(player1.id, RoundPublicInId.CALL)
table.publicIn(player1.id, RoundPublicInId.CHECK)
table.publicIn(player2.id, RoundPublicInId.CHECK)
table.publicIn(player1.id, RoundPublicInId.ALLIN)
table.publicIn(player2.id, RoundPublicInId.CALL)

Wrong inputs are mostly ignored, though they can produce a response, when it seems useful. As noted before, when providing input, the table object responds with output ids (e.g. PLAYERACTIONREQUIRED) along with additional data that depends on the output id. For all possible outputs, check RoundPublicInId and TablePublicInId enums.

A simple command line game, where you respond with enum names, can be implemented simply as in examples/round_simulate.py. Command

python examples/round_simulate.py 3

runs a poker game with 3 players using the terminal as IO. Note that responses are in non-formatted raw form.

Tests

Basic tests for this library are included. You can test HandParser by running

python tests/handparser_reactive.py

and Round with

python tests/round_test.py

Note that HandParser can be fuzz tested against another poker library pokerface with

python tests/handparser_against_pokerface.py

which means it is considered safe. On the other hand, Table may still have some bugs.

License

GNU General Public License v3.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pokerlib-2.2.7.tar.gz (26.7 kB view details)

Uploaded Source

Built Distribution

pokerlib-2.2.7-py3-none-any.whl (39.9 kB view details)

Uploaded Python 3

File details

Details for the file pokerlib-2.2.7.tar.gz.

File metadata

  • Download URL: pokerlib-2.2.7.tar.gz
  • Upload date:
  • Size: 26.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.1 CPython/3.10.12 Linux/5.15.90.1-microsoft-standard-WSL2

File hashes

Hashes for pokerlib-2.2.7.tar.gz
Algorithm Hash digest
SHA256 12929a6e1e960363481f0faefeb537c69e4c3ce7a7a2e068b3ebffb01eee490b
MD5 43f8b9190c92220b7ac7fdf8a1d8d44a
BLAKE2b-256 2a33702ac8f9d3a6e674c82319001a1bfc23f9f5ddb0aff63c6f5e5ae71f1570

See more details on using hashes here.

File details

Details for the file pokerlib-2.2.7-py3-none-any.whl.

File metadata

  • Download URL: pokerlib-2.2.7-py3-none-any.whl
  • Upload date:
  • Size: 39.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.1 CPython/3.10.12 Linux/5.15.90.1-microsoft-standard-WSL2

File hashes

Hashes for pokerlib-2.2.7-py3-none-any.whl
Algorithm Hash digest
SHA256 605d17bad00ffb611e2eb13a817de51bbbafcb42b9969b68482807917db76570
MD5 09c0373d539043502798ce72e635baef
BLAKE2b-256 fca7aebee0b0d0243ef5f4a66167b82ffae4a529df3629a32eb6173ab76065dc

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page