cardrank

package module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 25, 2022 License: MIT Imports: 9 Imported by: 0

README

cardrank.io/cardrank

Package cardrank.io/cardrank is a library of types, utilities, and interfaces for working with playing cards, card decks, and evaluating poker hand ranks.

Supports Texas Holdem, Texas Holdem Short (6+), Texas Holdem Royal (10+), Omaha, Omaha Hi/Lo, Stud, Stud Hi/Lo, Razz, and Badugi.

Tests Go Report Card Reference Releases

Overview

The cardrank.io/cardrank package contains types for cards, card suits, card ranks, card decks, and hands of cards.

A single package level type provides a standard interface for dealing cards for, and evaluating poker hands of the following:

Hand evaluation and ranking of the different poker hand types is accomplished through pure Go implementations of well-known poker rank evaluation algorithms. Poker hands can be compared and ordered to determine the hand's winner(s).

Development of additional poker variants, such as Kansas City Lowball and Candian Stud (Sökö), is planned.

Using

To use within a Go package or module:

go get cardrank.io/cardrank

See package level Go documentation.

Quickstart

Complete examples for Texas Holdem, Texas Holdem Short (6+), Texas Holdem Royal (10+), Omaha, Omaha Hi/Lo, Stud, Stud Hi/Lo, Razz, and Badugi are available in the source repository. Other examples are available in the Go package documentation showing use of the package's types, utilities, and interfaces.

Texas Holdem

The following showcases a simple game of Texas Holdem:

package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"
	"time"

	"cardrank.io/cardrank"
)

func main() {
	const players = 6
	seed := time.Now().UnixNano()
	// note: use a better pseudo-random number generator
	rnd := rand.New(rand.NewSource(seed))
	pockets, board := cardrank.Holdem.Deal(rnd.Shuffle, players)
	hands := cardrank.Holdem.RankHands(pockets, board)
	fmt.Printf("------ Holdem %d ------\n", seed)
	fmt.Printf("Board:    %b\n", board)
	for i := 0; i < players; i++ {
		fmt.Printf("Player %d: %b %s %b %b\n", i+1, hands[i].Pocket(), hands[i].Description(), hands[i].Best(), hands[i].Unused())
	}
	h, pivot := cardrank.Order(hands)
	if pivot == 1 {
		fmt.Printf("Result:   Player %d wins with %s %b\n", h[0]+1, hands[h[0]].Description(), hands[h[0]].Best())
	} else {
		var s, b []string
		for j := 0; j < pivot; j++ {
			s = append(s, strconv.Itoa(h[j]+1))
			b = append(b, fmt.Sprintf("%b", hands[h[j]].Best()))
		}
		fmt.Printf("Result:   Players %s push with %s %s\n", strings.Join(s, ", "), hands[h[0]].Description(), strings.Join(b, ", "))
	}
}

Output:

------ Holdem 1653086388531833787 ------
Board:    [A♣ 3♥ Q♥ J♣ J♠]
Player 1: [5♣ 5♦] Two Pair, Jacks over Fives, kicker Ace [J♣ J♠ 5♣ 5♦ A♣] [Q♥ 3♥]
Player 2: [A♥ 7♠] Two Pair, Aces over Jacks, kicker Queen [A♣ A♥ J♣ J♠ Q♥] [7♠ 3♥]
Player 3: [8♥ 3♣] Two Pair, Jacks over Threes, kicker Ace [J♣ J♠ 3♣ 3♥ A♣] [Q♥ 8♥]
Player 4: [9♣ T♠] Pair, Jacks, kickers Ace, Queen, Ten [J♣ J♠ A♣ Q♥ T♠] [9♣ 3♥]
Player 5: [6♣ J♥] Three of a Kind, Jacks, kickers Ace, Queen [J♣ J♥ J♠ A♣ Q♥] [6♣ 3♥]
Player 6: [2♣ T♦] Pair, Jacks, kickers Ace, Queen, Ten [J♣ J♠ A♣ Q♥ T♦] [3♥ 2♣]
Result:   Player 5 wins with Three of a Kind, Jacks, kickers Ace, Queen [J♣ J♥ J♠ A♣ Q♥]
Omaha Hi/Lo

The following showcases a simple game of Omaha Hi/Lo, highlighting Hi/Lo winner determination:

package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"
	"time"

	"cardrank.io/cardrank"
)

func main() {
	const players = 6
	seed := time.Now().UnixNano()
	// note: use a better pseudo-random number generator
	rnd := rand.New(rand.NewSource(seed))
	pockets, board := cardrank.OmahaHiLo.Deal(rnd.Shuffle, players)
	hands := cardrank.OmahaHiLo.RankHands(pockets, board)
	fmt.Printf("------ OmahaHiLo %d ------\n", seed)
	fmt.Printf("Board: %b\n", board)
	for i := 0; i < players; i++ {
		fmt.Printf("Player %d: %b\n", i+1, pockets[i])
		fmt.Printf("  Hi: %s %b %b\n", hands[i].Description(), hands[i].Best(), hands[i].Unused())
		if hands[i].LowValid() {
			fmt.Printf("  Lo: %s %b %b\n", hands[i].LowDescription(), hands[i].LowBest(), hands[i].LowUnused())
		} else {
			fmt.Printf("  Lo: None\n")
		}
	}
	h, hPivot := cardrank.Order(hands)
	l, lPivot := cardrank.LowOrder(hands)
	typ := "wins"
	if lPivot == 0 {
		typ = "scoops"
	}
	if hPivot == 1 {
		fmt.Printf("Result (Hi): Player %d %s with %s %b\n", h[0]+1, typ, hands[h[0]].Description(), hands[h[0]].Best())
	} else {
		var s, b []string
		for i := 0; i < hPivot; i++ {
			s = append(s, strconv.Itoa(h[i]+1))
			b = append(b, fmt.Sprintf("%b", hands[h[i]].Best()))
		}
		fmt.Printf("Result (Hi): Players %s push with %s %s\n", strings.Join(s, ", "), hands[h[0]].Description(), strings.Join(b, ", "))
	}
	if lPivot == 1 {
		fmt.Printf("Result (Lo): Player %d wins with %s %b\n", l[0]+1, hands[l[0]].LowDescription(), hands[l[0]].LowBest())
	} else if lPivot > 1 {
		var s, b []string
		for j := 0; j < lPivot; j++ {
			s = append(s, strconv.Itoa(l[j]+1))
			b = append(b, fmt.Sprintf("%b", hands[l[j]].LowBest()))
		}
		fmt.Printf("Result (Lo): Players %s push with %s %s\n", strings.Join(s, ", "), hands[l[0]].LowDescription(), strings.Join(b, ", "))
	} else {
		fmt.Printf("Result (Lo): no player made a low hand\n")
	}
}

Output:

------ OmahaHiLo 1653086518494356973 ------
Board: [2♣ K♥ 6♠ 5♣ 8♠]
Player 1: [A♣ 9♦ J♦ T♣]
  Hi: Nothing, Ace-high, kickers King, Jack, Eight, Six [A♣ K♥ J♦ 8♠ 6♠] [9♦ T♣ 2♣ 5♣]
  Lo: None
Player 2: [7♣ 5♥ 6♣ T♦]
  Hi: Two Pair, Sixes over Fives, kicker King [6♣ 6♠ 5♣ 5♥ K♥] [7♣ T♦ 2♣ 8♠]
  Lo: Eight-low [8♠ 7♣ 6♠ 5♥ 2♣] [6♣ T♦ K♥ 5♣]
Player 3: [4♣ Q♥ K♣ Q♦]
  Hi: Pair, Kings, kickers Queen, Eight, Six [K♣ K♥ Q♥ 8♠ 6♠] [4♣ Q♦ 2♣ 5♣]
  Lo: None
Player 4: [5♦ 3♦ 9♠ 9♣]
  Hi: Pair, Nines, kickers King, Eight, Six [9♣ 9♠ K♥ 8♠ 6♠] [5♦ 3♦ 2♣ 5♣]
  Lo: Eight-low [8♠ 6♠ 5♦ 3♦ 2♣] [9♠ 9♣ K♥ 5♣]
Player 5: [2♠ K♦ 2♥ 8♦]
  Hi: Three of a Kind, Twos, kickers King, Eight [2♣ 2♥ 2♠ K♥ 8♠] [K♦ 8♦ 6♠ 5♣]
  Lo: None
Player 6: [J♠ 3♣ K♠ J♥]
  Hi: Pair, Kings, kickers Jack, Eight, Six [K♥ K♠ J♠ 8♠ 6♠] [3♣ J♥ 2♣ 5♣]
  Lo: None
Result (Hi): Player 5 wins with Three of a Kind, Twos, kickers King, Eight [2♣ 2♥ 2♠ K♥ 8♠]
Result (Lo): Player 4 wins with Eight-low [8♠ 6♠ 5♦ 3♦ 2♣]
Hand Ranking

Poker Hand's make use of a HandRank to determine the relative rank of a Hand, on a low-to-high basis. Higher poker hands have a lower value HandRank than lower poker hands. For example, a StraightFlush will have a lower HandRank than a FullHouse.

When a Hand is created, a Hi and Lo (if applicable) HandRank is evaluated, and made available via Hand.Rank and Hand.LowRank methods, respectively. The Hi and Lo HandRank's are evaluated by a Ranker, dependent on the Hand's Type:

Cactus Kev

For regular poker hand types (Holdem, Royal, Omaha, and Stud), poker hand rank is determined by Go implementations of different Cactus Kev evaluators:

See below for more information on the default ranker in use by the package, and for information on using build tags to disable for different scenarios.

Default Ranker

The package-level DefaultRanker variable is used for regular poker evaluation. For most scenarios, the HybridRanker provides the best possible evaluation performance, and is used by default when no build tags have been specified.

Hybrid

The HybridRanker uses either the CactusFastRanker or an instance of the TwoPlusTwoRanker depending on the Hand having 5, 6, or 7 cards.

Two-Plus-Two

The TwoPlusTwoRanker makes use of a large (approximately 130 MiB) lookup table to accomplish extremely fast 5, 6 and 7 card hand rank evaluation. Due to the large size of the lookup table, the TwoPlusTwoRanker will be excluded when using the using the portable or embedded build tags.

Other Variants

For the Short, OmahaHiLo, StudHiLo, Razz, and Badugi poker hand types, a 6-plus, an 8-or-better, a Razz, and a Badugi poker hand rank evaluators are used.

Winner Determination

Winner(s) are determined by the lowest possible HandRank when comparing a Hand's Rank or LowRank against another hand. Two or more hands having a HandRank of equal value indicate that the hands have equivalent HandRank, and thus have both won.

As such, when hands are sorted (low-to-high) by Rank or LowRank, the winner(s) of a hand will be all the hands in the lowest position and having the same HandRank.

Comparing Hands

A Hand can be compared to another Hand using Compare and LowCompare.

Compare and LowCompare return -1, 0, or +1, making it easy to compare or sort hands:

// Compare hands:
if hand1.Compare(hand2) < 0 {
	fmt.Printf("%s is a winner!", hand1)
}

// Compare low hands:
// (applicable only for a hand types that supports low hands)
if hand1.LowCompare(hand2) == 0 {
	fmt.Printf("%s and %s are equal!", hand1, hand2)
}

// Sort hands:
sort.Slice(hands, func(i, j int) bool {
	return hands[i].Compare(hands[j]) < 0
})
Ordering Hands

Order and LowOrder determine the winner(s) of a hand by ordering the indexes of a []*Hand and returning the list of ordered hands as a []int and an int pivot indicating the position within the returned list demarcating winning and losing hands.

A Hand whose index is in position i < pivot is considered to be the winner(s) of the hand. Hi hands are guaranteed to have 1 or more winner(s), while Lo hands have 0 or more winner(s):

// Order hands by lowest hand rank, low to high:
h, pivot := cardrank.Order(hands)
for i := 0; i < pivot; i++ {
	fmt.Printf("%s is a Hi winner!", hands[h[i]])
}

// Order low hands by lowest hand rank, low to high:
// (applicable only for a hand types that supports low hands)
l, pivot := cardrank.LowOrder(hands)
for i := 0; i < pivot; i++ {
	fmt.Printf("%s is a Lo winner!", hands[h[i]])
}

See the examples for an overview of using the package APIs for winner determination for the different Type of poker hands.

Build Tags

Build tags can be used with go build to change the package's build configuration. Available tags:

portable

The portable tag disables the TwoPlusTwoRanker, in effect excluding the the large lookup table, and creating significantly smaller binaries but at the cost of more expensive poker hand rank evaluation. Useful when building for portable or embedded environments, such as a WASM application:

GOOS=js GOARCH=wasm go build -tags portable
embedded

The embedded tag disables the CactusFastRanker and the TwoPlusTwoRanker, creating the smallest possible binaries:

GOOS=js GOARCH=wasm go build -tags embedded
noinit

The noinit tag disables the packagelevel initialization of variables DefaultRanker and DefaultSixPlusRanker. Useful when applications need the fastest possible startup times and can defer initialization, or when using a third-party Ranker algorithm:

GOOS=js GOARCH=wasm go build -tags 'embedded noinit'

When using the noinit build tag, the user will need to call the Init func to set DefaultCactus, DefaultRanker and DefaultSixPlusRanker automatically or by manually specifying the variables:

// Set DefaultCactus, DefaultRanker and DefaultSixPlusRanker based on
// available implementations:
cardrank.Init()

// Set manually (such as when using a third-party implementation):
cardrank.DefaultCactus = cardrank.CactusRanker
cardrank.DefaultRanker = cardrank.HandRanker(cardrank.CactusRanker)
cardrank.DefaultSixPlusRanker = cardrank.HandRanker(cardrank.SixPlusRanker(cardrank.CactusRanker))

Future Development

Rankers for Kansas City Lowball, Sökö, and other poker variants will be added to this package in addition to standardized interfaces for managing poker tables and games.

Documentation

Overview

Package cardrank.io/cardrank is a library of types, utilities, and interfaces for working with playing cards, card decks, and evaluating poker hand ranks.

Supports Texas Holdem, Texas Holdem Short (6+), Texas Holdem Royal (10+), Omaha, Omaha Hi/Lo, Stud, Stud Hi/Lo, Razz, and Badugi.

Example (Badugi)
package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"

	"cardrank.io/cardrank"
)

func main() {
	for i, game := range []struct {
		seed    int64
		players int
	}{
		{119, 2},
		{321, 5},
		{408, 6},
		{455, 6},
		{1113, 6},
	} {
		// note: use a real random source
		rnd := rand.New(rand.NewSource(game.seed))
		pockets, _ := cardrank.Badugi.Deal(rnd.Shuffle, game.players)
		hands := cardrank.Badugi.RankHands(pockets, nil)
		fmt.Printf("------ Badugi %d ------\n", i+1)
		for j := 0; j < game.players; j++ {
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, hands[j].Pocket(), hands[j].Description(), hands[j].Best(), hands[j].Unused())
		}
		h, pivot := cardrank.Order(hands)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s %b\n", h[0]+1, hands[h[0]].Description(), hands[h[0]].Best())
		} else {
			var s, b []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(h[j]+1))
				b = append(b, fmt.Sprintf("%b", hands[h[j]].Best()))
			}
			fmt.Printf("Result:   Players %s push with %s %s\n", strings.Join(s, ", "), hands[h[0]].Description(), strings.Join(b, ", "))
		}
	}
}
Output:

