This repository contains a Go port of the Deuces poker hand evaluation library, originally written in Python. The goal of this project is to provide a fast and efficient poker hand evaluator in Go, maintaining the core logic and functionality of the original library.
- Card Representation: Efficient 32-bit integer representation of playing cards.
- Deck: Standard 52-card deck with shuffling and drawing capabilities.
- Lookup Table: Precomputed lookup tables for rapid poker hand evaluation.
- Evaluator: Evaluates 5, 6, or 7-card poker hands to determine their rank.
To build and run this project, you need to have Go installed on your system. You can download it from the official Go website: https://golang.org/dl/
-
Clone the repository:
git clone https://github.com/gregory-chatelier/go-deuces.git cd go-deuces -
Run tests to verify the installation:
go test ./...
To see a complete working example, navigate to the example directory and run:
cd example
go mod tidy
go run main.gopackage main
import (
"fmt"
"github.com/gregory-chatelier/go-deuces"
)
func main() {
// Create a card
card, err := deuces.NewCard("Qh")
if err != nil {
fmt.Printf("Error creating card: %v\n", err)
return
}
fmt.Printf("Card: %s\n", card.IntToPrettyStr())
// Get card properties
fmt.Printf("Rank: %d, Suit: %d, Prime: %d\n", card.GetRankInt(), card.GetSuitInt(), card.GetPrime())
}package main
import (
"fmt"
"github.com/gregory-chatelier/go-deuces"
)
func main() {
// Create a new deck
deck := deuces.NewDeck()
// Draw cards
hands := deck.Draw(5)
fmt.Print("Drawn cards: ")
for _, card := range hands {
fmt.Printf("%s ", card.IntToPrettyStr())
}
fmt.Println()
fmt.Printf("Cards left in deck: %d\n", len(deck.Cards))
}package main
import (
"fmt"
"github.com/gregory-chatelier/go-deuces"
)
func mustNewCard(s string) deuces.Card {
card, err := deuces.NewCard(s)
if err != nil {
// In a real application, you would handle this error more gracefully,
// e//.g., return an error or a default card. For example brevity, we panic.
panic(fmt.Sprintf("failed to create card %s: %v", s, err))
}
return card
}
func main() {
// Create an evaluator
evaluator := deuces.NewEvaluator()
// Define a board and a hand
board := []deuces.Card{
mustNewCard("As"),
mustNewCard("Ks"),
mustNewCard("Qs"),
mustNewCard("Js"),
mustNewCard("Ts"),
}
hand := []deuces.Card{
mustNewCard("2c"),
mustNewCard("3d"),
}
// Evaluate the hand
rank := evaluator.Evaluate(hand, board)
fmt.Printf("Hand rank: %d\n", rank)
// Get hand rank class and string
rankClass := evaluator.GetRankClass(rank)
fmt.Printf("Hand class: %s\n", evaluator.ClassToString(rankClass))
// Get percentage rank
percentage := evaluator.GetFiveCardRankPercentage(rank)
fmt.Printf("Percentage rank: %.2f%%\n", percentage*100)
}Based on benchmarks, this Go port evaluates poker hands approximately 6 to 7 times faster than the original Python Deuces library. This performance gain is achieved without leveraging Go's native threading capabilities. While significantly faster than the Python version, it's important to note that this implementation is still slower than highly optimized C/C++ implementations like Pokerstove.
This library provides a Monte Carlo simulation feature to estimate the win probability of a poker hand against a given number of opponents.
package main
import (
"fmt"
"github.com/gregory-chatelier/go-deuces"
)
func mustNewCard(s string) deuces.Card {
card, err := deuces.NewCard(s)
if err != nil {
panic(fmt.Sprintf("failed to create card %s: %v", s, err))
}
return card
}
func main() {
hand := []deuces.Card{mustNewCard("As"), mustNewCard("Ks")}
board := []deuces.Card{mustNewCard("Qs"), mustNewCard("Js"), mustNewCard("Ts")}
numOpponents := 3
iterations := 100000 // Number of simulations
result, err := deuces.EstimateWinProbability(hand, board, numOpponents, iterations)
if err != nil {
panic(err)
}
fmt.Println(result)
}This project is provided "as is", without warranty of any kind, express or implied. Use at your own risk.