------ Badugi 1 ------
Player 1: [K♥ 7♣ J♣ 4♣] King, Four-low [K♥ 4♣] [J♣ 7♣]
Player 2: [A♥ 5♠ Q♠ 2♠] Two, Ace-low [2♠ A♥] [Q♠ 5♠]
Result:   Player 2 wins with Two, Ace-low [2♠ A♥]
------ Badugi 2 ------
Player 1: [3♠ 6♦ Q♦ K♦] Six, Three-low [6♦ 3♠] [K♦ Q♦]
Player 2: [J♦ 3♦ Q♣ K♠] King, Queen, Three-low [K♠ Q♣ 3♦] [J♦]
Player 3: [T♦ 2♥ T♠ 8♥] Ten, Two-low [T♠ 2♥] [T♦ 8♥]
Player 4: [8♣ 8♦ Q♥ Q♠] Queen, Eight-low [Q♠ 8♦] [Q♥ 8♣]
Player 5: [6♣ A♥ 4♥ 6♠] Six, Ace-low [6♠ A♥] [6♣ 4♥]
Result:   Player 2 wins with King, Queen, Three-low [K♠ Q♣ 3♦]
------ Badugi 3 ------
Player 1: [K♠ J♠ 3♠ 5♣] Five, Three-low [5♣ 3♠] [K♠ J♠]
Player 2: [7♠ 4♠ Q♠ 3♣] Four, Three-low [4♠ 3♣] [Q♠ 7♠]
Player 3: [T♠ 5♥ 3♥ 8♦] Ten, Eight, Three-low [T♠ 8♦ 3♥] [5♥]
Player 4: [4♣ 8♥ 2♣ T♦] Ten, Eight, Two-low [T♦ 8♥ 2♣] [4♣]
Player 5: [6♠ K♦ J♦ 2♠] Jack, Two-low [J♦ 2♠] [K♦ 6♠]
Player 6: [Q♦ 2♦ A♣ T♣] Two, Ace-low [2♦ A♣] [Q♦ T♣]
Result:   Player 4 wins with Ten, Eight, Two-low [T♦ 8♥ 2♣]
------ Badugi 4 ------
Player 1: [6♠ Q♥ 2♣ 9♠] Queen, Six, Two-low [Q♥ 6♠ 2♣] [9♠]
Player 2: [3♦ T♣ K♥ 4♥] Ten, Four, Three-low [T♣ 4♥ 3♦] [K♥]
Player 3: [6♥ J♥ 4♦ Q♦] Six, Four-low [6♥ 4♦] [Q♦ J♥]
Player 4: [A♣ J♣ 5♣ K♠] King, Ace-low [K♠ A♣] [J♣ 5♣]
Player 5: [K♣ A♠ 8♣ 5♥] Eight, Five, Ace-low [8♣ 5♥ A♠] [K♣]
Player 6: [Q♠ J♠ 8♦ 7♥] Jack, Eight, Seven-low [J♠ 8♦ 7♥] [Q♠]
Result:   Player 5 wins with Eight, Five, Ace-low [8♣ 5♥ A♠]
------ Badugi 5 ------
Player 1: [3♦ T♥ A♣ 7♦] Ten, Three, Ace-low [T♥ 3♦ A♣] [7♦]
Player 2: [5♣ 6♠ 4♦ J♠] Six, Five, Four-low [6♠ 5♣ 4♦] [J♠]
Player 3: [9♠ 3♣ Q♠ 7♠] Seven, Three-low [7♠ 3♣] [Q♠ 9♠]
Player 4: [5♦ K♠ T♠ 8♠] Eight, Five-low [8♠ 5♦] [K♠ T♠]
Player 5: [J♥ 7♥ J♣ 2♣] Seven, Two-low [7♥ 2♣] [J♥ J♣]
Player 6: [3♠ 7♣ 2♠ 2♥] Seven, Three, Two-low [7♣ 3♠ 2♥] [2♠]
Result:   Player 2 wins with Six, Five, Four-low [6♠ 5♣ 4♦]
Example (Holdem)
package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"

	"cardrank.io/cardrank"
)

func main() {
	for i, game := range []struct {
		seed    int64
		players int
	}{
		{3, 2},
		{278062, 2},
		{1928, 6},
		{6151, 6},
		{5680, 6},
		{23965, 2},
		{13959, 2},
		{23366, 6},
		{29555, 3},
		{472600, 3},
		{107, 10},
	} {
		// note: use a real random source
		rnd := rand.New(rand.NewSource(game.seed))
		pockets, board := cardrank.Holdem.Deal(rnd.Shuffle, game.players)
		hands := cardrank.Holdem.RankHands(pockets, board)
		fmt.Printf("------ Holdem %d ------\n", i+1)
		fmt.Printf("Board:    %b\n", board)
		for j := 0; j < game.players; j++ {
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, hands[j].Pocket(), hands[j].Description(), hands[j].Best(), hands[j].Unused())
		}
		h, pivot := cardrank.Order(hands)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s %b\n", h[0]+1, hands[h[0]].Description(), hands[h[0]].Best())
		} else {
			var s, b []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(h[j]+1))
				b = append(b, fmt.Sprintf("%b", hands[h[j]].Best()))
			}
			fmt.Printf("Result:   Players %s push with %s %s\n", strings.Join(s, ", "), hands[h[0]].Description(), strings.Join(b, ", "))
		}
	}
}
Output:

------ Holdem 1 ------
Board:    [J♠ T♠ 2♦ 2♠ Q♥]
Player 1: [6♦ 8♠] Pair, Twos, kickers Queen, Jack, Ten [2♦ 2♠ Q♥ J♠ T♠] [8♠ 6♦]
Player 2: [7♠ 4♣] Pair, Twos, kickers Queen, Jack, Ten [2♦ 2♠ Q♥ J♠ T♠] [7♠ 4♣]
Result:   Players 1, 2 push with Pair, Twos, kickers Queen, Jack, Ten [2♦ 2♠ Q♥ J♠ T♠], [2♦ 2♠ Q♥ J♠ T♠]
------ Holdem 2 ------
Board:    [8♠ 9♠ J♠ 9♣ T♠]
Player 1: [7♠ T♣] Straight Flush, Jack-high [J♠ T♠ 9♠ 8♠ 7♠] [T♣ 9♣]
Player 2: [6♦ Q♠] Straight Flush, Queen-high [Q♠ J♠ T♠ 9♠ 8♠] [9♣ 6♦]
Result:   Player 2 wins with Straight Flush, Queen-high [Q♠ J♠ T♠ 9♠ 8♠]
------ Holdem 3 ------
Board:    [A♠ T♣ K♠ J♣ 6♥]
Player 1: [T♥ 2♠] Pair, Tens, kickers Ace, King, Jack [T♣ T♥ A♠ K♠ J♣] [6♥ 2♠]
Player 2: [Q♣ J♠] Straight, Ace-high [A♠ K♠ Q♣ J♣ T♣] [J♠ 6♥]
Player 3: [4♥ Q♠] Straight, Ace-high [A♠ K♠ Q♠ J♣ T♣] [6♥ 4♥]
Player 4: [5♦ K♦] Pair, Kings, kickers Ace, Jack, Ten [K♦ K♠ A♠ J♣ T♣] [6♥ 5♦]
Player 5: [Q♥ 7♣] Straight, Ace-high [A♠ K♠ Q♥ J♣ T♣] [7♣ 6♥]
Player 6: [6♠ 3♣] Pair, Sixes, kickers Ace, King, Jack [6♥ 6♠ A♠ K♠ J♣] [T♣ 3♣]
Result:   Players 2, 3, 5 push with Straight, Ace-high [A♠ K♠ Q♣ J♣ T♣], [A♠ K♠ Q♠ J♣ T♣], [A♠ K♠ Q♥ J♣ T♣]
------ Holdem 4 ------
Board:    [9♦ J♣ A♥ 9♥ J♠]
Player 1: [K♠ 7♦] Two Pair, Jacks over Nines, kicker Ace [J♣ J♠ 9♦ 9♥ A♥] [K♠ 7♦]
Player 2: [A♦ 4♥] Two Pair, Aces over Jacks, kicker Nine [A♦ A♥ J♣ J♠ 9♦] [9♥ 4♥]
Player 3: [3♥ T♣] Two Pair, Jacks over Nines, kicker Ace [J♣ J♠ 9♦ 9♥ A♥] [T♣ 3♥]
Player 4: [8♦ 9♠] Full House, Nines full of Jacks [9♦ 9♥ 9♠ J♣ J♠] [A♥ 8♦]
Player 5: [8♥ 6♣] Two Pair, Jacks over Nines, kicker Ace [J♣ J♠ 9♦ 9♥ A♥] [8♥ 6♣]
Player 6: [5♥ J♦] Full House, Jacks full of Nines [J♣ J♦ J♠ 9♦ 9♥] [A♥ 5♥]
Result:   Player 6 wins with Full House, Jacks full of Nines [J♣ J♦ J♠ 9♦ 9♥]
------ Holdem 5 ------
Board:    [3♠ 9♥ A♦ 6♥ Q♦]
Player 1: [T♦ 8♦] Nothing, Ace-high, kickers Queen, Ten, Nine, Eight [A♦ Q♦ T♦ 9♥ 8♦] [6♥ 3♠]
Player 2: [K♠ T♣] Nothing, Ace-high, kickers King, Queen, Ten, Nine [A♦ K♠ Q♦ T♣ 9♥] [6♥ 3♠]
Player 3: [7♥ 8♣] Nothing, Ace-high, kickers Queen, Nine, Eight, Seven [A♦ Q♦ 9♥ 8♣ 7♥] [6♥ 3♠]
Player 4: [4♥ 7♦] Nothing, Ace-high, kickers Queen, Nine, Seven, Six [A♦ Q♦ 9♥ 7♦ 6♥] [4♥ 3♠]
Player 5: [K♥ 5♦] Nothing, Ace-high, kickers King, Queen, Nine, Six [A♦ K♥ Q♦ 9♥ 6♥] [5♦ 3♠]
Player 6: [T♥ 5♣] Nothing, Ace-high, kickers Queen, Ten, Nine, Six [A♦ Q♦ T♥ 9♥ 6♥] [5♣ 3♠]
Result:   Player 2 wins with Nothing, Ace-high, kickers King, Queen, Ten, Nine [A♦ K♠ Q♦ T♣ 9♥]
------ Holdem 6 ------
Board:    [T♥ 6♥ 7♥ 2♥ 7♣]
Player 1: [6♣ 6♠] Full House, Sixes full of Sevens [6♣ 6♥ 6♠ 7♣ 7♥] [T♥ 2♥]
Player 2: [K♥ 5♥] Flush, King-high [K♥ T♥ 7♥ 6♥ 5♥] [2♥ 7♣]
Result:   Player 1 wins with Full House, Sixes full of Sevens [6♣ 6♥ 6♠ 7♣ 7♥]
------ Holdem 7 ------
Board:    [4♦ A♥ A♣ 4♠ A♦]
Player 1: [T♥ T♠] Full House, Aces full of Tens [A♣ A♦ A♥ T♥ T♠] [4♦ 4♠]
Player 2: [9♣ A♠] Four of a Kind, Aces, kicker Four [A♣ A♦ A♥ A♠ 4♦] [4♠ 9♣]
Result:   Player 2 wins with Four of a Kind, Aces, kicker Four [A♣ A♦ A♥ A♠ 4♦]
------ Holdem 8 ------
Board:    [Q♥ T♥ T♠ J♥ K♥]
Player 1: [A♥ 9♠] Straight Flush, Ace-high, Royal [A♥ K♥ Q♥ J♥ T♥] [T♠ 9♠]
Player 2: [Q♣ 2♠] Two Pair, Queens over Tens, kicker King [Q♣ Q♥ T♥ T♠ K♥] [J♥ 2♠]
Player 3: [6♥ 3♦] Flush, King-high [K♥ Q♥ J♥ T♥ 6♥] [T♠ 3♦]
Player 4: [8♥ 8♦] Flush, King-high [K♥ Q♥ J♥ T♥ 8♥] [T♠ 8♦]
Player 5: [4♦ Q♦] Two Pair, Queens over Tens, kicker King [Q♦ Q♥ T♥ T♠ K♥] [J♥ 4♦]
Player 6: [A♦ T♣] Straight, Ace-high [A♦ K♥ Q♥ J♥ T♣] [T♥ T♠]
Result:   Player 1 wins with Straight Flush, Ace-high, Royal [A♥ K♥ Q♥ J♥ T♥]
------ Holdem 9 ------
Board:    [A♣ 2♣ 4♣ 5♣ 9♥]
Player 1: [T♣ J♦] Flush, Ace-high [A♣ T♣ 5♣ 4♣ 2♣] [J♦ 9♥]
Player 2: [4♥ 6♠] Pair, Fours, kickers Ace, Nine, Six [4♣ 4♥ A♣ 9♥ 6♠] [5♣ 2♣]
Player 3: [3♣ T♠] Straight Flush, Five-high, Steel Wheel [5♣ 4♣ 3♣ 2♣ A♣] [T♠ 9♥]
Result:   Player 3 wins with Straight Flush, Five-high, Steel Wheel [5♣ 4♣ 3♣ 2♣ A♣]
------ Holdem 10 ------
Board:    [8♣ J♣ 8♥ 7♥ 9♥]
Player 1: [8♦ 8♠] Four of a Kind, Eights, kicker Jack [8♣ 8♦ 8♥ 8♠ J♣] [9♥ 7♥]
Player 2: [6♥ T♥] Straight Flush, Ten-high [T♥ 9♥ 8♥ 7♥ 6♥] [J♣ 8♣]
Player 3: [3♣ K♥] Pair, Eights, kickers King, Jack, Nine [8♣ 8♥ K♥ J♣ 9♥] [7♥ 3♣]
Result:   Player 2 wins with Straight Flush, Ten-high [T♥ 9♥ 8♥ 7♥ 6♥]
------ Holdem 11 ------
Board:    [5♥ 3♣ J♥ 6♦ 6♣]
Player 1: [8♥ 4♥] Pair, Sixes, kickers Jack, Eight, Five [6♣ 6♦ J♥ 8♥ 5♥] [4♥ 3♣]
Player 2: [T♣ 3♥] Two Pair, Sixes over Threes, kicker Jack [6♣ 6♦ 3♣ 3♥ J♥] [T♣ 5♥]
Player 3: [A♠ 6♠] Three of a Kind, Sixes, kickers Ace, Jack [6♣ 6♦ 6♠ A♠ J♥] [5♥ 3♣]
Player 4: [J♠ 8♠] Two Pair, Jacks over Sixes, kicker Eight [J♥ J♠ 6♣ 6♦ 8♠] [5♥ 3♣]
Player 5: [6♥ 2♣] Three of a Kind, Sixes, kickers Jack, Five [6♣ 6♦ 6♥ J♥ 5♥] [3♣ 2♣]
Player 6: [T♥ Q♣] Pair, Sixes, kickers Queen, Jack, Ten [6♣ 6♦ Q♣ J♥ T♥] [5♥ 3♣]
Player 7: [Q♠ 5♦] Two Pair, Sixes over Fives, kicker Queen [6♣ 6♦ 5♦ 5♥ Q♠] [J♥ 3♣]
Player 8: [T♠ 2♠] Pair, Sixes, kickers Jack, Ten, Five [6♣ 6♦ J♥ T♠ 5♥] [3♣ 2♠]
Player 9: [5♣ 9♦] Two Pair, Sixes over Fives, kicker Jack [6♣ 6♦ 5♣ 5♥ J♥] [9♦ 3♣]
Player 10: [J♣ A♣] Two Pair, Jacks over Sixes, kicker Ace [J♣ J♥ 6♣ 6♦ A♣] [5♥ 3♣]
Result:   Player 3 wins with Three of a Kind, Sixes, kickers Ace, Jack [6♣ 6♦ 6♠ A♠ J♥]
Example (Omaha)
package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"

	"cardrank.io/cardrank"
)

func main() {
	for i, game := range []struct {
		seed    int64
		players int
	}{
		{119, 2},
		{321, 5},
		{408, 6},
		{455, 6},
		{1113, 6},
	} {
		// note: use a real random source
		rnd := rand.New(rand.NewSource(game.seed))
		pockets, board := cardrank.Omaha.Deal(rnd.Shuffle, game.players)
		hands := cardrank.Omaha.RankHands(pockets, board)
		fmt.Printf("------ Omaha %d ------\n", i+1)
		fmt.Printf("Board:    %b\n", board)
		for j := 0; j < game.players; j++ {
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, hands[j].Pocket(), hands[j].Description(), hands[j].Best(), hands[j].Unused())
		}
		h, pivot := cardrank.Order(hands)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s %b\n", h[0]+1, hands[h[0]].Description(), hands[h[0]].Best())
		} else {
			var s, b []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(h[j]+1))
				b = append(b, fmt.Sprintf("%b", hands[h[j]].Best()))
			}
			fmt.Printf("Result:   Players %s push with %s %s\n", strings.Join(s, ", "), hands[h[0]].Description(), strings.Join(b, ", "))
		}
	}
}
Output:

------ Omaha 1 ------
Board:    [3♥ 5♥ 4♥ 7♥ K♣]
Player 1: [K♥ 7♣ J♣ 4♣] Two Pair, Kings over Sevens, kicker Five [K♣ K♥ 7♣ 7♥ 5♥] [J♣ 4♣ 3♥ 4♥]
Player 2: [A♥ 5♠ Q♠ 2♠] Straight, Five-high [5♥ 4♥ 3♥ 2♠ A♥] [5♠ Q♠ 7♥ K♣]
Result:   Player 2 wins with Straight, Five-high [5♥ 4♥ 3♥ 2♠ A♥]
------ Omaha 2 ------
Board:    [3♥ 7♣ 3♣ 9♠ 9♣]
Player 1: [3♠ 6♦ Q♦ K♦] Three of a Kind, Threes, kickers King, Nine [3♣ 3♥ 3♠ K♦ 9♠] [6♦ Q♦ 7♣ 9♣]
Player 2: [J♦ 3♦ Q♣ K♠] Three of a Kind, Threes, kickers King, Nine [3♣ 3♦ 3♥ K♠ 9♠] [J♦ Q♣ 7♣ 9♣]
Player 3: [T♦ 2♥ T♠ 8♥] Two Pair, Tens over Nines, kicker Seven [T♦ T♠ 9♣ 9♠ 7♣] [2♥ 8♥ 3♥ 3♣]
Player 4: [8♣ 8♦ Q♥ Q♠] Two Pair, Queens over Nines, kicker Seven [Q♥ Q♠ 9♣ 9♠ 7♣] [8♣ 8♦ 3♥ 3♣]
Player 5: [6♣ A♥ 4♥ 6♠] Two Pair, Nines over Sixes, kicker Seven [9♣ 9♠ 6♣ 6♠ 7♣] [A♥ 4♥ 3♥ 3♣]
Result:   Players 1, 2 push with Three of a Kind, Threes, kickers King, Nine [3♣ 3♥ 3♠ K♦ 9♠], [3♣ 3♦ 3♥ K♠ 9♠]
------ Omaha 3 ------
Board:    [J♣ T♥ 4♥ K♣ Q♣]
Player 1: [K♠ J♠ 3♠ 5♣] Two Pair, Kings over Jacks, kicker Queen [K♣ K♠ J♣ J♠ Q♣] [3♠ 5♣ T♥ 4♥]
Player 2: [7♠ 4♠ Q♠ 3♣] Two Pair, Queens over Fours, kicker King [Q♣ Q♠ 4♥ 4♠ K♣] [7♠ 3♣ J♣ T♥]
Player 3: [T♠ 5♥ 3♥ 8♦] Pair, Tens, kickers King, Queen, Eight [T♥ T♠ K♣ Q♣ 8♦] [5♥ 3♥ J♣ 4♥]
Player 4: [4♣ 8♥ 2♣ T♦] Flush, King-high [K♣ Q♣ J♣ 4♣ 2♣] [8♥ T♦ T♥ 4♥]
Player 5: [6♠ K♦ J♦ 2♠] Two Pair, Kings over Jacks, kicker Queen [K♣ K♦ J♣ J♦ Q♣] [6♠ 2♠ T♥ 4♥]
Player 6: [Q♦ 2♦ A♣ T♣] Straight Flush, Ace-high, Royal [A♣ K♣ Q♣ J♣ T♣] [Q♦ 2♦ T♥ 4♥]
Result:   Player 6 wins with Straight Flush, Ace-high, Royal [A♣ K♣ Q♣ J♣ T♣]
------ Omaha 4 ------
Board:    [2♦ 6♦ 6♣ Q♣ 7♣]
Player 1: [6♠ Q♥ 2♣ 9♠] Full House, Sixes full of Queens [6♣ 6♦ 6♠ Q♣ Q♥] [2♣ 9♠ 2♦ 7♣]
Player 2: [3♦ T♣ K♥ 4♥] Pair, Sixes, kickers King, Queen, Ten [6♣ 6♦ K♥ Q♣ T♣] [3♦ 4♥ 2♦ 7♣]
Player 3: [6♥ J♥ 4♦ Q♦] Full House, Sixes full of Queens [6♣ 6♦ 6♥ Q♣ Q♦] [J♥ 4♦ 2♦ 7♣]
Player 4: [A♣ J♣ 5♣ K♠] Flush, Ace-high [A♣ Q♣ J♣ 7♣ 6♣] [5♣ K♠ 2♦ 6♦]
Player 5: [K♣ A♠ 8♣ 5♥] Flush, King-high [K♣ Q♣ 8♣ 7♣ 6♣] [A♠ 5♥ 2♦ 6♦]
Player 6: [Q♠ J♠ 8♦ 7♥] Two Pair, Queens over Sevens, kicker Six [Q♣ Q♠ 7♣ 7♥ 6♦] [J♠ 8♦ 2♦ 6♣]
Result:   Players 1, 3 push with Full House, Sixes full of Queens [6♣ 6♦ 6♠ Q♣ Q♥], [6♣ 6♦ 6♥ Q♣ Q♦]
------ Omaha 5 ------
Board:    [4♣ K♣ 6♦ 9♦ 5♠]
Player 1: [3♦ T♥ A♣ 7♦] Straight, Seven-high [7♦ 6♦ 5♠ 4♣ 3♦] [T♥ A♣ K♣ 9♦]
Player 2: [5♣ 6♠ 4♦ J♠] Two Pair, Sixes over Fives, kicker King [6♦ 6♠ 5♣ 5♠ K♣] [4♦ J♠ 4♣ 9♦]
Player 3: [9♠ 3♣ Q♠ 7♠] Straight, Seven-high [7♠ 6♦ 5♠ 4♣ 3♣] [9♠ Q♠ K♣ 9♦]
Player 4: [5♦ K♠ T♠ 8♠] Two Pair, Kings over Fives, kicker Nine [K♣ K♠ 5♦ 5♠ 9♦] [T♠ 8♠ 4♣ 6♦]
Player 5: [J♥ 7♥ J♣ 2♣] Pair, Jacks, kickers King, Nine, Six [J♣ J♥ K♣ 9♦ 6♦] [7♥ 2♣ 4♣ 5♠]
Player 6: [3♠ 7♣ 2♠ 2♥] Straight, Seven-high [7♣ 6♦ 5♠ 4♣ 3♠] [2♠ 2♥ K♣ 9♦]
Result:   Players 1, 3, 6 push with Straight, Seven-high [7♦ 6♦ 5♠ 4♣ 3♦], [7♠ 6♦ 5♠ 4♣ 3♣], [7♣ 6♦ 5♠ 4♣ 3♠]
Example (OmahaHiLo)
package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"

	"cardrank.io/cardrank"
)

func main() {
	for i, game := range []struct {
		seed    int64
		players int
	}{
		{119, 2},
		{321, 5},
		{408, 6},
		{455, 6},
		{1113, 6},
	} {
		// note: use a real random source
		rnd := rand.New(rand.NewSource(game.seed))
		pockets, board := cardrank.OmahaHiLo.Deal(rnd.Shuffle, game.players)
		hands := cardrank.OmahaHiLo.RankHands(pockets, board)
		fmt.Printf("------ OmahaHiLo %d ------\n", i+1)
		fmt.Printf("Board: %b\n", board)
		for j := 0; j < game.players; j++ {
			fmt.Printf("Player %d: %b\n", j+1, pockets[j])
			fmt.Printf("  Hi: %s %b %b\n", hands[j].Description(), hands[j].Best(), hands[j].Unused())
			if hands[j].LowValid() {
				fmt.Printf("  Lo: %s %b %b\n", hands[j].LowDescription(), hands[j].LowBest(), hands[j].LowUnused())
			} else {
				fmt.Printf("  Lo: None\n")
			}
		}
		h, hPivot := cardrank.Order(hands)
		l, lPivot := cardrank.LowOrder(hands)
		typ := "wins"
		if lPivot == 0 {
			typ = "scoops"
		}
		if hPivot == 1 {
			fmt.Printf("Result (Hi): Player %d %s with %s %b\n", h[0]+1, typ, hands[h[0]].Description(), hands[h[0]].Best())
		} else {
			var s, b []string
			for j := 0; j < hPivot; j++ {
				s = append(s, strconv.Itoa(h[j]+1))
				b = append(b, fmt.Sprintf("%b", hands[h[j]].Best()))
			}
			fmt.Printf("Result (Hi): Players %s push with %s %s\n", strings.Join(s, ", "), hands[h[0]].Description(), strings.Join(b, ", "))
		}
		if lPivot == 1 {
			fmt.Printf("Result (Lo): Player %d wins with %s %b\n", l[0]+1, hands[l[0]].LowDescription(), hands[l[0]].LowBest())
		} else if lPivot > 1 {
			var s, b []string
			for j := 0; j < lPivot; j++ {
				s = append(s, strconv.Itoa(l[j]+1))
				b = append(b, fmt.Sprintf("%b", hands[l[j]].LowBest()))
			}
			fmt.Printf("Result (Lo): Players %s push with %s %s\n", strings.Join(s, ", "), hands[l[0]].LowDescription(), strings.Join(b, ", "))
		} else {
			fmt.Printf("Result (Lo): no player made a low hand\n")
		}
	}
}
Output:

------ OmahaHiLo 1 ------
Board: [3♥ 5♥ 4♥ 7♥ K♣]
Player 1: [K♥ 7♣ J♣ 4♣]
  Hi: Two Pair, Kings over Sevens, kicker Five [K♣ K♥ 7♣ 7♥ 5♥] [J♣ 4♣ 3♥ 4♥]
  Lo: None
Player 2: [A♥ 5♠ Q♠ 2♠]
  Hi: Straight, Five-high [5♥ 4♥ 3♥ 2♠ A♥] [5♠ Q♠ 7♥ K♣]
  Lo: Five-low [5♥ 4♥ 3♥ 2♠ A♥] [5♠ Q♠ 7♥ K♣]
Result (Hi): Player 2 wins with Straight, Five-high [5♥ 4♥ 3♥ 2♠ A♥]
Result (Lo): Player 2 wins with Five-low [5♥ 4♥ 3♥ 2♠ A♥]
------ OmahaHiLo 2 ------
Board: [3♥ 7♣ 3♣ 9♠ 9♣]
Player 1: [3♠ 6♦ Q♦ K♦]
  Hi: Three of a Kind, Threes, kickers King, Nine [3♣ 3♥ 3♠ K♦ 9♠] [6♦ Q♦ 7♣ 9♣]
  Lo: None
Player 2: [J♦ 3♦ Q♣ K♠]
  Hi: Three of a Kind, Threes, kickers King, Nine [3♣ 3♦ 3♥ K♠ 9♠] [J♦ Q♣ 7♣ 9♣]
  Lo: None
Player 3: [T♦ 2♥ T♠ 8♥]
  Hi: Two Pair, Tens over Nines, kicker Seven [T♦ T♠ 9♣ 9♠ 7♣] [2♥ 8♥ 3♥ 3♣]
  Lo: None
Player 4: [8♣ 8♦ Q♥ Q♠]
  Hi: Two Pair, Queens over Nines, kicker Seven [Q♥ Q♠ 9♣ 9♠ 7♣] [8♣ 8♦ 3♥ 3♣]
  Lo: None
Player 5: [6♣ A♥ 4♥ 6♠]
  Hi: Two Pair, Nines over Sixes, kicker Seven [9♣ 9♠ 6♣ 6♠ 7♣] [A♥ 4♥ 3♥ 3♣]
  Lo: None
Result (Hi): Players 1, 2 push with Three of a Kind, Threes, kickers King, Nine [3♣ 3♥ 3♠ K♦ 9♠], [3♣ 3♦ 3♥ K♠ 9♠]
Result (Lo): no player made a low hand
------ OmahaHiLo 3 ------
Board: [J♣ T♥ 4♥ K♣ Q♣]
Player 1: [K♠ J♠ 3♠ 5♣]
  Hi: Two Pair, Kings over Jacks, kicker Queen [K♣ K♠ J♣ J♠ Q♣] [3♠ 5♣ T♥ 4♥]
  Lo: None
Player 2: [7♠ 4♠ Q♠ 3♣]
  Hi: Two Pair, Queens over Fours, kicker King [Q♣ Q♠ 4♥ 4♠ K♣] [7♠ 3♣ J♣ T♥]
  Lo: None
Player 3: [T♠ 5♥ 3♥ 8♦]
  Hi: Pair, Tens, kickers King, Queen, Eight [T♥ T♠ K♣ Q♣ 8♦] [5♥ 3♥ J♣ 4♥]
  Lo: None
Player 4: [4♣ 8♥ 2♣ T♦]
  Hi: Flush, King-high [K♣ Q♣ J♣ 4♣ 2♣] [8♥ T♦ T♥ 4♥]
  Lo: None
Player 5: [6♠ K♦ J♦ 2♠]
  Hi: Two Pair, Kings over Jacks, kicker Queen [K♣ K♦ J♣ J♦ Q♣] [6♠ 2♠ T♥ 4♥]
  Lo: None
Player 6: [Q♦ 2♦ A♣ T♣]
  Hi: Straight Flush, Ace-high, Royal [A♣ K♣ Q♣ J♣ T♣] [Q♦ 2♦ T♥ 4♥]
  Lo: None
Result (Hi): Player 6 scoops with Straight Flush, Ace-high, Royal [A♣ K♣ Q♣ J♣ T♣]
Result (Lo): no player made a low hand
------ OmahaHiLo 4 ------
Board: [2♦ 6♦ 6♣ Q♣ 7♣]
Player 1: [6♠ Q♥ 2♣ 9♠]
  Hi: Full House, Sixes full of Queens [6♣ 6♦ 6♠ Q♣ Q♥] [2♣ 9♠ 2♦ 7♣]
  Lo: None
Player 2: [3♦ T♣ K♥ 4♥]
  Hi: Pair, Sixes, kickers King, Queen, Ten [6♣ 6♦ K♥ Q♣ T♣] [3♦ 4♥ 2♦ 7♣]
  Lo: Seven-low [7♣ 6♦ 4♥ 3♦ 2♦] [T♣ K♥ 6♣ Q♣]
Player 3: [6♥ J♥ 4♦ Q♦]
  Hi: Full House, Sixes full of Queens [6♣ 6♦ 6♥ Q♣ Q♦] [J♥ 4♦ 2♦ 7♣]
  Lo: None
Player 4: [A♣ J♣ 5♣ K♠]
  Hi: Flush, Ace-high [A♣ Q♣ J♣ 7♣ 6♣] [5♣ K♠ 2♦ 6♦]
  Lo: Seven-low [7♣ 6♦ 5♣ 2♦ A♣] [J♣ K♠ 6♣ Q♣]
Player 5: [K♣ A♠ 8♣ 5♥]
  Hi: Flush, King-high [K♣ Q♣ 8♣ 7♣ 6♣] [A♠ 5♥ 2♦ 6♦]
  Lo: Seven-low [7♣ 6♦ 5♥ 2♦ A♠] [K♣ 8♣ 6♣ Q♣]
Player 6: [Q♠ J♠ 8♦ 7♥]
  Hi: Two Pair, Queens over Sevens, kicker Six [Q♣ Q♠ 7♣ 7♥ 6♦] [J♠ 8♦ 2♦ 6♣]
  Lo: None
Result (Hi): Players 1, 3 push with Full House, Sixes full of Queens [6♣ 6♦ 6♠ Q♣ Q♥], [6♣ 6♦ 6♥ Q♣ Q♦]
Result (Lo): Player 2 wins with Seven-low [7♣ 6♦ 4♥ 3♦ 2♦]
------ OmahaHiLo 5 ------
Board: [4♣ K♣ 6♦ 9♦ 5♠]
Player 1: [3♦ T♥ A♣ 7♦]
  Hi: Straight, Seven-high [7♦ 6♦ 5♠ 4♣ 3♦] [T♥ A♣ K♣ 9♦]
  Lo: Six-low [6♦ 5♠ 4♣ 3♦ A♣] [T♥ 7♦ K♣ 9♦]
Player 2: [5♣ 6♠ 4♦ J♠]
  Hi: Two Pair, Sixes over Fives, kicker King [6♦ 6♠ 5♣ 5♠ K♣] [4♦ J♠ 4♣ 9♦]
  Lo: None
Player 3: [9♠ 3♣ Q♠ 7♠]
  Hi: Straight, Seven-high [7♠ 6♦ 5♠ 4♣ 3♣] [9♠ Q♠ K♣ 9♦]
  Lo: Seven-low [7♠ 6♦ 5♠ 4♣ 3♣] [9♠ Q♠ K♣ 9♦]
Player 4: [5♦ K♠ T♠ 8♠]
  Hi: Two Pair, Kings over Fives, kicker Nine [K♣ K♠ 5♦ 5♠ 9♦] [T♠ 8♠ 4♣ 6♦]
  Lo: None
Player 5: [J♥ 7♥ J♣ 2♣]
  Hi: Pair, Jacks, kickers King, Nine, Six [J♣ J♥ K♣ 9♦ 6♦] [7♥ 2♣ 4♣ 5♠]
  Lo: Seven-low [7♥ 6♦ 5♠ 4♣ 2♣] [J♥ J♣ K♣ 9♦]
Player 6: [3♠ 7♣ 2♠ 2♥]
  Hi: Straight, Seven-high [7♣ 6♦ 5♠ 4♣ 3♠] [2♠ 2♥ K♣ 9♦]
  Lo: Six-low [6♦ 5♠ 4♣ 3♠ 2♠] [7♣ 2♥ K♣ 9♦]
Result (Hi): Players 1, 3, 6 push with Straight, Seven-high [7♦ 6♦ 5♠ 4♣ 3♦], [7♠ 6♦ 5♠ 4♣ 3♣], [7♣ 6♦ 5♠ 4♣ 3♠]
Result (Lo): Player 1 wins with Six-low [6♦ 5♠ 4♣ 3♦ A♣]
Example (OmahaMultiBoard)
package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"

	"cardrank.io/cardrank"
)

func main() {
	for i, game := range []struct {
		seed    int64
		players int
	}{
		{119, 2},
		{321, 5},
		{408, 6},
		{455, 6},
		{1113, 6},
	} {
		// note: use a real random source
		rnd := rand.New(rand.NewSource(game.seed))
		deck := cardrank.Omaha.Deck()
		deck.Shuffle(rnd.Shuffle)
		pockets := deck.Deal(game.players, 4)
		boards := deck.MultiBoard(2, 4, 2, 2)
		fmt.Printf("------ Omaha %d ------\n", i+1)
		for j := 0; j < len(boards); j++ {
			fmt.Printf("Board %d:    %b\n", j+1, boards[j])
			hands := cardrank.Omaha.RankHands(pockets, boards[j])
			for k := 0; k < game.players; k++ {
				fmt.Printf("  Player %d: %b %s %b %b\n", k+1, hands[k].Pocket(), hands[k].Description(), hands[k].Best(), hands[k].Unused())
			}
			h, pivot := cardrank.Order(hands)
			if pivot == 1 {
				fmt.Printf("Result %d:   Player %d wins with %s %b\n", j+1, h[0]+1, hands[h[0]].Description(), hands[h[0]].Best())
			} else {
				var s, b []string
				for j := 0; j < pivot; j++ {
					s = append(s, strconv.Itoa(h[j]+1))
					b = append(b, fmt.Sprintf("%b", hands[h[j]].Best()))
				}
				fmt.Printf("Result %d:   Players %s push with %s %s\n", j+1, strings.Join(s, ", "), hands[h[0]].Description(), strings.Join(b, ", "))
			}
		}
	}
}
Output:

------ Omaha 1 ------
Board 1:    [3♥ 5♥ 4♥ 9♦ 7♦]
  Player 1: [K♥ 7♣ J♣ 4♣] Two Pair, Sevens over Fours, kicker Nine [7♣ 7♦ 4♣ 4♥ 9♦] [K♥ J♣ 3♥ 5♥]
  Player 2: [A♥ 5♠ Q♠ 2♠] Straight, Five-high [5♥ 4♥ 3♥ 2♠ A♥] [5♠ Q♠ 9♦ 7♦]
Result 1:   Player 2 wins with Straight, Five-high [5♥ 4♥ 3♥ 2♠ A♥]
Board 2:    [7♥ K♦ K♣ 9♥ T♥]
  Player 1: [K♥ 7♣ J♣ 4♣] Full House, Kings full of Sevens [K♣ K♦ K♥ 7♣ 7♥] [J♣ 4♣ 9♥ T♥]
  Player 2: [A♥ 5♠ Q♠ 2♠] Pair, Kings, kickers Ace, Queen, Ten [K♣ K♦ A♥ Q♠ T♥] [5♠ 2♠ 7♥ 9♥]
Result 2:   Player 1 wins with Full House, Kings full of Sevens [K♣ K♦ K♥ 7♣ 7♥]
------ Omaha 2 ------
Board 1:    [3♥ 7♣ 3♣ 7♠ 2♦]
  Player 1: [3♠ 6♦ Q♦ K♦] Three of a Kind, Threes, kickers King, Seven [3♣ 3♥ 3♠ K♦ 7♣] [6♦ Q♦ 7♠ 2♦]
  Player 2: [J♦ 3♦ Q♣ K♠] Three of a Kind, Threes, kickers King, Seven [3♣ 3♦ 3♥ K♠ 7♣] [J♦ Q♣ 7♠ 2♦]
  Player 3: [T♦ 2♥ T♠ 8♥] Two Pair, Tens over Sevens, kicker Three [T♦ T♠ 7♣ 7♠ 3♥] [2♥ 8♥ 3♣ 2♦]
  Player 4: [8♣ 8♦ Q♥ Q♠] Two Pair, Queens over Sevens, kicker Three [Q♥ Q♠ 7♣ 7♠ 3♥] [8♣ 8♦ 3♣ 2♦]
  Player 5: [6♣ A♥ 4♥ 6♠] Two Pair, Sevens over Sixes, kicker Three [7♣ 7♠ 6♣ 6♠ 3♥] [A♥ 4♥ 3♣ 2♦]
Result 1:   Players 1, 2 push with Three of a Kind, Threes, kickers King, Seven [3♣ 3♥ 3♠ K♦ 7♣], [3♣ 3♦ 3♥ K♠ 7♣]
Board 2:    [9♠ T♣ 9♣ 7♥ J♣]
  Player 1: [3♠ 6♦ Q♦ K♦] Straight, King-high [K♦ Q♦ J♣ T♣ 9♠] [3♠ 6♦ 9♣ 7♥]
  Player 2: [J♦ 3♦ Q♣ K♠] Straight, King-high [K♠ Q♣ J♣ T♣ 9♠] [J♦ 3♦ 9♣ 7♥]
  Player 3: [T♦ 2♥ T♠ 8♥] Full House, Tens full of Nines [T♣ T♦ T♠ 9♣ 9♠] [2♥ 8♥ 7♥ J♣]
  Player 4: [8♣ 8♦ Q♥ Q♠] Straight, Queen-high [Q♥ J♣ T♣ 9♠ 8♣] [8♦ Q♠ 9♣ 7♥]
  Player 5: [6♣ A♥ 4♥ 6♠] Two Pair, Nines over Sixes, kicker Jack [9♣ 9♠ 6♣ 6♠ J♣] [A♥ 4♥ T♣ 7♥]
Result 2:   Player 3 wins with Full House, Tens full of Nines [T♣ T♦ T♠ 9♣ 9♠]
------ Omaha 3 ------
Board 1:    [J♣ T♥ 4♥ 9♦ 7♦]
  Player 1: [K♠ J♠ 3♠ 5♣] Pair, Jacks, kickers King, Ten, Nine [J♣ J♠ K♠ T♥ 9♦] [3♠ 5♣ 4♥ 7♦]
  Player 2: [7♠ 4♠ Q♠ 3♣] Two Pair, Sevens over Fours, kicker Jack [7♦ 7♠ 4♥ 4♠ J♣] [Q♠ 3♣ T♥ 9♦]
  Player 3: [T♠ 5♥ 3♥ 8♦] Straight, Jack-high [J♣ T♠ 9♦ 8♦ 7♦] [5♥ 3♥ T♥ 4♥]
  Player 4: [4♣ 8♥ 2♣ T♦] Straight, Jack-high [J♣ T♦ 9♦ 8♥ 7♦] [4♣ 2♣ T♥ 4♥]
  Player 5: [6♠ K♦ J♦ 2♠] Pair, Jacks, kickers King, Ten, Nine [J♣ J♦ K♦ T♥ 9♦] [6♠ 2♠ 4♥ 7♦]
  Player 6: [Q♦ 2♦ A♣ T♣] Pair, Tens, kickers Ace, Jack, Nine [T♣ T♥ A♣ J♣ 9♦] [Q♦ 2♦ 4♥ 7♦]
Result 1:   Players 3, 4 push with Straight, Jack-high [J♣ T♠ 9♦ 8♦ 7♦], [J♣ T♦ 9♦ 8♥ 7♦]
Board 2:    [K♣ 7♣ Q♣ 5♠ 2♥]
  Player 1: [K♠ J♠ 3♠ 5♣] Two Pair, Kings over Fives, kicker Queen [K♣ K♠ 5♣ 5♠ Q♣] [J♠ 3♠ 7♣ 2♥]
  Player 2: [7♠ 4♠ Q♠ 3♣] Two Pair, Queens over Sevens, kicker King [Q♣ Q♠ 7♣ 7♠ K♣] [4♠ 3♣ 5♠ 2♥]
  Player 3: [T♠ 5♥ 3♥ 8♦] Pair, Fives, kickers King, Queen, Ten [5♥ 5♠ K♣ Q♣ T♠] [3♥ 8♦ 7♣ 2♥]
  Player 4: [4♣ 8♥ 2♣ T♦] Flush, King-high [K♣ Q♣ 7♣ 4♣ 2♣] [8♥ T♦ 5♠ 2♥]
  Player 5: [6♠ K♦ J♦ 2♠] Two Pair, Kings over Twos, kicker Queen [K♣ K♦ 2♥ 2♠ Q♣] [6♠ J♦ 7♣ 5♠]
  Player 6: [Q♦ 2♦ A♣ T♣] Flush, Ace-high [A♣ K♣ Q♣ T♣ 7♣] [Q♦ 2♦ 5♠ 2♥]
Result 2:   Player 6 wins with Flush, Ace-high [A♣ K♣ Q♣ T♣ 7♣]
------ Omaha 4 ------
Board 1:    [2♦ 6♦ 6♣ K♦ 3♠]
  Player 1: [6♠ Q♥ 2♣ 9♠] Full House, Sixes full of Twos [6♣ 6♦ 6♠ 2♣ 2♦] [Q♥ 9♠ K♦ 3♠]
  Player 2: [3♦ T♣ K♥ 4♥] Two Pair, Kings over Sixes, kicker Ten [K♦ K♥ 6♣ 6♦ T♣] [3♦ 4♥ 2♦ 3♠]
  Player 3: [6♥ J♥ 4♦ Q♦] Flush, King-high [K♦ Q♦ 6♦ 4♦ 2♦] [6♥ J♥ 6♣ 3♠]
  Player 4: [A♣ J♣ 5♣ K♠] Two Pair, Kings over Sixes, kicker Ace [K♦ K♠ 6♣ 6♦ A♣] [J♣ 5♣ 2♦ 3♠]
  Player 5: [K♣ A♠ 8♣ 5♥] Two Pair, Kings over Sixes, kicker Ace [K♣ K♦ 6♣ 6♦ A♠] [8♣ 5♥ 2♦ 3♠]
  Player 6: [Q♠ J♠ 8♦ 7♥] Pair, Sixes, kickers King, Queen, Jack [6♣ 6♦ K♦ Q♠ J♠] [8♦ 7♥ 2♦ 3♠]
Result 1:   Player 1 wins with Full House, Sixes full of Twos [6♣ 6♦ 6♠ 2♣ 2♦]
Board 2:    [Q♣ 5♦ 7♣ 7♦ T♠]
  Player 1: [6♠ Q♥ 2♣ 9♠] Two Pair, Queens over Sevens, kicker Nine [Q♣ Q♥ 7♣ 7♦ 9♠] [6♠ 2♣ 5♦ T♠]
  Player 2: [3♦ T♣ K♥ 4♥] Two Pair, Tens over Sevens, kicker King [T♣ T♠ 7♣ 7♦ K♥] [3♦ 4♥ Q♣ 5♦]
  Player 3: [6♥ J♥ 4♦ Q♦] Two Pair, Queens over Sevens, kicker Jack [Q♣ Q♦ 7♣ 7♦ J♥] [6♥ 4♦ 5♦ T♠]
  Player 4: [A♣ J♣ 5♣ K♠] Two Pair, Sevens over Fives, kicker Ace [7♣ 7♦ 5♣ 5♦ A♣] [J♣ K♠ Q♣ T♠]
  Player 5: [K♣ A♠ 8♣ 5♥] Two Pair, Sevens over Fives, kicker Ace [7♣ 7♦ 5♦ 5♥ A♠] [K♣ 8♣ Q♣ T♠]
  Player 6: [Q♠ J♠ 8♦ 7♥] Full House, Sevens full of Queens [7♣ 7♦ 7♥ Q♣ Q♠] [J♠ 8♦ 5♦ T♠]
Result 2:   Player 6 wins with Full House, Sevens full of Queens [7♣ 7♦ 7♥ Q♣ Q♠]
------ Omaha 5 ------
Board 1:    [4♣ K♣ 6♦ 6♥ 2♦]
  Player 1: [3♦ T♥ A♣ 7♦] Pair, Sixes, kickers Ace, King, Ten [6♦ 6♥ A♣ K♣ T♥] [3♦ 7♦ 4♣ 2♦]
  Player 2: [5♣ 6♠ 4♦ J♠] Full House, Sixes full of Fours [6♦ 6♥ 6♠ 4♣ 4♦] [5♣ J♠ K♣ 2♦]
  Player 3: [9♠ 3♣ Q♠ 7♠] Pair, Sixes, kickers King, Queen, Nine [6♦ 6♥ K♣ Q♠ 9♠] [3♣ 7♠ 4♣ 2♦]
  Player 4: [5♦ K♠ T♠ 8♠] Two Pair, Kings over Sixes, kicker Ten [K♣ K♠ 6♦ 6♥ T♠] [5♦ 8♠ 4♣ 2♦]
  Player 5: [J♥ 7♥ J♣ 2♣] Two Pair, Jacks over Sixes, kicker King [J♣ J♥ 6♦ 6♥ K♣] [7♥ 2♣ 4♣ 2♦]
  Player 6: [3♠ 7♣ 2♠ 2♥] Full House, Twos full of Sixes [2♦ 2♥ 2♠ 6♦ 6♥] [3♠ 7♣ 4♣ K♣]
Result 1:   Player 2 wins with Full House, Sixes full of Fours [6♦ 6♥ 6♠ 4♣ 4♦]
Board 2:    [9♦ K♥ 5♠ K♦ 6♣]
  Player 1: [3♦ T♥ A♣ 7♦] Pair, Kings, kickers Ace, Ten, Nine [K♦ K♥ A♣ T♥ 9♦] [3♦ 7♦ 5♠ 6♣]
  Player 2: [5♣ 6♠ 4♦ J♠] Two Pair, Kings over Sixes, kicker Jack [K♦ K♥ 6♣ 6♠ J♠] [5♣ 4♦ 9♦ 5♠]
  Player 3: [9♠ 3♣ Q♠ 7♠] Two Pair, Kings over Nines, kicker Queen [K♦ K♥ 9♦ 9♠ Q♠] [3♣ 7♠ 5♠ 6♣]
  Player 4: [5♦ K♠ T♠ 8♠] Full House, Kings full of Fives [K♦ K♥ K♠ 5♦ 5♠] [T♠ 8♠ 9♦ 6♣]
  Player 5: [J♥ 7♥ J♣ 2♣] Two Pair, Kings over Jacks, kicker Nine [K♦ K♥ J♣ J♥ 9♦] [7♥ 2♣ 5♠ 6♣]
  Player 6: [3♠ 7♣ 2♠ 2♥] Two Pair, Kings over Twos, kicker Nine [K♦ K♥ 2♥ 2♠ 9♦] [3♠ 7♣ 5♠ 6♣]
Result 2:   Player 4 wins with Full House, Kings full of Fives [K♦ K♥ K♠ 5♦ 5♠]
Example (Razz)
package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"

	"cardrank.io/cardrank"
)

func main() {
	for i, game := range []struct {
		seed    int64
		players int
	}{
		{119, 2},
		{321, 5},
		{408, 6},
		{455, 6},
		{1113, 6},
	} {
		// note: use a real random source
		rnd := rand.New(rand.NewSource(game.seed))
		pockets, _ := cardrank.Razz.Deal(rnd.Shuffle, game.players)
		hands := cardrank.Razz.RankHands(pockets, nil)
		fmt.Printf("------ Razz %d ------\n", i+1)
		for j := 0; j < game.players; j++ {
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, hands[j].Pocket(), hands[j].Description(), hands[j].Best(), hands[j].Unused())
		}
		h, pivot := cardrank.Order(hands)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s %b\n", h[0]+1, hands[h[0]].Description(), hands[h[0]].Best())
		} else {
			var s, b []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(h[j]+1))
				b = append(b, fmt.Sprintf("%b", hands[h[j]].Best()))
			}
			fmt.Printf("Result:   Players %s push with %s %s\n", strings.Join(s, ", "), hands[h[0]].Description(), strings.Join(b, ", "))
		}
	}
}
Output:

------ Razz 1 ------
Player 1: [K♥ 7♣ J♣ 4♣ A♥ 5♠ Q♠] Jack-low [J♣ 7♣ 5♠ 4♣ A♥] [K♥ Q♠]
Player 2: [2♠ 6♣ 3♥ 5♥ 4♥ Q♦ 7♥] Six-low [6♣ 5♥ 4♥ 3♥ 2♠] [Q♦ 7♥]
Result:   Player 2 wins with Six-low [6♣ 5♥ 4♥ 3♥ 2♠]
------ Razz 2 ------
Player 1: [3♠ 6♦ Q♦ K♦ J♦ 3♦ Q♣] King-low [K♦ Q♦ J♦ 6♦ 3♠] [3♦ Q♣]
Player 2: [K♠ T♦ 2♥ T♠ 8♥ 8♣ 8♦] Pair, Eights, kickers King, Ten, Two [8♥ 8♣ K♠ T♦ 2♥] [T♠ 8♦]
Player 3: [Q♥ Q♠ 6♣ A♥ 4♥ 6♠ T♥] Queen-low [Q♥ T♥ 6♣ 4♥ A♥] [Q♠ 6♠]
Player 4: [3♥ 7♣ 3♣ 5♦ 9♠ T♣ 9♣] Ten-low [T♣ 9♠ 7♣ 5♦ 3♥] [3♣ 9♣]
Player 5: [J♠ 7♠ K♥ 7♥ 2♣ 2♦ A♦] King-low [K♥ J♠ 7♠ 2♣ A♦] [7♥ 2♦]
Result:   Player 4 wins with Ten-low [T♣ 9♠ 7♣ 5♦ 3♥]
------ Razz 3 ------
Player 1: [K♠ J♠ 3♠ 5♣ 7♠ 4♠ Q♠] Jack-low [J♠ 7♠ 5♣ 4♠ 3♠] [K♠ Q♠]
Player 2: [3♣ T♠ 5♥ 3♥ 8♦ 4♣ 8♥] Ten-low [T♠ 8♦ 5♥ 4♣ 3♣] [3♥ 8♥]
Player 3: [2♣ T♦ 6♠ K♦ J♦ 2♠ Q♦] Queen-low [Q♦ J♦ T♦ 6♠ 2♣] [K♦ 2♠]
Player 4: [2♦ A♣ T♣ 7♥ J♣ T♥ 4♥] Ten-low [T♣ 7♥ 4♥ 2♦ A♣] [J♣ T♥]
Player 5: [8♠ K♣ 7♣ Q♣ K♥ 9♦ 6♦] Queen-low [Q♣ 9♦ 8♠ 7♣ 6♦] [K♣ K♥]
Player 6: [5♠ J♥ 7♦ 3♦ 2♥ A♦ 9♣] Seven-low [7♦ 5♠ 3♦ 2♥ A♦] [J♥ 9♣]
Result:   Player 6 wins with Seven-low [7♦ 5♠ 3♦ 2♥ A♦]
------ Razz 4 ------
Player 1: [6♠ Q♥ 2♣ 9♠ 3♦ T♣ K♥] Ten-low [T♣ 9♠ 6♠ 3♦ 2♣] [Q♥ K♥]
Player 2: [4♥ 6♥ J♥ 4♦ Q♦ A♣ J♣] Queen-low [Q♦ J♥ 6♥ 4♥ A♣] [4♦ J♣]
Player 3: [5♣ K♠ K♣ A♠ 8♣ 5♥ Q♠] King-low [K♠ Q♠ 8♣ 5♣ A♠] [K♣ 5♥]
Player 4: [J♠ 8♦ 7♥ 2♠ 2♦ 6♦ 6♣] Jack-low [J♠ 8♦ 7♥ 6♦ 2♠] [2♦ 6♣]
Player 5: [8♥ Q♣ 5♦ 7♣ 9♥ K♦ 9♣] Queen-low [Q♣ 9♥ 8♥ 7♣ 5♦] [K♦ 9♣]
Player 6: [7♦ A♥ 3♠ 3♣ T♠ T♥ 2♥] Ten-low [T♠ 7♦ 3♠ 2♥ A♥] [3♣ T♥]
Result:   Player 6 wins with Ten-low [T♠ 7♦ 3♠ 2♥ A♥]
------ Razz 5 ------
Player 1: [3♦ T♥ A♣ 7♦ 5♣ 6♠ 4♦] Six-low [6♠ 5♣ 4♦ 3♦ A♣] [T♥ 7♦]
Player 2: [J♠ 9♠ 3♣ Q♠ 7♠ 5♦ K♠] Jack-low [J♠ 9♠ 7♠ 5♦ 3♣] [Q♠ K♠]
Player 3: [T♠ 8♠ J♥ 7♥ J♣ 2♣ 3♠] Ten-low [T♠ 8♠ 7♥ 3♠ 2♣] [J♥ J♣]
Player 4: [7♣ 2♠ 2♥ 4♥ 4♣ K♣ 6♦] King-low [K♣ 7♣ 6♦ 4♥ 2♠] [2♥ 4♣]
Player 5: [A♠ 9♦ K♥ 5♠ 8♦ 6♥ 8♥] Nine-low [9♦ 8♦ 6♥ 5♠ A♠] [K♥ 8♥]
Player 6: [K♦ 8♣ 2♦ A♥ 6♣ 4♠ T♦] Eight-low [8♣ 6♣ 4♠ 2♦ A♥] [K♦ T♦]
Result:   Player 1 wins with Six-low [6♠ 5♣ 4♦ 3♦ A♣]
Example (Royal)
package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"

	"cardrank.io/cardrank"
)

func main() {
	for i, game := range []struct {
		seed    int64
		players int
	}{
		{119, 2},
		{155, 3},
		{384, 4},
		{880, 5},
		{3453, 2},
		{5662, 3},
		{65481, 4},
		{27947, 5},
	} {
		// note: use a real random source
		rnd := rand.New(rand.NewSource(game.seed))
		pockets, board := cardrank.Royal.Deal(rnd.Shuffle, game.players)
		hands := cardrank.Royal.RankHands(pockets, board)
		fmt.Printf("------ Royal %d ------\n", i+1)
		fmt.Printf("Board:    %b\n", board)
		for j := 0; j < game.players; j++ {
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, hands[j].Pocket(), hands[j].Description(), hands[j].Best(), hands[j].Unused())
		}
		h, pivot := cardrank.Order(hands)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s %b\n", h[0]+1, hands[h[0]].Description(), hands[h[0]].Best())
		} else {
			var s, b []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(h[j]+1))
				b = append(b, fmt.Sprintf("%b", hands[h[j]].Best()))
			}
			fmt.Printf("Result:   Players %s push with %s %s\n", strings.Join(s, ", "), hands[h[0]].Description(), strings.Join(b, ", "))
		}
	}
}
Output:

------ Royal 1 ------
Board:    [K♦ A♦ T♥ T♣ J♠]
Player 1: [A♠ A♥] Full House, Aces full of Tens [A♦ A♥ A♠ T♣ T♥] [K♦ J♠]
Player 2: [T♠ K♠] Full House, Tens full of Kings [T♣ T♥ T♠ K♦ K♠] [A♦ J♠]
Result:   Player 1 wins with Full House, Aces full of Tens [A♦ A♥ A♠ T♣ T♥]
------ Royal 2 ------
Board:    [A♣ K♠ J♦ Q♣ J♣]
Player 1: [A♠ T♠] Straight, Ace-high [A♣ K♠ Q♣ J♣ T♠] [A♠ J♦]
Player 2: [K♣ Q♠] Two Pair, Kings over Queens, kicker Ace [K♣ K♠ Q♣ Q♠ A♣] [J♣ J♦]
Player 3: [J♥ T♥] Straight, Ace-high [A♣ K♠ Q♣ J♣ T♥] [J♦ J♥]
Result:   Players 1, 3 push with Straight, Ace-high [A♣ K♠ Q♣ J♣ T♠], [A♣ K♠ Q♣ J♣ T♥]
------ Royal 3 ------
Board:    [K♠ T♦ T♣ Q♦ A♥]
Player 1: [T♠ J♣] Straight, Ace-high [A♥ K♠ Q♦ J♣ T♣] [T♦ T♠]
Player 2: [A♦ K♥] Two Pair, Aces over Kings, kicker Queen [A♦ A♥ K♥ K♠ Q♦] [T♣ T♦]
Player 3: [T♥ Q♣] Full House, Tens full of Queens [T♣ T♦ T♥ Q♣ Q♦] [A♥ K♠]
Player 4: [K♦ K♣] Full House, Kings full of Tens [K♣ K♦ K♠ T♣ T♦] [A♥ Q♦]
Result:   Player 4 wins with Full House, Kings full of Tens [K♣ K♦ K♠ T♣ T♦]
------ Royal 4 ------
Board:    [J♥ A♠ T♥ T♣ K♠]
Player 1: [Q♦ K♥] Straight, Ace-high [A♠ K♥ Q♦ J♥ T♣] [K♠ T♥]
Player 2: [A♣ A♦] Full House, Aces full of Tens [A♣ A♦ A♠ T♣ T♥] [K♠ J♥]
Player 3: [K♦ T♠] Full House, Tens full of Kings [T♣ T♥ T♠ K♦ K♠] [A♠ J♥]
Player 4: [T♦ Q♠] Straight, Ace-high [A♠ K♠ Q♠ J♥ T♣] [T♦ T♥]
Player 5: [J♠ J♦] Full House, Jacks full of Tens [J♦ J♥ J♠ T♣ T♥] [A♠ K♠]
Result:   Player 2 wins with Full House, Aces full of Tens [A♣ A♦ A♠ T♣ T♥]
------ Royal 5 ------
Board:    [J♣ K♥ K♠ J♥ Q♣]
Player 1: [A♥ J♦] Full House, Jacks full of Kings [J♣ J♦ J♥ K♥ K♠] [A♥ Q♣]
Player 2: [T♦ Q♠] Two Pair, Kings over Queens, kicker Jack [K♥ K♠ Q♣ Q♠ J♣] [J♥ T♦]
Result:   Player 1 wins with Full House, Jacks full of Kings [J♣ J♦ J♥ K♥ K♠]
------ Royal 6 ------
Board:    [K♥ A♠ K♦ K♠ A♣]
Player 1: [J♥ Q♦] Full House, Kings full of Aces [K♦ K♥ K♠ A♣ A♠] [Q♦ J♥]
Player 2: [Q♠ J♠] Full House, Kings full of Aces [K♦ K♥ K♠ A♣ A♠] [Q♠ J♠]
Player 3: [A♥ T♣] Full House, Aces full of Kings [A♣ A♥ A♠ K♦ K♥] [K♠ T♣]
Result:   Player 3 wins with Full House, Aces full of Kings [A♣ A♥ A♠ K♦ K♥]
------ Royal 7 ------
Board:    [J♥ T♦ Q♠ K♣ K♥]
Player 1: [K♦ T♥] Full House, Kings full of Tens [K♣ K♦ K♥ T♦ T♥] [Q♠ J♥]
Player 2: [A♠ Q♣] Straight, Ace-high [A♠ K♣ Q♣ J♥ T♦] [K♥ Q♠]
Player 3: [J♣ T♠] Two Pair, Kings over Jacks, kicker Queen [K♣ K♥ J♣ J♥ Q♠] [T♦ T♠]
Player 4: [A♥ A♦] Straight, Ace-high [A♦ K♣ Q♠ J♥ T♦] [A♥ K♥]
Result:   Player 1 wins with Full House, Kings full of Tens [K♣ K♦ K♥ T♦ T♥]
------ Royal 8 ------
Board:    [A♠ K♦ Q♦ A♦ A♣]
Player 1: [Q♠ T♦] Full House, Aces full of Queens [A♣ A♦ A♠ Q♦ Q♠] [K♦ T♦]
Player 2: [J♥ Q♥] Full House, Aces full of Queens [A♣ A♦ A♠ Q♦ Q♥] [K♦ J♥]
Player 3: [K♣ J♠] Full House, Aces full of Kings [A♣ A♦ A♠ K♣ K♦] [Q♦ J♠]
Player 4: [A♥ K♠] Four of a Kind, Aces, kicker King [A♣ A♦ A♥ A♠ K♦] [K♠ Q♦]
Player 5: [J♦ T♥] Straight, Ace-high [A♣ K♦ Q♦ J♦ T♥] [A♦ A♠]
Result:   Player 4 wins with Four of a Kind, Aces, kicker King [A♣ A♦ A♥ A♠ K♦]
Example (Short)
package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"

	"cardrank.io/cardrank"
)

func main() {
	for i, game := range []struct {
		seed    int64
		players int
	}{
		{119, 2},
		{155, 4},
		{384, 8},
		{880, 4},
		{3453, 3},
		{5662, 3},
		{65481, 2},
		{27947, 4},
	} {
		// note: use a real random source
		rnd := rand.New(rand.NewSource(game.seed))
		pockets, board := cardrank.Short.Deal(rnd.Shuffle, game.players)
		hands := cardrank.Short.RankHands(pockets, board)
		fmt.Printf("------ Short %d ------\n", i+1)
		fmt.Printf("Board:    %b\n", board)
		for j := 0; j < game.players; j++ {
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, hands[j].Pocket(), hands[j].Description(), hands[j].Best(), hands[j].Unused())
		}
		h, pivot := cardrank.Order(hands)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s %b\n", h[0]+1, hands[h[0]].Description(), hands[h[0]].Best())
		} else {
			var s, b []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(h[j]+1))
				b = append(b, fmt.Sprintf("%b", hands[h[j]].Best()))
			}
			fmt.Printf("Result:   Players %s push with %s %s\n", strings.Join(s, ", "), hands[h[0]].Description(), strings.Join(b, ", "))
		}
	}
}
Output:

------ Short 1 ------
Board:    [9♥ A♦ A♥ 8♣ A♣]
Player 1: [8♥ 7♥] Full House, Aces full of Eights [A♣ A♦ A♥ 8♣ 8♥] [9♥ 7♥]
Player 2: [A♠ J♦] Four of a Kind, Aces, kicker Jack [A♣ A♦ A♥ A♠ J♦] [9♥ 8♣]
Result:   Player 2 wins with Four of a Kind, Aces, kicker Jack [A♣ A♦ A♥ A♠ J♦]
------ Short 2 ------
Board:    [9♣ 6♦ A♠ J♠ 6♠]
Player 1: [T♥ 6♣] Three of a Kind, Sixes, kickers Ace, Jack [6♣ 6♦ 6♠ A♠ J♠] [T♥ 9♣]
Player 2: [6♥ 9♥] Full House, Sixes full of Nines [6♦ 6♥ 6♠ 9♣ 9♥] [A♠ J♠]
Player 3: [A♣ 7♣] Two Pair, Aces over Sixes, kicker Jack [A♣ A♠ 6♦ 6♠ J♠] [9♣ 7♣]
Player 4: [T♠ K♠] Flush, Ace-high [A♠ K♠ J♠ T♠ 6♠] [9♣ 6♦]
Result:   Player 4 wins with Flush, Ace-high [A♠ K♠ J♠ T♠ 6♠]
------ Short 3 ------
Board:    [T♥ J♣ 7♥ 9♥ K♣]
Player 1: [8♥ T♠] Straight, Jack-high [J♣ T♥ 9♥ 8♥ 7♥] [K♣ T♠]
Player 2: [J♠ 6♣] Pair, Jacks, kickers King, Ten, Nine [J♣ J♠ K♣ T♥ 9♥] [7♥ 6♣]
Player 3: [7♦ 8♠] Straight, Jack-high [J♣ T♥ 9♥ 8♠ 7♦] [K♣ 7♥]
Player 4: [9♣ A♥] Pair, Nines, kickers Ace, King, Jack [9♣ 9♥ A♥ K♣ J♣] [T♥ 7♥]
Player 5: [T♣ Q♠] Straight, King-high [K♣ Q♠ J♣ T♣ 9♥] [T♥ 7♥]
Player 6: [7♣ Q♦] Straight, King-high [K♣ Q♦ J♣ T♥ 9♥] [7♣ 7♥]
Player 7: [6♠ 8♦] Straight, Jack-high [J♣ T♥ 9♥ 8♦ 7♥] [K♣ 6♠]
Player 8: [K♥ K♦] Three of a Kind, Kings, kickers Jack, Ten [K♣ K♦ K♥ J♣ T♥] [9♥ 7♥]
Result:   Players 5, 6 push with Straight, King-high [K♣ Q♠ J♣ T♣ 9♥], [K♣ Q♦ J♣ T♥ 9♥]
------ Short 4 ------
Board:    [T♦ 9♣ 9♦ Q♦ 8♦]
Player 1: [J♠ T♥] Straight, Queen-high [Q♦ J♠ T♦ 9♣ 8♦] [T♥ 9♦]
Player 2: [6♣ A♣] Pair, Nines, kickers Ace, Queen, Ten [9♣ 9♦ A♣ Q♦ T♦] [8♦ 6♣]
Player 3: [9♥ 8♠] Full House, Nines full of Eights [9♣ 9♦ 9♥ 8♦ 8♠] [Q♦ T♦]
Player 4: [J♦ A♦] Straight Flush, Queen-high [Q♦ J♦ T♦ 9♦ 8♦] [9♣ A♦]
Result:   Player 4 wins with Straight Flush, Queen-high [Q♦ J♦ T♦ 9♦ 8♦]
------ Short 5 ------
Board:    [6♠ A♣ 7♦ A♠ 6♦]
Player 1: [9♣ T♠] Two Pair, Aces over Sixes, kicker Ten [A♣ A♠ 6♦ 6♠ T♠] [9♣ 7♦]
Player 2: [J♥ T♦] Two Pair, Aces over Sixes, kicker Jack [A♣ A♠ 6♦ 6♠ J♥] [T♦ 7♦]
Player 3: [K♠ A♥] Full House, Aces full of Sixes [A♣ A♥ A♠ 6♦ 6♠] [K♠ 7♦]
Result:   Player 3 wins with Full House, Aces full of Sixes [A♣ A♥ A♠ 6♦ 6♠]
------ Short 6 ------
Board:    [A♣ 6♣ 9♣ T♦ 8♣]
Player 1: [6♥ 7♣] Straight Flush, Nine-high, Iron Maiden [9♣ 8♣ 7♣ 6♣ A♣] [T♦ 6♥]
Player 2: [6♠ 9♠] Two Pair, Nines over Sixes, kicker Ace [9♣ 9♠ 6♣ 6♠ A♣] [T♦ 8♣]
Player 3: [J♥ Q♠] Straight, Queen-high [Q♠ J♥ T♦ 9♣ 8♣] [A♣ 6♣]
Result:   Player 1 wins with Straight Flush, Nine-high, Iron Maiden [9♣ 8♣ 7♣ 6♣ A♣]
------ Short 7 ------
Board:    [K♥ K♦ K♠ K♣ J♣]
Player 1: [7♦ T♦] Four of a Kind, Kings, kicker Jack [K♣ K♦ K♥ K♠ J♣] [T♦ 7♦]
Player 2: [8♦ 6♥] Four of a Kind, Kings, kicker Jack [K♣ K♦ K♥ K♠ J♣] [8♦ 6♥]
Result:   Players 1, 2 push with Four of a Kind, Kings, kicker Jack [K♣ K♦ K♥ K♠ J♣], [K♣ K♦ K♥ K♠ J♣]
------ Short 8 ------
Board:    [8♦ 8♥ 8♠ Q♠ T♦]
Player 1: [J♦ T♣] Full House, Eights full of Tens [8♦ 8♥ 8♠ T♣ T♦] [Q♠ J♦]
Player 2: [K♠ T♠] Full House, Eights full of Tens [8♦ 8♥ 8♠ T♦ T♠] [K♠ Q♠]
Player 3: [9♣ J♣] Straight, Queen-high [Q♠ J♣ T♦ 9♣ 8♦] [8♥ 8♠]
Player 4: [T♥ 7♥] Full House, Eights full of Tens [8♦ 8♥ 8♠ T♦ T♥] [Q♠ 7♥]
Result:   Players 1, 2, 4 push with Full House, Eights full of Tens [8♦ 8♥ 8♠ T♣ T♦], [8♦ 8♥ 8♠ T♦ T♠], [8♦ 8♥ 8♠ T♦ T♥]
Example (Stud)
package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"

	"cardrank.io/cardrank"
)

func main() {
	for i, game := range []struct {
		seed    int64
		players int
	}{
		{119, 2},
		{321, 5},
		{408, 6},
		{455, 6},
		{1113, 6},
	} {
		// note: use a real random source
		rnd := rand.New(rand.NewSource(game.seed))
		pockets, _ := cardrank.Stud.Deal(rnd.Shuffle, game.players)
		hands := cardrank.Stud.RankHands(pockets, nil)
		fmt.Printf("------ Stud %d ------\n", i+1)
		for j := 0; j < game.players; j++ {
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, hands[j].Pocket(), hands[j].Description(), hands[j].Best(), hands[j].Unused())
		}
		h, pivot := cardrank.Order(hands)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s %b\n", h[0]+1, hands[h[0]].Description(), hands[h[0]].Best())
		} else {
			var s, b []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(h[j]+1))
				b = append(b, fmt.Sprintf("%b", hands[h[j]].Best()))
			}
			fmt.Printf("Result:   Players %s push with %s %s\n", strings.Join(s, ", "), hands[h[0]].Description(), strings.Join(b, ", "))
		}
	}
}
Output:

------ Stud 1 ------
Player 1: [K♥ 7♣ J♣ 4♣ A♥ 5♠ Q♠] Nothing, Ace-high, kickers King, Queen, Jack, Seven [A♥ K♥ Q♠ J♣ 7♣] [5♠ 4♣]
Player 2: [2♠ 6♣ 3♥ 5♥ 4♥ Q♦ 7♥] Straight, Seven-high [7♥ 6♣ 5♥ 4♥ 3♥] [Q♦ 2♠]
Result:   Player 2 wins with Straight, Seven-high [7♥ 6♣ 5♥ 4♥ 3♥]
------ Stud 2 ------
Player 1: [3♠ 6♦ Q♦ K♦ J♦ 3♦ Q♣] Flush, King-high [K♦ Q♦ J♦ 6♦ 3♦] [Q♣ 3♠]
Player 2: [K♠ T♦ 2♥ T♠ 8♥ 8♣ 8♦] Full House, Eights full of Tens [8♣ 8♦ 8♥ T♦ T♠] [K♠ 2♥]
Player 3: [Q♥ Q♠ 6♣ A♥ 4♥ 6♠ T♥] Two Pair, Queens over Sixes, kicker Ace [Q♥ Q♠ 6♣ 6♠ A♥] [T♥ 4♥]
Player 4: [3♥ 7♣ 3♣ 5♦ 9♠ T♣ 9♣] Two Pair, Nines over Threes, kicker Ten [9♣ 9♠ 3♣ 3♥ T♣] [7♣ 5♦]
Player 5: [J♠ 7♠ K♥ 7♥ 2♣ 2♦ A♦] Two Pair, Sevens over Twos, kicker Ace [7♥ 7♠ 2♣ 2♦ A♦] [K♥ J♠]
Result:   Player 2 wins with Full House, Eights full of Tens [8♣ 8♦ 8♥ T♦ T♠]
------ Stud 3 ------
Player 1: [K♠ J♠ 3♠ 5♣ 7♠ 4♠ Q♠] Flush, King-high [K♠ Q♠ J♠ 7♠ 4♠] [3♠ 5♣]
Player 2: [3♣ T♠ 5♥ 3♥ 8♦ 4♣ 8♥] Two Pair, Eights over Threes, kicker Ten [8♦ 8♥ 3♣ 3♥ T♠] [5♥ 4♣]
Player 3: [2♣ T♦ 6♠ K♦ J♦ 2♠ Q♦] Pair, Twos, kickers King, Queen, Jack [2♣ 2♠ K♦ Q♦ J♦] [T♦ 6♠]
Player 4: [2♦ A♣ T♣ 7♥ J♣ T♥ 4♥] Pair, Tens, kickers Ace, Jack, Seven [T♣ T♥ A♣ J♣ 7♥] [4♥ 2♦]
Player 5: [8♠ K♣ 7♣ Q♣ K♥ 9♦ 6♦] Pair, Kings, kickers Queen, Nine, Eight [K♣ K♥ Q♣ 9♦ 8♠] [7♣ 6♦]
Player 6: [5♠ J♥ 7♦ 3♦ 2♥ A♦ 9♣] Nothing, Ace-high, kickers Jack, Nine, Seven, Five [A♦ J♥ 9♣ 7♦ 5♠] [3♦ 2♥]
Result:   Player 1 wins with Flush, King-high [K♠ Q♠ J♠ 7♠ 4♠]
------ Stud 4 ------
Player 1: [6♠ Q♥ 2♣ 9♠ 3♦ T♣ K♥] Nothing, King-high, kickers Queen, Ten, Nine, Six [K♥ Q♥ T♣ 9♠ 6♠] [3♦ 2♣]
Player 2: [4♥ 6♥ J♥ 4♦ Q♦ A♣ J♣] Two Pair, Jacks over Fours, kicker Ace [J♣ J♥ 4♦ 4♥ A♣] [Q♦ 6♥]
Player 3: [5♣ K♠ K♣ A♠ 8♣ 5♥ Q♠] Two Pair, Kings over Fives, kicker Ace [K♣ K♠ 5♣ 5♥ A♠] [Q♠ 8♣]
Player 4: [J♠ 8♦ 7♥ 2♠ 2♦ 6♦ 6♣] Two Pair, Sixes over Twos, kicker Jack [6♣ 6♦ 2♦ 2♠ J♠] [8♦ 7♥]
Player 5: [8♥ Q♣ 5♦ 7♣ 9♥ K♦ 9♣] Pair, Nines, kickers King, Queen, Eight [9♣ 9♥ K♦ Q♣ 8♥] [7♣ 5♦]
Player 6: [7♦ A♥ 3♠ 3♣ T♠ T♥ 2♥] Two Pair, Tens over Threes, kicker Ace [T♥ T♠ 3♣ 3♠ A♥] [7♦ 2♥]
Result:   Player 3 wins with Two Pair, Kings over Fives, kicker Ace [K♣ K♠ 5♣ 5♥ A♠]
------ Stud 5 ------
Player 1: [3♦ T♥ A♣ 7♦ 5♣ 6♠ 4♦] Straight, Seven-high [7♦ 6♠ 5♣ 4♦ 3♦] [A♣ T♥]
Player 2: [J♠ 9♠ 3♣ Q♠ 7♠ 5♦ K♠] Flush, King-high [K♠ Q♠ J♠ 9♠ 7♠] [5♦ 3♣]
Player 3: [T♠ 8♠ J♥ 7♥ J♣ 2♣ 3♠] Pair, Jacks, kickers Ten, Eight, Seven [J♣ J♥ T♠ 8♠ 7♥] [3♠ 2♣]
Player 4: [7♣ 2♠ 2♥ 4♥ 4♣ K♣ 6♦] Two Pair, Fours over Twos, kicker King [4♣ 4♥ 2♥ 2♠ K♣] [7♣ 6♦]
Player 5: [A♠ 9♦ K♥ 5♠ 8♦ 6♥ 8♥] Pair, Eights, kickers Ace, King, Nine [8♦ 8♥ A♠ K♥ 9♦] [6♥ 5♠]
Player 6: [K♦ 8♣ 2♦ A♥ 6♣ 4♠ T♦] Nothing, Ace-high, kickers King, Ten, Eight, Six [A♥ K♦ T♦ 8♣ 6♣] [4♠ 2♦]
Result:   Player 2 wins with Flush, King-high [K♠ Q♠ J♠ 9♠ 7♠]
Example (StudHiLo)
package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"

	"cardrank.io/cardrank"
)

func main() {
	for i, game := range []struct {
		seed    int64
		players int
	}{
		{119, 2},
		{321, 5},
		{408, 6},
		{455, 6},
		{1113, 6},
	} {
		// note: use a real random source
		rnd := rand.New(rand.NewSource(game.seed))
		pockets, _ := cardrank.StudHiLo.Deal(rnd.Shuffle, game.players)
		hands := cardrank.StudHiLo.RankHands(pockets, nil)
		fmt.Printf("------ StudHiLo %d ------\n", i+1)
		for j := 0; j < game.players; j++ {
			fmt.Printf("Player %d: %b\n", j+1, pockets[j])
			fmt.Printf("  Hi: %s %b %b\n", hands[j].Description(), hands[j].Best(), hands[j].Unused())
			if hands[j].LowValid() {
				fmt.Printf("  Lo: %s %b %b\n", hands[j].LowDescription(), hands[j].LowBest(), hands[j].LowUnused())
			} else {
				fmt.Printf("  Lo: None\n")
			}
		}
		h, hPivot := cardrank.Order(hands)
		l, lPivot := cardrank.LowOrder(hands)
		typ := "wins"
		if lPivot == 0 {
			typ = "scoops"
		}
		if hPivot == 1 {
			fmt.Printf("Result (Hi): Player %d %s with %s %b\n", h[0]+1, typ, hands[h[0]].Description(), hands[h[0]].Best())
		} else {
			var s, b []string
			for j := 0; j < hPivot; j++ {
				s = append(s, strconv.Itoa(h[j]+1))
				b = append(b, fmt.Sprintf("%b", hands[h[j]].Best()))
			}
			fmt.Printf("Result (Hi): Players %s push with %s %s\n", strings.Join(s, ", "), hands[h[0]].Description(), strings.Join(b, ", "))
		}
		if lPivot == 1 {
			fmt.Printf("Result (Lo): Player %d wins with %s %b\n", l[0]+1, hands[l[0]].LowDescription(), hands[l[0]].LowBest())
		} else if lPivot > 1 {
			var s, b []string
			for j := 0; j < lPivot; j++ {
				s = append(s, strconv.Itoa(l[j]+1))
				b = append(b, fmt.Sprintf("%b", hands[l[j]].LowBest()))
			}
			fmt.Printf("Result (Lo): Players %s push with %s %s\n", strings.Join(s, ", "), hands[l[0]].LowDescription(), strings.Join(b, ", "))
		} else {
			fmt.Printf("Result (Lo): no player made a low hand\n")
		}
	}
}
Output:

------ StudHiLo 1 ------
Player 1: [K♥ 7♣ J♣ 4♣ A♥ 5♠ Q♠]
  Hi: Nothing, Ace-high, kickers King, Queen, Jack, Seven [A♥ K♥ Q♠ J♣ 7♣] [5♠ 4♣]
  Lo: None
Player 2: [2♠ 6♣ 3♥ 5♥ 4♥ Q♦ 7♥]
  Hi: Straight, Seven-high [7♥ 6♣ 5♥ 4♥ 3♥] [Q♦ 2♠]
  Lo: Six-low [6♣ 5♥ 4♥ 3♥ 2♠] [Q♦ 7♥]
Result (Hi): Player 2 wins with Straight, Seven-high [7♥ 6♣ 5♥ 4♥ 3♥]
Result (Lo): Player 2 wins with Six-low [6♣ 5♥ 4♥ 3♥ 2♠]
------ StudHiLo 2 ------
Player 1: [3♠ 6♦ Q♦ K♦ J♦ 3♦ Q♣]
  Hi: Flush, King-high [K♦ Q♦ J♦ 6♦ 3♦] [Q♣ 3♠]
  Lo: None
Player 2: [K♠ T♦ 2♥ T♠ 8♥ 8♣ 8♦]
  Hi: Full House, Eights full of Tens [8♣ 8♦ 8♥ T♦ T♠] [K♠ 2♥]
  Lo: None
Player 3: [Q♥ Q♠ 6♣ A♥ 4♥ 6♠ T♥]
  Hi: Two Pair, Queens over Sixes, kicker Ace [Q♥ Q♠ 6♣ 6♠ A♥] [T♥ 4♥]
  Lo: None
Player 4: [3♥ 7♣ 3♣ 5♦ 9♠ T♣ 9♣]
  Hi: Two Pair, Nines over Threes, kicker Ten [9♣ 9♠ 3♣ 3♥ T♣] [7♣ 5♦]
  Lo: None
Player 5: [J♠ 7♠ K♥ 7♥ 2♣ 2♦ A♦]
  Hi: Two Pair, Sevens over Twos, kicker Ace [7♥ 7♠ 2♣ 2♦ A♦] [K♥ J♠]
  Lo: None
Result (Hi): Player 2 scoops with Full House, Eights full of Tens [8♣ 8♦ 8♥ T♦ T♠]
Result (Lo): no player made a low hand
------ StudHiLo 3 ------
Player 1: [K♠ J♠ 3♠ 5♣ 7♠ 4♠ Q♠]
  Hi: Flush, King-high [K♠ Q♠ J♠ 7♠ 4♠] [3♠ 5♣]
  Lo: None
Player 2: [3♣ T♠ 5♥ 3♥ 8♦ 4♣ 8♥]
  Hi: Two Pair, Eights over Threes, kicker Ten [8♦ 8♥ 3♣ 3♥ T♠] [5♥ 4♣]
  Lo: None
Player 3: [2♣ T♦ 6♠ K♦ J♦ 2♠ Q♦]
  Hi: Pair, Twos, kickers King, Queen, Jack [2♣ 2♠ K♦ Q♦ J♦] [T♦ 6♠]
  Lo: None
Player 4: [2♦ A♣ T♣ 7♥ J♣ T♥ 4♥]
  Hi: Pair, Tens, kickers Ace, Jack, Seven [T♣ T♥ A♣ J♣ 7♥] [4♥ 2♦]
  Lo: None
Player 5: [8♠ K♣ 7♣ Q♣ K♥ 9♦ 6♦]
  Hi: Pair, Kings, kickers Queen, Nine, Eight [K♣ K♥ Q♣ 9♦ 8♠] [7♣ 6♦]
  Lo: None
Player 6: [5♠ J♥ 7♦ 3♦ 2♥ A♦ 9♣]
  Hi: Nothing, Ace-high, kickers Jack, Nine, Seven, Five [A♦ J♥ 9♣ 7♦ 5♠] [3♦ 2♥]
  Lo: Seven-low [7♦ 5♠ 3♦ 2♥ A♦] [J♥ 9♣]
Result (Hi): Player 1 wins with Flush, King-high [K♠ Q♠ J♠ 7♠ 4♠]
Result (Lo): Player 6 wins with Seven-low [7♦ 5♠ 3♦ 2♥ A♦]
------ StudHiLo 4 ------
Player 1: [6♠ Q♥ 2♣ 9♠ 3♦ T♣ K♥]
  Hi: Nothing, King-high, kickers Queen, Ten, Nine, Six [K♥ Q♥ T♣ 9♠ 6♠] [3♦ 2♣]
  Lo: None
Player 2: [4♥ 6♥ J♥ 4♦ Q♦ A♣ J♣]
  Hi: Two Pair, Jacks over Fours, kicker Ace [J♣ J♥ 4♦ 4♥ A♣] [Q♦ 6♥]
  Lo: None
Player 3: [5♣ K♠ K♣ A♠ 8♣ 5♥ Q♠]
  Hi: Two Pair, Kings over Fives, kicker Ace [K♣ K♠ 5♣ 5♥ A♠] [Q♠ 8♣]
  Lo: None
Player 4: [J♠ 8♦ 7♥ 2♠ 2♦ 6♦ 6♣]
  Hi: Two Pair, Sixes over Twos, kicker Jack [6♣ 6♦ 2♦ 2♠ J♠] [8♦ 7♥]
  Lo: None
Player 5: [8♥ Q♣ 5♦ 7♣ 9♥ K♦ 9♣]
  Hi: Pair, Nines, kickers King, Queen, Eight [9♣ 9♥ K♦ Q♣ 8♥] [7♣ 5♦]
  Lo: None
Player 6: [7♦ A♥ 3♠ 3♣ T♠ T♥ 2♥]
  Hi: Two Pair, Tens over Threes, kicker Ace [T♥ T♠ 3♣ 3♠ A♥] [7♦ 2♥]
  Lo: None
Result (Hi): Player 3 scoops with Two Pair, Kings over Fives, kicker Ace [K♣ K♠ 5♣ 5♥ A♠]
Result (Lo): no player made a low hand
------ StudHiLo 5 ------
Player 1: [3♦ T♥ A♣ 7♦ 5♣ 6♠ 4♦]
  Hi: Straight, Seven-high [7♦ 6♠ 5♣ 4♦ 3♦] [A♣ T♥]
  Lo: Six-low [6♠ 5♣ 4♦ 3♦ A♣] [T♥ 7♦]
Player 2: [J♠ 9♠ 3♣ Q♠ 7♠ 5♦ K♠]
  Hi: Flush, King-high [K♠ Q♠ J♠ 9♠ 7♠] [5♦ 3♣]
  Lo: None
Player 3: [T♠ 8♠ J♥ 7♥ J♣ 2♣ 3♠]
  Hi: Pair, Jacks, kickers Ten, Eight, Seven [J♣ J♥ T♠ 8♠ 7♥] [3♠ 2♣]
  Lo: None
Player 4: [7♣ 2♠ 2♥ 4♥ 4♣ K♣ 6♦]
  Hi: Two Pair, Fours over Twos, kicker King [4♣ 4♥ 2♥ 2♠ K♣] [7♣ 6♦]
  Lo: None
Player 5: [A♠ 9♦ K♥ 5♠ 8♦ 6♥ 8♥]
  Hi: Pair, Eights, kickers Ace, King, Nine [8♦ 8♥ A♠ K♥ 9♦] [6♥ 5♠]
  Lo: None
Player 6: [K♦ 8♣ 2♦ A♥ 6♣ 4♠ T♦]
  Hi: Nothing, Ace-high, kickers King, Ten, Eight, Six [A♥ K♦ T♦ 8♣ 6♣] [4♠ 2♦]
  Lo: Eight-low [8♣ 6♣ 4♠ 2♦ A♥] [K♦ T♦]
Result (Hi): Player 2 wins with Flush, King-high [K♠ Q♠ J♠ 9♠ 7♠]
Result (Lo): Player 1 wins with Six-low [6♠ 5♣ 4♦ 3♦ A♣]

Index

Examples

Constants

View Source
const (
	UnicodeSpadeAce     rune = '🂡'
	UnicodeHeartAce     rune = '🂱'
	UnicodeDiamondAce   rune = '🃁'
	UnicodeClubAce      rune = '🃑'
	UnicodeSpadeBlack   rune = '♠'
	UnicodeSpadeWhite   rune = '♤'
	UnicodeHeartBlack   rune = '♥'
	UnicodeHeartWhite   rune = '♡'
	UnicodeDiamondBlack rune = '♦'
	UnicodeDiamondWhite rune = '♢'
	UnicodeClubBlack    rune = '♣'
	UnicodeClubWhite    rune = '♧'
)

Unicode card runes.

View Source
const (
	// UnshuffledSize is the unshuffled deck size.
	UnshuffledSize = 52
	// UnshuffledShortSize is the unshuffled short deck size.
	UnshuffledShortSize = 36
	// UnshuffledRoyalSize is the unshuffled royal deck size.
	UnshuffledRoyalSize = 20
)

Variables

This section is empty.

Functions

func BadugiRanker added in v0.3.0

func BadugiRanker(hand []Card) (HandRank, []Card, []Card)

BadugiRanker is a Badugi hand ranker.

func CactusFastRanker added in v0.1.3

func CactusFastRanker(c0, c1, c2, c3, c4 Card) uint16

CactusFastRanker is a fast Cactus Kev hand ranker, implementing Paul Senzee's perfect hash lookup.

See: http://senzee.blogspot.com/2006/06/some-perfect-hash.html

func CactusRanker added in v0.1.3

func CactusRanker(c0, c1, c2, c3, c4 Card) uint16

CactusRanker is a Cactus Kev hand ranker that generates the lookup maps on the fly.

See: https://archive.is/G6GZg

func EightOrBetterRanker added in v0.1.3

func EightOrBetterRanker(c0, c1, c2, c3, c4 Card) uint16

EightOrBetterRanker is a 8-or-better low hand ranker. Aces are low, straights and flushes do not count. Any card with rank 8 or higher will cause

func Init added in v0.1.6

func Init()

Init inits the package level default variables. Must be manually called prior to using this package when built with the `noinit` build tag.

func LowOrder added in v0.1.3

func LowOrder(hands []*Hand) ([]int, int)

LowOrder orders hands by rank, low to high, returning 'pivot' of winning vs losing hands. If there are no low hands the pivot will be 0.

func Order added in v0.1.3

func Order(hands []*Hand) ([]int, int)

Order orders hands by rank, low to high, returning 'pivot' of winning vs losing hands. Pivot will always be 1 or higher.

func PlayingCardKnightRune

func PlayingCardKnightRune(r Rank, s Suit) rune

PlayingCardKnightRune returns the unicode playing card rune for the card rank and suit, substituting knights for jacks.

func PlayingCardRune

func PlayingCardRune(r Rank, s Suit) rune

PlayingCardRune returns the unicode playing card rune for the card rank and suit.

func RazzRanker added in v0.1.5

func RazzRanker(c0, c1, c2, c3, c4 Card) uint16

RazzRanker is a Razz (Ace-to-Five) low hand ranker. Aces are low, straights and flushes do not count.

When there is a pair (or higher) of matching ranks, will be the inverted value of the regular hand rank.

Types

type Card

type Card uint32

Card is a card consisting of a rank (23456789TJQKA) and suit (shdc).

Example (Unmarshal)
package main

import (
	"encoding/json"
	"fmt"
	"log"

	"cardrank.io/cardrank"
)

func main() {
	var hand []cardrank.Card
	if err := json.Unmarshal([]byte(`["3s", "4c", "5c", "Ah", "2d"]`), &hand); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", hand)
}
Output:

[3s 4c 5c Ah 2d]

func FromIndex added in v0.2.5

func FromIndex(i int) (Card, error)

FromIndex creates a card from a numerical index (0-51).

func FromRune

func FromRune(r rune) (Card, error)

FromRune creates a card from a unicode playing card rune.

Example
package main

import (
	"fmt"
	"log"

	"cardrank.io/cardrank"
)

func main() {
	c, err := cardrank.FromRune('🂡')
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%b\n", c)
}
Output:

A♠

func FromString

func FromString(str string) (Card, error)

FromString creates a card from a string.

func Must

func Must(v ...string) []Card

Must creates a Card slice from v.

See Parse for overview of accepted string representations of cards.

Example
package main

import (
	"fmt"

	"cardrank.io/cardrank"
)

func main() {
	hand := cardrank.Must("Ah K♠ 🃍 J♤ 10h")
	fmt.Printf("%b", hand)
}
Output:

[A♥ K♠ Q♦ J♠ T♥]

func MustCard

func MustCard(s string) Card

MustCard creates a Card from s.

Example
package main

import (
	"fmt"

	"cardrank.io/cardrank"
)

func main() {
	c := cardrank.MustCard("Ah")
	fmt.Printf("%N of %L (%b)\n", c, c, c)
}
Output:

Ace of Hearts (A♥)

func New

func New(r Rank, s Suit) Card

New creates a card for the specified rank and suit.

func Parse

func Parse(v ...string) ([]Card, error)

Parse parses strings of Card representations from v. Ignores whitespace between cards and case. Combines all parsed representations into a single Card slice.

Cards can described using common text strings (such as "Ah", "ah", "aH", or "AH"), or having a white or black unicode pip for the suit (such as "J♤" or "K♠"), or single unicode playing card runes (such as "🃆" or "🂣").

func Unshuffled

func Unshuffled() []Card

Unshuffled generates an unshuffled set of standard playing cards.

func UnshuffledExclude

func UnshuffledExclude(exclude []Card) []Card

UnshuffledExclude generates an unshuffled set of cards, with excluded cards removed.

func UnshuffledRoyal added in v0.2.0

func UnshuffledRoyal() []Card

UnshuffledRoyal generates an unshuffled set of royal cards (10+).

func UnshuffledShort added in v0.2.0

func UnshuffledShort() []Card

UnshuffledShort generates an unshuffled set of short cards (6+).

func (Card) Format

func (c Card) Format(f fmt.State, verb rune)

Format satisfies the fmt.Formatter interface.

Supported verbs:

s - rank (23456789TJQKA) and suit (shdc) (ex: Ks Ah)
S - same as s, uppercased (ex: KS AH)
q - same as s, quoted (ex: "Ks" "Ah")
v - same as s
r - rank (as in s) without suit (ex: K A)
u - suit (as in s) without rank (shdc)
b - rank (as in s) and the black unicode pip rune (♠♥♦♣) (ex: K♠ A♥)
B - black unicode pip rune (as in b) without rank (♠♥♦♣)
h - rank (as in s) and the white unicode pip rune (♤♡♢♧) (ex: K♤ A♡)
H - white unicode pip rune (as in h) without rank (♤♡♢♧)
c - playing card rune (ex: 🂡  🂱  🃁  🃑)
C - playing card rune (as in c), substituting knights for jacks (ex: 🂬  🂼  🃌  🃜)
n - rank name, lower cased (ex: one two jack queen king ace)
N - rank name, title cased (ex: One Two Jack Queen King Ace)
p - plural rank name, lower cased (ex: ones twos sixes)
P - plural rank name, title cased (ex: Ones Twos Sixes)
t - suit name, lower cased (spade heart diamond club)
T - suit name, title cased (Spade Heart Diamond Club)
l - plural suit name, lower cased (spades hearts diamonds clubs)
L - plural suit name, title cased (Spades Hearts Diamonds Clubs)
d - base 10 integer value

func (Card) Index added in v0.2.5

func (c Card) Index() int

Index returns the index of the card.

func (Card) MarshalText

func (c Card) MarshalText() ([]byte, error)

MarshalText satisfies the encoding.TextMarshaler interface.

func (Card) Rank

func (c Card) Rank() Rank

Rank returns the rank of the card.

func (Card) RankByte

func (c Card) RankByte() byte

RankByte returns the rank byte of the card.

func (Card) RankIndex

func (c Card) RankIndex() int

RankIndex returns the rank index of the card.

func (Card) String

func (c Card) String() string

String satisfies the fmt.Stringer interface.

func (Card) Suit

func (c Card) Suit() Suit

Suit returns the suit of the card.

func (Card) SuitByte

func (c Card) SuitByte() byte

SuitByte returns the suit byte of the card.

func (Card) SuitIndex

func (c Card) SuitIndex() int

SuitIndex returns the suit index of the card.

func (*Card) UnmarshalText

func (c *Card) UnmarshalText(buf []byte) error

UnmarshalText satisfies the encoding.TextUnmarshaler interface.

type Deck

type Deck struct {
	// contains filtered or unexported fields
}

Deck is a set of playing cards.

func NewDeck

func NewDeck(cards ...Card) *Deck

NewDeck creates a new deck of cards. If no cards are provided, then a deck will be created using the standard unshuffled cards.

func NewRoyalDeck added in v0.2.0

func NewRoyalDeck() *Deck

NewRoyalDeck creates a new royal deck (10+).

func NewShoeDeck added in v0.2.0

func NewShoeDeck(n int) *Deck

NewShoeDeck creates a card deck "shoe" composed of n decks of unshuffled cards.

func NewShortDeck

func NewShortDeck() *Deck

NewShortDeck creates a new short deck (6+).

func (*Deck) Badugi added in v0.1.3

func (d *Deck) Badugi(hands int) ([][]Card, []Card)

Badugi draws hands for Badugi, returning the sets of pockets (one per hand). Deals no board cards.

func (*Deck) Board

func (d *Deck) Board(counts ...int) []Card

Board draws board cards by discarding a card and drawing n cards for each n in counts.

func (*Deck) Deal

func (d *Deck) Deal(hands, n int) [][]Card

Deal draws one card successively for each hand until each hand has n cards.

func (*Deck) Draw

func (d *Deck) Draw(n int) []Card

Draw draws the next n cards from the top (front) of the deck.

Example
package main

import (
	"fmt"
	"math/rand"

	"cardrank.io/cardrank"
)

func main() {
	d := cardrank.NewDeck()
	// note: use a real random source
	rnd := rand.New(rand.NewSource(52))
	d.Shuffle(rnd.Shuffle)
	hand := d.Draw(7)
	fmt.Printf("%b\n", hand)
}
Output:

[9♣ 6♥ Q♠ 3♠ J♠ 9♥ K♣]

func (*Deck) Empty

func (d *Deck) Empty() bool

Empty returns true when there are no cards remaining in the deck.

func (*Deck) Holdem

func (d *Deck) Holdem(hands int) ([][]Card, []Card)

Holdem draws hands for Texas Holdem, returning the set of pockets (one per hand) and board cards. Deals 1 card per player until each player has 2 pocket cards, then discards a card, deals 3 board cards, discards another, deals another board card, discards another, and deals a final card to the board.

func (*Deck) MultiBoard added in v0.2.7

func (d *Deck) MultiBoard(n int, counts ...int) [][]Card

MultiBoard draws n boards of cards, by discarding a card and drawing m cards for each m in counts.

func (*Deck) Omaha

func (d *Deck) Omaha(hands int) ([][]Card, []Card)

Omaha draws hands for Omaha, returning the set of pockets (one per hand) and board cards.

func (*Deck) Remaining

func (d *Deck) Remaining() int

Remaining returns the number of remaining cards in the deck.

func (*Deck) SetLimit

func (d *Deck) SetLimit(limit int)

SetLimit sets a limit for the deck.

Useful when using a card deck "shoe" composed of more than one deck of cards.

func (*Deck) Shuffle

func (d *Deck) Shuffle(f func(int, func(int, int)))

Shuffle shuffles the deck's cards using f (same interface as math/rand.Shuffle).

func (*Deck) ShuffleN

func (d *Deck) ShuffleN(n int, f func(int, func(int, int)))

ShuffleN shuffles the deck's cards, n times, using f (same interface as math/rand.Shuffle).

func (*Deck) Stud added in v0.1.3

func (d *Deck) Stud(hands int) ([][]Card, []Card)

Stud draws hands for Stud, returning the sets of pockets (one per hand). Deals no board cards.

type Error

type Error string

Error is a error.

const (
	// ErrInvalidCard is the invalid card error.
	ErrInvalidCard Error = "invalid card"
	// ErrInvalidCardRank is the invalid card rank error.
	ErrInvalidCardRank Error = "invalid card rank"
	// ErrInvalidCardSuit is the invalid card suit error.
	ErrInvalidCardSuit Error = "invalid card suit"
	// ErrInvalidType is the invalid type error.
	ErrInvalidType Error = "invalid type"
)

Error values.

func (Error) Error

func (err Error) Error() string

Error satisfies the error interface.

type Hand

type Hand struct {
	// contains filtered or unexported fields
}

Hand is a poker hand.

func NewHand

func NewHand(typ Type, pocket, board []Card) *Hand

NewHand creates a new hand of the specified type.

Example
package main

import (
	"fmt"
	"math/rand"

	"cardrank.io/cardrank"
)

func main() {
	d := cardrank.NewDeck()
	// note: use a real random source
	rnd := rand.New(rand.NewSource(6265))
	d.Shuffle(rnd.Shuffle)
	hand := d.Draw(5)
	h := cardrank.NewHand(cardrank.Holdem, hand, nil)
	fmt.Printf("%b\n", h)
}
Output:

Four of a Kind, Eights, kicker Seven [8♣ 8♦ 8♥ 8♠ 7♠]

func (*Hand) Best

func (h *Hand) Best() []Card

Best returns the hand's best-five cards.

func (*Hand) Board

func (h *Hand) Board() []Card

Board returns the hand's board.

func (*Hand) Compare

func (h *Hand) Compare(b *Hand) int

Compare compares the hand ranks.

func (*Hand) Description

func (h *Hand) Description() string

Description describes the hand's best-five cards.

Examples:

Straight Flush, Ace-high, Royal
Straight Flush, King-high
Straight Flush, Five-high, Steel Wheel
Four of a Kind, Nines, kicker Jack
Full House, Sixes full of Fours
Flush, Ten-high
Straight, Eight-high
Three of a Kind, Fours, kickers Ace, King
Two Pair, Nines over Sixes, kicker Jack
Pair, Aces, kickers King, Queen, Nine
Nothing, Seven-high, kickers Six, Five, Three, Two

func (*Hand) Fixed

func (h *Hand) Fixed() HandRank

Fixed returns the hand's fixed rank.

func (*Hand) Format

func (h *Hand) Format(f fmt.State, verb rune)

Format satisfies the fmt.Formatter interface.

func (Hand) LowBest added in v0.1.1

func (h Hand) LowBest() []Card

LowBest returns the hand's best-five low cards.

func (*Hand) LowCompare added in v0.1.3

func (h *Hand) LowCompare(b *Hand) int

LowCompare compares the low hand ranks.

func (*Hand) LowDescription added in v0.1.1

func (h *Hand) LowDescription() string

LowDescription describes the hands best-five low cards.

func (Hand) LowRank added in v0.1.3

func (h Hand) LowRank() HandRank

LowRank returns the hand's low rank.

func (Hand) LowUnused added in v0.1.1

func (h Hand) LowUnused() []Card

LowUnused returns the poker hand's unused-five low cards.

func (*Hand) LowValid added in v0.1.3

func (h *Hand) LowValid() bool

LowValid returns true if is a valid low hand.

func (*Hand) Pocket

func (h *Hand) Pocket() []Card

Pocket returns the hand's pocket.

func (*Hand) Rank

func (h *Hand) Rank() HandRank

Rank returns the hand's rank.

func (*Hand) Unused

func (h *Hand) Unused() []Card

Unused returns the hand's unused cards.

type HandFormatter

type HandFormatter []Card

HandFormatter wraps formatting a set of cards. Allows `go test` to function without disabling vet.

func (HandFormatter) Format

func (hand HandFormatter) Format(f fmt.State, verb rune)

Format satisfies the fmt.Formatter interface.

type HandRank

type HandRank uint16

HandRank is a poker hand rank.

Ranks are ordered low-to-high.

const (
	StraightFlush HandRank = 10
	FourOfAKind   HandRank = 166
	FullHouse     HandRank = 322
	Flush         HandRank = 1599
	Straight      HandRank = 1609
	ThreeOfAKind  HandRank = 2467
	TwoPair       HandRank = 3325
	Pair          HandRank = 6185
	Nothing       HandRank = 7462
	HighCard      HandRank = Nothing
	Invalid                = HandRank(^uint16(0))
)

Poker hand rank values.

See: https://archive.is/G6GZg

func (HandRank) Fixed

func (r HandRank) Fixed() HandRank

Fixed converts a relative poker rank to a fixed hand rank.

func (HandRank) Name

func (r HandRank) Name() string

Name returns the hand rank name.

func (HandRank) String

func (r HandRank) String() string

String satisfies the fmt.Stringer interface.

type Rank

type Rank uint8

Rank is a card rank.

const (
	Ace Rank = 12 - iota
	King
	Queen
	Jack
	Ten
	Nine
	Eight
	Seven
	Six
	Five
	Four
	Three
	Two
)

Card ranks.

func RankFromRune

func RankFromRune(r rune) (Rank, error)

RankFromRune returns the card rank for the rune.

func (Rank) Byte

func (r Rank) Byte() byte

Byte returns the byte representation for the card rank.

func (Rank) Index

func (r Rank) Index() int

Index the int index for the card rank (0-12 for Two-Ace).

func (Rank) Name

func (r Rank) Name() string

Name returns the name of the card rank.

func (Rank) PluralName

func (r Rank) PluralName() string

PluralName returns the plural name of the card rank.

func (Rank) String

func (r Rank) String() string

String satisfies the fmt.Stringer interface.

type RankFiveFunc added in v0.1.3

type RankFiveFunc func(c0, c1, c2, c3, c4 Card) uint16

RankFiveFunc ranks a hand of 5 cards.

var DefaultCactus RankFiveFunc

DefaultCactus is the default Cactus Kev implementation.

func SixPlusRanker added in v0.1.3

func SixPlusRanker(f RankFiveFunc) RankFiveFunc

SixPlusRanker creates a 6-plus hand ranker.

type RankerFunc

type RankerFunc func([]Card) HandRank

RankerFunc ranks a hand of 5, 6, or 7 cards.

var DefaultRanker RankerFunc

DefaultRanker is the default hand ranker.

var DefaultSixPlusRanker RankerFunc

DefaultSixPlusRanker is the default 6-plus (short deck) hand ranker.

func HandRanker added in v0.1.3

func HandRanker(f RankFiveFunc) RankerFunc

HandRanker creates a new hand ranker for 5, 6, or 7 cards using f.

func HybridRanker added in v0.1.3

func HybridRanker(f5 RankFiveFunc, f7 RankerFunc) RankerFunc

HybridRanker creates a hybrid ranker using f5 for hands with 5 and 6 cards, and f7 for hands with 7 cards.

func NewTwoPlusTwoRanker added in v0.1.5

func NewTwoPlusTwoRanker() RankerFunc

TwoPlusRanker creates a new two plus hand ranker.

type Suit

type Suit uint8

Suit is a card suit.

const (
	Spade Suit = 1 << iota
	Heart
	Diamond
	Club
)

Card suits.

func SuitFromRune

func SuitFromRune(r rune) (Suit, error)

SuitFromRune returns the card suit for the rune.

func (Suit) Byte

func (s Suit) Byte() byte

Byte returns the byte representation for the card suit.

func (Suit) Index

func (s Suit) Index() int

Index returns the int index for the card suit (0-3 for Spade, Heart, Diamond, Club).

func (Suit) Name

func (s Suit) Name() string

Name returns the name of the card suit.

func (Suit) PluralName

func (s Suit) PluralName() string

PluralName returns the plural name of the card suit.

func (Suit) String

func (s Suit) String() string

String satisfies the fmt.Stringer interface.

func (Suit) UnicodeBlack

func (s Suit) UnicodeBlack() rune

UnicodeBlack returns the black unicode pip rune for the card suit.

func (Suit) UnicodeWhite

func (s Suit) UnicodeWhite() rune

UnicodeWhite returns the white unicode pip rune for the card suit.

type TwoPlusTwoRanker added in v0.1.5

type TwoPlusTwoRanker struct {
	// contains filtered or unexported fields
}

TwoPlusTwoRanker is a implementation of the 2+2 poker forum hand ranker. Uses the embedded twoplustwo*.dat files to provide extremely fast 7 card hand lookup. Uses Cactus Kev values.

The lookup table is contained in the 'twoplustwo*.dat' files, and were broken up from a single file to get around GitHub's size limitations. Files were generated with 'gen.go', which is a pure-Go implementation of the code generator available at: https://github.com/tangentforks/TwoPlusTwoHandEvaluator

When recombined, the lookup table has the same hash as the original table generated using the C code.

type Type

type Type uint32

Type is a hand type.

const (
	Holdem Type = iota
	Short
	Royal
	Omaha
	OmahaHiLo
	Stud
	StudHiLo
	Razz
	Badugi
)

Hand types.

func (Type) Best

func (typ Type) Best(pocket, board []Card) (HandRank, []Card, []Card, HandRank, []Card, []Card)

Best returns the best hand and rank for the provided pocket, board. Returns the rank of the best available hand, its best cards, and its unused cards.

func (Type) Deal

func (typ Type) Deal(shuffle func(int, func(int, int)), hands int) ([][]Card, []Card)

Deal creates a new deck for the type, shuffling it once, returning the pockets and board for the number of hands specified.

Use DealShuffle when needing to shuffle the deck more than once.

func (Type) DealShuffle added in v0.2.0

func (typ Type) DealShuffle(shuffle func(int, func(int, int)), count, hands int) ([][]Card, []Card)

DealShuffle creates a new deck for the type and shuffles the deck count number of times, returning the pockets and board for the number of hands specified.

func (Type) Deck

func (typ Type) Deck() *Deck

NewDeck returns a new deck for the type.

func (Type) Low added in v0.2.4

func (typ Type) Low() bool

Low returns true if the hand type supports low evaluation.

func (Type) MarshalText added in v0.2.9

func (typ Type) MarshalText() ([]byte, error)

MarshalText satisfies the encoding.TextMarshaler interface.

func (Type) MaxPlayers added in v0.1.3

func (typ Type) MaxPlayers() int

MaxPlayers returns the max players for the type.

func (Type) RankHand

func (typ Type) RankHand(pocket, board []Card) *Hand

RankHand ranks the hand.

func (Type) RankHands

func (typ Type) RankHands(pockets [][]Card, board []Card) []*Hand

RankHands ranks the hands.

func (Type) String

func (typ Type) String() string

String satisfies the fmt.Stringer interface.

func (*Type) UnmarshalText added in v0.2.9

func (typ *Type) UnmarshalText(buf []byte) error

UnmarshalText satisfies the encoding.TextUnmarshaler interface.

Directories

Path Synopsis
_example

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL