cardrank

package module
v0.10.3 Latest Latest
Warning

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

Go to latest
Published: Mar 4, 2023 License: MIT Imports: 8 Imported by: 3

README

About

Package cardrank is a library of types, utilities, and interfaces for working with playing cards, card decks, evaluating poker ranks, managing deals and run outs for different game types.

Tests Go Report Card Reference Releases

Overview

The cardrank package contains types for working with Card's, Suit's, Rank's, Deck's, evaluating poker ranks, and managing deals and run outs.

In most cases, using the high-level Dealer with any registered Type should be sufficient for most purposes. An in-depth example is provided in the package documentation.

A Type wraps a type description defining a type's deal streets, deck, eval, Hi/Lo description and other meta-data needed for dealing streets and managing run outs.

Evaluation and ranking of the types is accomplished through pure Go implementations of well-known poker rank evaluation algorithms. Evaluation of cards can be compared and ordered to determine winner(s).

Supported Types

Supports evaluating and ranking the following Type's:

Holdem Variants Omaha Variants Hybrid Variants Draw Variants Other
Holdem Omaha Dallas Video Soko
Split OmahaHiLo Houston Draw SokoHiLo
Short OmahaDouble Fusion DrawHiLo Lowball
Manila OmahaFive FusionHiLo Stud LowballTriple
Spanish OmahaSix StudHiLo Razz
Royal Courchevel StudFive Badugi
Double CourchevelHiLo
Showtime
Swap
River

See the package's Type documentation for an overview of the above.

Using

To use within a Go package:

go get github.com/cardrank/cardrank

See package level Go package documentation for in-depth overviews of APIs.

Quickstart

Various examples are available in the Go package documentation. showing use of various types, utilities, and interfaces.

Additional examples for a Dealer and the Holdem and OmahaHiLo types are included in the example directory:

  • dealer - shows use of the Dealer, to handle dealing cards, handling multiple run outs, and determining winners using any Type's
  • holdem - shows using types and utilities to deal Holdem
  • omahahilo - shows using types and utilities to OmahaHiLo, demonstrating splitting Hi and Lo wins
Eval Ranking

EvalRank's are determined using a registered EvalFunc associated with the Type. EvalRank's are always ordered, low to high, and are relative/comparable:

fmt.Printf("%t\n", cardrank.StraightFlush < cardrank.FullHouse)

// Output:
true

Pocket and board Card's can be passed to a Type's Eval method, which in turn uses the Type's registered EvalFunc and returns an Evaluated value:

pocket, board := cardrank.Must("Ah Kh"), cardrank.Must("Qh Jh Th 2s 3s")
ev := cardrank.Holdem.Eval(pocket, board)
fmt.Printf("%s - %d\n", ev, ev.HiRank)

// Output:
// Straight Flush, Ace-high, Royal [Ah Kh Qh Jh Th] - 1

When evaluating cards, usually the eval is for 5, 6, or 7 cards, but some Type's are capable of evaluating fewer Card's:

pocket := cardrank.Must("2h 3s 4c")
ev := cardrank.Badugi.Eval(pocket, nil)
fmt.Printf("%s\n", ev)

// Output:
// Four, Three, Two-low [4c 3s 2h]

If an invalid number of cards is passed to a Type's EvalFunc, the Eval's HiRank and LoRank values will be set to Invalid.

Eval's can be used to compare different hands of Card's in order to determine a winner, by comparing the Eval.HiRank or Eval.LoRank values.

Hi/Lo

Different Type's may have both a Hi and Lo EvalRank, such as Double board Holdem, and various *HiLo variants, such as OmahaHiLo.

When a Eval is created, both the Hi and Lo values will be made available in the resulting Eval as the HiRank and LoRank, respectively.

Cactus Kev

For most Type's, the EvalRank is determined by Go implementations of a few well-known Cactus Kev algorithms:

See below for more information on the default rank func in use by the package, and for information on using build tags to enable/disable functionality for different target runtime environments.

Rank Cactus Func

The package-level RankCactus variable is used for regular poker evaluation, and can be set externally when wanting to build new game types, or trying new algorithms.

Two-Plus-Two

NewTwoPlusTwoEval 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 lookup table can be excluded when using the using the portable or embedded build tags, with slightly degraded performance for when evaluating 7 cards.

Note: it is disabled by default when GOOS=js (ie, WASM) builds, but can be forced to be included with the forcefat build tag.

Winner Determination

Winner(s) are determined by the lowest possible EvalRank for either the Hi or Lo value for the Type. Two or more hands having a EvalRank of equal value indicate that the hands have equivalent ranks, and have both won.

Eval's can be sorted (low-to-high) by it's HiRank and LoRank members. Winner(s) of a hand will be the hands in the lowest position and having equivalent HiRank's or LoRank's.

Comparing Eval Ranks

A Eval can be compared to another Eval using Comp.

Comp returns -1, 0, or +1, making it easy to compare or sort hands:

// Compare Hi:
if ev1.Comp(ev2, false) < 0 {
	fmt.Printf("%s is a winner!", ev1)
}

// Compare Lo:
if ev1.Comp(ev2, true) == 0 {
	fmt.Printf("%s and %s are equal!", ev1, ev2)
}

// Sort by Hi:
hi := evs[0].NewComp(false)
sort.Slice(evs, func(i, j int) bool {
	return hi(evs[i], evs[j]) < 0
})

// Sort by Lo:
lo := evs[0].NewComp(true)
sort.Slice(evs, func(i, j int) bool {
	return lo(evs[i], evs[j]) < 0
})
Ordering Evals

Order can determine the winner(s) of a hand by ordering the indexes of a []*Eval and returning the list of ordered evals as a []int and an int pivot indicating the position within the returned []int as a cutoff for a win:

// Order by HiRank:
hiOrder, hiPivot := cardrank.Order(evs, false)

For a Type with a lo value:

// Order by LoRank:
loOrder, loPivot := cardrank.Order(evs, true)

A Eval whose index is in position i < pivot is considered to be the winner(s). When ordering by HiRank, there will be 1 or more winner(s) (with exception for Video types), but when ordering by LoRank there may be 0 or more winner(s):

for i := 0; i < hiPivot; i++ {
	fmt.Printf("%s is a Hi winner!", evs[hiOrder[i]])
}

Similarly, for lo winners:

for i := 0; i < loPivot; i++ {
	fmt.Printf("%s is a Lo winner!", evs[loOrder[i]])
}
Build Tags

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

portable

The portable tag disables inclusion of the Two-plus-two lookup tables, 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 client application:

go build -tags portable
embedded

The embedded tag disables the CactusFast and the TwoPlusTwo, creating the smallest possible binaries. Useful when either embedding the package in another application, or in constrained runtime environments such as WASM:

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

The noinit tag disables the package level initialization. Useful when applications need the fastest possible startup times and can defer initialization, or when using a third-party algorithm:

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

When using the noinit build tag, the user will need to call the Init func to set RankCactus and to register the default types automatically:

// Set DefaultCactus, DefaultRank based on available implementations:
cardrank.Init()

Alternatively, the RankCactus can be set manually. After RankCactus has been set, call RegisterDefaultTypes to register built in types:

// Set when using a third-party implementation, or experimenting with new
// Cactus implementations:
cardrank.RankCactus = cardrank.CactusFast

// Call RegisterDefaultTypes to register default types
if err := cardrank.RegisterDefaultTypes(); err != nil {
	panic(err)
}
forcefat

The forcefat tag forces a "fat" binary build, including the TwoPlusTwo's large lookup table, irrespective of other build tags:

GOOS=js GOARCH=wasm go build -tags 'forcefat' -o cardrank.wasm

Documentation

Overview

Package cardrank is a library of types, utilities, and interfaces for working with playing cards, card decks, evaluating poker hand ranks, managing deals and run outs for different game types.

Example (Badugi)
package main

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

	"github.com/cardrank/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
		r := rand.New(rand.NewSource(game.seed))
		pockets, _ := cardrank.Badugi.Deal(r, 1, game.players)
		evs := cardrank.Badugi.EvalPockets(pockets, nil)
		fmt.Printf("------ Badugi %d ------\n", i+1)
		for j := 0; j < game.players; j++ {
			desc := evs[j].Desc(false)
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, pockets[j], desc, desc.Best, desc.Unused)
		}
		order, pivot := cardrank.Order(evs, false)
		desc := evs[order[0]].Desc(false)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s\n", order[0]+1, desc)
		} else {
			var s []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(order[j]+1))
			}
			fmt.Printf("Result:   Players %s push with %s\n", strings.Join(s, ", "), desc)
		}
	}
}
Output:

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

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

	"github.com/cardrank/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
		r := rand.New(rand.NewSource(game.seed))
		pockets, board := cardrank.Holdem.Deal(r, 1, game.players)
		evs := cardrank.Holdem.EvalPockets(pockets, board)
		fmt.Printf("------ Holdem %d ------\n", i+1)
		fmt.Printf("Board:    %b\n", board)
		for j := 0; j < game.players; j++ {
			desc := evs[j].Desc(false)
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, pockets[j], desc, desc.Best, desc.Unused)
		}
		order, pivot := cardrank.Order(evs, false)
		desc := evs[order[0]].Desc(false)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s\n", order[0]+1, desc)
		} else {
			var s []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(order[j]+1))
			}
			fmt.Printf("Result:   Players %s push with %s\n", strings.Join(s, ", "), desc)
		}
	}
}
Output:

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

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

	"github.com/cardrank/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
		r := rand.New(rand.NewSource(game.seed))
		pockets, board := cardrank.Omaha.Deal(r, 1, game.players)
		evs := cardrank.Omaha.EvalPockets(pockets, board)
		fmt.Printf("------ Omaha %d ------\n", i+1)
		fmt.Printf("Board:    %b\n", board)
		for j := 0; j < game.players; j++ {
			desc := evs[j].Desc(false)
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, pockets[j], desc, desc.Best, desc.Unused)
		}
		order, pivot := cardrank.Order(evs, false)
		desc := evs[order[0]].Desc(false)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s\n", order[0]+1, desc)
		} else {
			var s []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(order[j]+1))
			}
			fmt.Printf("Result:   Players %s push with %s\n", strings.Join(s, ", "), desc)
		}
	}
}
Output:

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

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

	"github.com/cardrank/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
		r := rand.New(rand.NewSource(game.seed))
		pockets, board := cardrank.OmahaHiLo.Deal(r, 1, game.players)
		evs := cardrank.OmahaHiLo.EvalPockets(pockets, board)
		fmt.Printf("------ OmahaHiLo %d ------\n", i+1)
		fmt.Printf("Board: %b\n", board)
		for j := 0; j < game.players; j++ {
			hi, lo := evs[j].Desc(false), evs[j].Desc(true)
			fmt.Printf("Player %d: %b\n", j+1, pockets[j])
			fmt.Printf("  Hi: %s %b %b\n", hi, hi.Best, hi.Unused)
			fmt.Printf("  Lo: %s %b %b\n", lo, lo.Best, lo.Unused)
		}
		hiOrder, hiPivot := cardrank.Order(evs, false)
		loOrder, loPivot := cardrank.Order(evs, true)
		typ := "wins"
		if loPivot == 0 {
			typ = "scoops"
		}
		desc := evs[hiOrder[0]].Desc(false)
		if hiPivot == 1 {
			fmt.Printf("Result (Hi): Player %d %s with %s\n", hiOrder[0]+1, typ, desc)
		} else {
			var s []string
			for j := 0; j < hiPivot; j++ {
				s = append(s, strconv.Itoa(hiOrder[j]+1))
			}
			fmt.Printf("Result (Hi): Players %s push with %s\n", strings.Join(s, ", "), desc)
		}
		if loPivot == 1 {
			desc := evs[loOrder[0]].Desc(true)
			fmt.Printf("Result (Lo): Player %d wins with %s\n", loOrder[0]+1, desc)
		} else if loPivot > 1 {
			var s []string
			for j := 0; j < loPivot; j++ {
				s = append(s, strconv.Itoa(loOrder[j]+1))
			}
			desc := evs[loOrder[0]].Desc(true)
			fmt.Printf("Result (Lo): Players %s push with %s\n", strings.Join(s, ", "), desc)
		} else {
			fmt.Printf("Result (Lo): no player made a lo\n")
		}
	}
}
Output:

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

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

	"github.com/cardrank/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
		r := rand.New(rand.NewSource(game.seed))
		pockets, _ := cardrank.Razz.Deal(r, 1, game.players)
		evs := cardrank.Razz.EvalPockets(pockets, nil)
		fmt.Printf("------ Razz %d ------\n", i+1)
		for j := 0; j < game.players; j++ {
			desc := evs[j].Desc(false)
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, pockets[j], desc, desc.Best, desc.Unused)
		}
		order, pivot := cardrank.Order(evs, false)
		desc := evs[order[0]].Desc(false)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s\n", order[0]+1, desc)
		} else {
			var s []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(order[j]+1))
			}
			fmt.Printf("Result:   Players %s push with %s\n", strings.Join(s, ", "), desc)
		}
	}
}
Output:

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

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

	"github.com/cardrank/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
		r := rand.New(rand.NewSource(game.seed))
		pockets, board := cardrank.Royal.Deal(r, 1, game.players)
		evs := cardrank.Royal.EvalPockets(pockets, board)
		fmt.Printf("------ Royal %d ------\n", i+1)
		fmt.Printf("Board:    %b\n", board)
		for j := 0; j < game.players; j++ {
			desc := evs[j].Desc(false)
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, pockets[j], desc, desc.Best, desc.Unused)
		}
		order, pivot := cardrank.Order(evs, false)
		desc := evs[order[0]].Desc(false)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s\n", order[0]+1, desc)
		} else {
			var s []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(order[j]+1))
			}
			fmt.Printf("Result:   Players %s push with %s\n", strings.Join(s, ", "), desc)
		}
	}
}
Output:

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

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

	"github.com/cardrank/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
		r := rand.New(rand.NewSource(game.seed))
		pockets, board := cardrank.Short.Deal(r, 1, game.players)
		evs := cardrank.Short.EvalPockets(pockets, board)
		fmt.Printf("------ Short %d ------\n", i+1)
		fmt.Printf("Board:    %b\n", board)
		for j := 0; j < game.players; j++ {
			desc := evs[j].Desc(false)
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, pockets[j], desc, desc.Best, desc.Unused)
		}
		order, pivot := cardrank.Order(evs, false)
		desc := evs[order[0]].Desc(false)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s\n", order[0]+1, desc)
		} else {
			var s []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(order[j]+1))
			}
			fmt.Printf("Result:   Players %s push with %s\n", strings.Join(s, ", "), desc)
		}
	}
}
Output:

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

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

	"github.com/cardrank/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
		r := rand.New(rand.NewSource(game.seed))
		pockets, _ := cardrank.Stud.Deal(r, 1, game.players)
		evs := cardrank.Stud.EvalPockets(pockets, nil)
		fmt.Printf("------ Stud %d ------\n", i+1)
		for j := 0; j < game.players; j++ {
			desc := evs[j].Desc(false)
			fmt.Printf("Player %d: %b %s %b %b\n", j+1, pockets[j], desc, desc.Best, desc.Unused)
		}
		order, pivot := cardrank.Order(evs, false)
		desc := evs[order[0]].Desc(false)
		if pivot == 1 {
			fmt.Printf("Result:   Player %d wins with %s\n", order[0]+1, desc)
		} else {
			var s []string
			for j := 0; j < pivot; j++ {
				s = append(s, strconv.Itoa(order[j]+1))
			}
			fmt.Printf("Result:   Players %s push with %s\n", strings.Join(s, ", "), desc)
		}
	}
}
Output:

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

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

	"github.com/cardrank/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
		r := rand.New(rand.NewSource(game.seed))
		pockets, _ := cardrank.StudHiLo.Deal(r, 1, game.players)
		evs := cardrank.StudHiLo.EvalPockets(pockets, nil)
		fmt.Printf("------ StudHiLo %d ------\n", i+1)
		for j := 0; j < game.players; j++ {
			hi, lo := evs[j].Desc(false), evs[j].Desc(true)
			fmt.Printf("Player %d: %b\n", j+1, pockets[j])
			fmt.Printf("  Hi: %s %b %b\n", hi, hi.Best, hi.Unused)
			fmt.Printf("  Lo: %s %b %b\n", lo, lo.Best, lo.Unused)
		}
		hiOrder, hiPivot := cardrank.Order(evs, false)
		loOrder, loPivot := cardrank.Order(evs, true)
		typ := "wins"
		if loPivot == 0 {
			typ = "scoops"
		}
		desc := evs[hiOrder[0]].Desc(false)
		if hiPivot == 1 {
			fmt.Printf("Result (Hi): Player %d %s with %s\n", hiOrder[0]+1, typ, desc)
		} else {
			var s []string
			for j := 0; j < hiPivot; j++ {
				s = append(s, strconv.Itoa(hiOrder[j]+1))
			}
			fmt.Printf("Result (Hi): Players %s push with %s\n", strings.Join(s, ", "), desc)
		}
		if loPivot == 1 {
			desc := evs[loOrder[0]].Desc(true)
			fmt.Printf("Result (Lo): Player %d wins with %s\n", loOrder[0]+1, desc)
		} else if loPivot > 1 {
			var s []string
			for j := 0; j < loPivot; j++ {
				s = append(s, strconv.Itoa(loOrder[j]+1))
			}
			desc := evs[loOrder[0]].Desc(true)
			fmt.Printf("Result (Lo): Players %s push with %s\n", strings.Join(s, ", "), desc)
		} else {
			fmt.Printf("Result (Lo): no player made a lo\n")
		}
	}
}
Output:

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

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 (
	// DeckFrench is a standard deck of 52 cards (aka "French" deck).
	DeckFrench = DeckType(Two)
	// DeckShort is a deck of Short (6+) cards.
	DeckShort = DeckType(Six)
	// DeckManila is a deck of Manila (7+) cards.
	DeckManila = DeckType(Seven)
	// DeckSpanish is a deck of Spanish (8+) cards.
	DeckSpanish = DeckType(Eight)
	// DeckRoyal is a deck of Royal (10+) cards.
	DeckRoyal = DeckType(Ten)
)

Deck types.

View Source
const InvalidCard = ^Card(0)

InvalidCard is an invalid card.

View Source
const InvalidRank = ^Rank(0)

InvalidRank is an invalid rank.

View Source
const InvalidSuit = ^Suit(0)

InvalidSuit is an invalid suit.

Variables

This section is empty.

Functions

func CactusDesc added in v0.9.0

func CactusDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)

CactusDesc writes a Cactus description to f for the rank, best, and unused cards.

Examples:

Straight Flush, Ace-high, Royal
Straight Flush, King-high, Platinum Oxide
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
Seven-high, kickers Six, Five, Three, Two

func FlushOverDesc added in v0.10.0

func FlushOverDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)

FlushOverDesc writes a FlushOver description to f for the rank, best, and unused cards.

func HoldemBlinds added in v0.8.0

func HoldemBlinds() []string

HoldemBlinds returns the Holdem blind names.

func Init

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 LowDesc added in v0.9.0

func LowDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)

LowDesc writes a Low description to f for the rank, best, and unused cards.

func LowballDesc added in v0.9.0

func LowballDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)

LowballDesc writes a Lowball description to f for the rank, best, and unused cards.

func NewTwoPlusTwoEval added in v0.10.0

func NewTwoPlusTwoEval() func([]Card) EvalRank

NewTwoPlusTwo creates a new Two-Plus-Two rank eval func, a version of the 2+2 poker forum rank evaluator. Uses the embedded twoplustwo*.dat files to provide extremely fast 7 card lookup.

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 'internal/twoplustwogen.go', which is a pure-Go port 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.

func Order

func Order(evs []*Eval, low bool) ([]int, int)

Order determines the hi or lo order for evs, using the the first eval type's Comp. Returns indices and pivot of winning vs losing. Pivot will always be 1 or higher for hi evals. When ordering low evals, if there are no valid (ie, qualified) evals, the returned pivot will be 0.

func PlayingCardKnightRune

func PlayingCardKnightRune(rank Rank, suit Suit) rune

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

func PlayingCardRune

func PlayingCardRune(rank Rank, suit Suit) rune

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

func RazzDesc added in v0.9.0

func RazzDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)

RazzDesc writes a Razz description to f for the rank, best, and unused cards.

func RegisterDefaultTypes added in v0.8.0

func RegisterDefaultTypes() error

RegisterDefaultTypes registers default types.

See DefaultTypes.

func RegisterType added in v0.8.0

func RegisterType(desc TypeDesc) error

RegisterType registers a type.

func SokoDesc added in v0.9.0

func SokoDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)

SokoDesc writes a Soko description to f for the rank, best, and unused cards.

func StudBlinds added in v0.8.0

func StudBlinds() []string

StudBlinds returns the Stud blind names.

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"

	"github.com/cardrank/cardrank"
)

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

[3s 4c 5c Ah 2d]

func FromIndex

func FromIndex(i int) Card

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

func FromRune

func FromRune(r rune) Card

FromRune creates a card from a unicode playing card rune.

Example
package main

import (
	"fmt"

	"github.com/cardrank/cardrank"
)

func main() {
	c := cardrank.FromRune('🂡')
	fmt.Printf("%b\n", c)
}
Output:

A♠

func FromString

func FromString(s string) Card

FromString creates a card from a string.

Example
package main

import (
	"fmt"

	"github.com/cardrank/cardrank"
)

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

Ace of Hearts (A♥)

func Must

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

Must creates a Card slice from v.

See Parse for overview of accepted string representations of cards.

Example
package main

import (
	"fmt"

	"github.com/cardrank/cardrank"
)

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

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

func New

func New(rank Rank, suit Suit) Card

New creates a card for the specified rank and suit.

func Parse

func Parse(strs ...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 (Card) AceRank added in v0.10.0

func (c Card) AceRank() int

AceRank returns the Ace low index of the card.

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
F - straight flush name for the rank

func (Card) Index

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 CardFormatter added in v0.8.0

type CardFormatter []Card

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

func (CardFormatter) Format added in v0.8.0

func (v CardFormatter) Format(f fmt.State, verb rune)

Format satisfies the fmt.Formatter interface.

type Dealer added in v0.8.0

type Dealer struct {
	TypeDesc
	Count   int
	Deck    *Deck
	Active  map[int]bool
	Discard []Card
	Runs    []*Run
	Results []*Result
	// contains filtered or unexported fields
}

Dealer maintains deal state for a type, streets, deck, positions, runs, results, and wins.

Example (FusionHiLo)
package main

import (
	"fmt"
	"math/rand"

	"github.com/cardrank/cardrank"
)

func main() {
	for i, game := range []struct {
		seed     int64
		players  int
		change   byte
		runs     int
		inactive []int
	}{
		{566, 2, 't', 3, nil},
		{1039, 5, 'f', 2, []int{0, 3, 4}},
		{2087, 6, 't', 2, []int{0, 5}},
	} {
		// note: use a real random source
		r := rand.New(rand.NewSource(game.seed))
		fmt.Printf("------ FusionHiLo %d ------\n", i+1)
		// setup dealer and display
		d := cardrank.FusionHiLo.Dealer(r, 1, game.players)
		// display deck
		deck := d.Deck.All()
		fmt.Printf("Deck:\n")
		for i := 0; i < len(deck); i += 8 {
			n := i + 8
			if n > len(deck) {
				n = len(deck)
			}
			fmt.Printf("  %v\n", deck[i:n])
		}
		for d.Next() {
			fmt.Printf("%s\n", d)
			rn, run := d.Run()
			fmt.Printf("  Run %d:\n", rn)
			// display pockets
			if d.HasPocket() {
				for i := 0; i < game.players; i++ {
					fmt.Printf("    %d: %v\n", i, run.Pockets[i])
				}
			}
			// display discarded cards
			if v := d.Discarded(); len(v) != 0 {
				fmt.Printf("    Discard: %v\n", v)
			}
			// display board
			if d.HasBoard() {
				fmt.Printf("    Board: %v\n", run.Hi)
				if d.Double {
					fmt.Printf("           %v\n", run.Lo)
				}
			}
			// change runs, deactivate positions
			if d.Id() == game.change {
				if valid := d.ChangeRuns(game.runs); !valid {
					panic("unable to change runs")
				}
				// deactivate
				d.Deactivate(game.inactive...)
			}
		}
		fmt.Printf("Showdown:\n")
		for d.NextResult() {
			n, res := d.Result()
			fmt.Printf("  Run %d:\n", n)
			for i := 0; i < game.players; i++ {
				if d.Active[i] {
					hi := res.Evals[i].Desc(false)
					fmt.Printf("    %d: %v %v %s\n", i, hi.Best, hi.Unused, hi)
					if d.Low || d.Double {
						lo := res.Evals[i].Desc(true)
						fmt.Printf("       %v %v %s\n", lo.Best, lo.Unused, lo)
					}
				} else {
					fmt.Printf("    %d: inactive\n", i)
				}
			}
			hi, lo := res.Win()
			fmt.Printf("    Result: %d with %s\n", hi, hi)
			if lo != nil {
				fmt.Printf("            %d with %s\n", lo, lo)
			}
		}
	}
}
Output:

------ FusionHiLo 1 ------
Deck:
  [4h Qs 5c 4c 5d 8d 8c As]
  [Ks 6h 7s 9s 3h Ac Js 9h]
  [4s 7d 2h 8s 2s Ad Ts Qh]
  [Qc 5h 6s 9d 9c 6c Kd 2d]
  [3s Ah Kh 5s Jd Jc 2c Td]
  [3c Jh 8h 4d Th 7c 7h 3d]
  [6d Tc Kc Qd]
p: Pre-Flop (p: 2)
  Run 0:
    0: [4h 5c]
    1: [Qs 4c]
f: Flop (p: 1, d: 1, b: 3)
  Run 0:
    0: [4h 5c 5d]
    1: [Qs 4c 8d]
    Discard: [8c]
    Board: [As Ks 6h]
t: Turn (p: 1, d: 1, b: 1)
  Run 0:
    0: [4h 5c 5d 7s]
    1: [Qs 4c 8d 9s]
    Discard: [3h]
    Board: [As Ks 6h Ac]
r: River (d: 1, b: 1)
  Run 0:
    Discard: [Js]
    Board: [As Ks 6h Ac 9h]
r: River (d: 1, b: 1)
  Run 1:
    Discard: [4s]
    Board: [As Ks 6h Ac 7d]
r: River (d: 1, b: 1)
  Run 2:
    Discard: [2h]
    Board: [As Ks 6h Ac 8s]
Showdown:
  Run 0:
    0: [Ac As 5c 5d Ks] [9h 7s 6h 4h] Two Pair, Aces over Fives, kicker King
       [] [] None
    1: [Ac As 9h 9s Qs] [Ks 8d 6h 4c] Two Pair, Aces over Nines, kicker Queen
       [] [] None
    Result: 1 scoops with Two Pair, Aces over Nines, kicker Queen
  Run 1:
    0: [Ac As 7d 7s 5c] [Ks 6h 5d 4h] Two Pair, Aces over Sevens, kicker Five
       [7d 6h 5c 4h As] [Ac Ks 7s 5d] Seven, Six, Five, Four, Ace-low
    1: [Ac As Ks Qs 9s] [8d 7d 6h 4c] Pair, Aces, kickers King, Queen, Nine
       [8d 7d 6h 4c As] [Ac Ks Qs 9s] Eight, Seven, Six, Four, Ace-low
    Result: 0 wins with Two Pair, Aces over Sevens, kicker Five
            0 wins with Seven, Six, Five, Four, Ace-low
  Run 2:
    0: [Ac As 5c 5d Ks] [8s 7s 6h 4h] Two Pair, Aces over Fives, kicker King
       [8s 6h 5c 4h As] [Ac Ks 7s 5d] Eight, Six, Five, Four, Ace-low
    1: [As Ks Qs 9s 8s] [Ac 8d 6h 4c] Flush, Ace-high, kickers King, Queen, Nine, Eight
       [] [] None
    Result: 1 wins with Flush, Ace-high, kickers King, Queen, Nine, Eight
            0 wins with Eight, Six, Five, Four, Ace-low
------ FusionHiLo 2 ------
Deck:
  [2h 5s Ac Ts Kd 5h 6d Th]
  [2s 6s 7c 4h 8c 9h Ah 8s]
  [Kc 9d 5c 5d As 4d 3h 2c]
  [7s 8h 4c 7d 8d Qs 3c 7h]
  [Jc Jh 6c 3s Qd 9c 4s 3d]
  [Ks Ad Qc Td Tc Qh Js 6h]
  [2d 9s Jd Kh]
p: Pre-Flop (p: 2)
  Run 0:
    0: [2h 5h]
    1: [5s 6d]
    2: [Ac Th]
    3: [Ts 2s]
    4: [Kd 6s]
f: Flop (p: 1, d: 1, b: 3)
  Run 0:
    0: [2h 5h 7c]
    1: [5s 6d 4h]
    2: [Ac Th 8c]
    3: [Ts 2s 9h]
    4: [Kd 6s Ah]
    Discard: [8s]
    Board: [Kc 9d 5c]
t: Turn (p: 1, d: 1, b: 1)
  Run 0:
    0: [2h 5h 7c 5d]
    1: [5s 6d 4h As]
    2: [Ac Th 8c 4d]
    3: [Ts 2s 9h 3h]
    4: [Kd 6s Ah 2c]
    Discard: [7s]
    Board: [Kc 9d 5c 8h]
t: Turn (p: 1, d: 1, b: 1)
  Run 1:
    0: [2h 5h 7c 4c]
    1: [5s 6d 4h 7d]
    2: [Ac Th 8c 8d]
    3: [Ts 2s 9h Qs]
    4: [Kd 6s Ah 3c]
    Discard: [7h]
    Board: [Kc 9d 5c Jc]
r: River (d: 1, b: 1)
  Run 0:
    Discard: [Jh]
    Board: [Kc 9d 5c 8h 6c]
r: River (d: 1, b: 1)
  Run 1:
    Discard: [3s]
    Board: [Kc 9d 5c Jc Qd]
Showdown:
  Run 0:
    0: inactive
    1: [6c 6d 5c 5s Kc] [As 9d 8h 4h] Two Pair, Sixes over Fives, kicker King
       [8h 6c 5c 4h As] [Kc 9d 6d 5s] Eight, Six, Five, Four, Ace-low
    2: [Ac Kc 8c 6c 5c] [Th 9d 8h 4d] Flush, Ace-high, kickers King, Eight, Six, Five
       [8h 6c 5c 4d Ac] [Kc Th 9d 8c] Eight, Six, Five, Four, Ace-low
    3: inactive
    4: inactive
    Result: 2 wins with Flush, Ace-high, kickers King, Eight, Six, Five
            1, 2 split with Eight, Six, Five, Four, Ace-low
  Run 1:
    0: inactive
    1: [5c 5s Kc Qd 7d] [Jc 9d 6d 4h] Pair, Fives, kickers King, Queen, Seven
       [] [] None
    2: [Ac Kc Jc 8c 5c] [Qd Th 9d 8d] Flush, Ace-high, kickers King, Jack, Eight, Five
       [] [] None
    3: inactive
    4: inactive
    Result: 2 scoops with Flush, Ace-high, kickers King, Jack, Eight, Five
------ FusionHiLo 3 ------
Deck:
  [8h 5d 5c 3h Jc 6h Kd Td]
  [6s As 7c 6c 2c Jd 9h 8c]
  [7s 5s 8d Tc 3s Kc Qh Qd]
  [7d Ks Jh 4s 9s 4h Th Qc]
  [Ah 2d Ts 7h 4c Qs Kh 6d]
  [9d 2s Js 3d 5h 2h Ac Ad]
  [3c 8s 4d 9c]
p: Pre-Flop (p: 2)
  Run 0:
    0: [8h Kd]
    1: [5d Td]
    2: [5c 6s]
    3: [3h As]
    4: [Jc 7c]
    5: [6h 6c]
f: Flop (p: 1, d: 1, b: 3)
  Run 0:
    0: [8h Kd 2c]
    1: [5d Td Jd]
    2: [5c 6s 9h]
    3: [3h As 8c]
    4: [Jc 7c 7s]
    5: [6h 6c 5s]
    Discard: [8d]
    Board: [Tc 3s Kc]
t: Turn (p: 1, d: 1, b: 1)
  Run 0:
    0: [8h Kd 2c Qh]
    1: [5d Td Jd Qd]
    2: [5c 6s 9h 7d]
    3: [3h As 8c Ks]
    4: [Jc 7c 7s Jh]
    5: [6h 6c 5s 4s]
    Discard: [9s]
    Board: [Tc 3s Kc 4h]
r: River (d: 1, b: 1)
  Run 0:
    Discard: [Th]
    Board: [Tc 3s Kc 4h Qc]
r: River (d: 1, b: 1)
  Run 1:
    Discard: [Ah]
    Board: [Tc 3s Kc 4h 2d]
Showdown:
  Run 0:
    0: inactive
    1: [Qc Qd Tc Td Kc] [Jd 5d 4h 3s] Two Pair, Queens over Tens, kicker King
       [] [] None
    2: [Kc Qc Tc 9h 7d] [6s 5c 4h 3s] King-high, kickers Queen, Ten, Nine, Seven
       [] [] None
    3: [Kc Ks 3h 3s Qc] [As Tc 8c 4h] Two Pair, Kings over Threes, kicker Queen
       [] [] None
    4: [Kc Qc Jc Tc 7c] [Jh 7s 4h 3s] Flush, King-high, kickers Queen, Jack, Ten, Seven
       [] [] None
    5: inactive
    Result: 4 scoops with Flush, King-high, kickers Queen, Jack, Ten, Seven
  Run 1:
    0: inactive
    1: [Tc Td Kc Qd 4h] [Jd 5d 3s 2d] Pair, Tens, kickers King, Queen, Four
       [] [] None
    2: [6s 5c 4h 3s 2d] [Kc Tc 9h 7d] Straight, Six-high
       [6s 5c 4h 3s 2d] [Kc Tc 9h 7d] Six, Five, Four, Three, Two-low
    3: [Kc Ks 3h 3s Tc] [As 8c 4h 2d] Two Pair, Kings over Threes, kicker Ten
       [8c 4h 3s 2d As] [Kc Ks Tc 3h] Eight, Four, Three, Two, Ace-low
    4: [Jc Jh Kc Tc 4h] [7c 7s 3s 2d] Pair, Jacks, kickers King, Ten, Four
       [] [] None
    5: inactive
    Result: 2 wins with Straight, Six-high
            2 wins with Six, Five, Four, Three, Two-low

func NewDealer added in v0.8.0

func NewDealer(desc TypeDesc, deck *Deck, count int) *Dealer

NewDealer creates a new dealer for a provided deck and pocket count.

func NewShuffledDealer added in v0.8.0

func NewShuffledDealer(desc TypeDesc, shuffler Shuffler, shuffles, count int) *Dealer

NewShuffledDealer creates a new deck and dealer, shuffling the deck multiple times and returning the dealer with the created deck and pocket count.

func (*Dealer) Board added in v0.8.0

func (d *Dealer) Board() int

Board returns the number of board cards to be dealt on the street.

func (*Dealer) BoardDiscard added in v0.9.0

func (d *Dealer) BoardDiscard() int

BoardDiscard returns the number of board cards to be discarded prior to dealing a board on the current street.

func (*Dealer) ChangeRuns added in v0.9.2

func (d *Dealer) ChangeRuns(runs int) bool

ChangeRuns changes the number of runs, returning true if successful.

func (*Dealer) Deactivate added in v0.9.0

func (d *Dealer) Deactivate(positions ...int)

Deactivate deactivates positions, which will not be dealt further cards and will not be included during eval.

func (*Dealer) Deal added in v0.8.0

func (d *Dealer) Deal(run int)

Deal deals pocket and board cards for the run.

func (*Dealer) Discarded added in v0.9.0

func (d *Dealer) Discarded() []Card

Discarded returns the number of pocket ard board cards discarded on the current street.

func (*Dealer) Eval added in v0.9.2

func (d *Dealer) Eval(run int) *Result

Eval evals the run, returning the result.

func (*Dealer) Format added in v0.8.0

func (d *Dealer) Format(f fmt.State, verb rune)

Format satisfies the fmt.Formatter interface.

func (*Dealer) HasActive added in v0.9.0

func (d *Dealer) HasActive() bool

HasActive returns true when there is more than 1 active positions.

func (*Dealer) HasBoard added in v0.9.0

func (d *Dealer) HasBoard() bool

HasBoard returns true when one or more board cards are dealt for the street.

func (*Dealer) HasNext added in v0.10.2

func (d *Dealer) HasNext() bool

HasNext returns true when there is one or more remaining streets.

func (*Dealer) HasPocket added in v0.9.0

func (d *Dealer) HasPocket() bool

HasPocket returns true when one or more pocket cards are dealt for the street.

func (*Dealer) Id added in v0.9.0

func (d *Dealer) Id() byte

Id returns the street id.

func (*Dealer) Inactive added in v0.9.0

func (d *Dealer) Inactive() []int

Inactive returns the inactive positions.

func (*Dealer) Next added in v0.8.0

func (d *Dealer) Next() bool

Next iterates the run and the street, discarding cards prior to dealing additional pocket and board cards for each run. Returns true when there are additional runs or streets, and having at least 2 active positions for a Type having more than 1 player.

func (*Dealer) NextId added in v0.9.0

func (d *Dealer) NextId() byte

NextId returns the next street id.

func (*Dealer) NextResult added in v0.9.0

func (d *Dealer) NextResult() bool

NextResult iterates the next result.

func (*Dealer) Pocket added in v0.8.0

func (d *Dealer) Pocket() int

Pocket returns the number of pocket cards to be dealt on the street.

func (*Dealer) PocketDiscard added in v0.9.0

func (d *Dealer) PocketDiscard() int

PocketDiscard returns the number of cards to be discarded prior to dealing pockets on the current street.

func (*Dealer) PocketDraw added in v0.9.0

func (d *Dealer) PocketDraw() int

PocketDraw returns the number of pocket cards that can be drawn on current the street.

func (*Dealer) PocketUp added in v0.9.0

func (d *Dealer) PocketUp() int

PocketUp returns the number of pocket cards to be turned up on the current street.

func (*Dealer) Reset added in v0.8.0

func (d *Dealer) Reset()

Reset resets the iterator to i.

func (*Dealer) Result added in v0.9.0

func (d *Dealer) Result() (int, *Result)

Result returns the current result.

func (*Dealer) Run added in v0.9.2

func (d *Dealer) Run() (int, *Run)

Run returns the current street and run.

type Deck

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

Deck is a set of playing cards.

func DeckOf added in v0.9.0

func DeckOf(cards ...Card) *Deck

DeckOf creates a deck for the provided cards.

func NewDeck

func NewDeck() *Deck

NewDeck creates a French deck of 52 unshuffled cards.

func NewShoe added in v0.9.0

func NewShoe(count int) *Deck

NewShoe creates a card shoe with multiple sets of 52 unshuffled cards.

func (*Deck) All added in v0.9.0

func (d *Deck) All() []Card

All returns a copy of all cards in the deck, without advancing.

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"

	"github.com/cardrank/cardrank"
)

func main() {
	d := cardrank.NewDeck()
	// note: use a real random source
	r := rand.New(rand.NewSource(52))
	d.Shuffle(r, 1)
	v := d.Draw(7)
	fmt.Printf("%b\n", v)
}
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) Limit added in v0.9.0

func (d *Deck) Limit(limit int)

Limit limits the cards for the deck, for use with card shoes composed of more than one deck of cards.

func (*Deck) Remaining

func (d *Deck) Remaining() int

Remaining returns the number of remaining cards in the deck.

func (*Deck) Reset added in v0.8.0

func (d *Deck) Reset()

Reset resets the deck.

func (*Deck) Shuffle

func (d *Deck) Shuffle(shuffler Shuffler, shuffles int)

Shuffle shuffles the deck's cards using the shuffler multiple times.

type DeckType added in v0.9.0

type DeckType uint8

DeckType is a deck type.

func (DeckType) Desc added in v0.9.0

func (typ DeckType) Desc(short bool) string

Desc returns the deck description.

func (DeckType) Format added in v0.9.0

func (typ DeckType) Format(f fmt.State, verb rune)

Format satisfies the fmt.Formatter interface.

func (DeckType) Name added in v0.9.0

func (typ DeckType) Name() string

Name returns the deck name.

func (DeckType) New added in v0.9.0

func (typ DeckType) New() *Deck

New returns a new deck for the deck type.

func (DeckType) Ordinal added in v0.9.0

func (typ DeckType) Ordinal() int

Ordinal returns the ordinal for the deck.

func (DeckType) Shoe added in v0.9.0

func (typ DeckType) Shoe(count int) *Deck

Shoe creates a card shoe composed of count number of decks of unshuffled cards.

func (DeckType) Unshuffled added in v0.9.0

func (typ DeckType) Unshuffled() []Card

Unshuffled returns a set of unshuffled cards for the deck type.

type Desc added in v0.9.0

type Desc struct {
	Type   DescType
	Rank   EvalRank
	Best   []Card
	Unused []Card
}

Desc wraps describing results.

func (*Desc) Format added in v0.9.0

func (desc *Desc) Format(f fmt.State, verb rune)

Format satisfies the fmt.Stringer interface.

type DescType added in v0.9.0

type DescType uint8

DescType is a description type.

const (
	DescCactus    DescType = 0
	DescFlushOver DescType = 'f'
	DescSoko      DescType = 'k'
	DescLow       DescType = 'l'
	DescLowball   DescType = 'b'
	DescRazz      DescType = 'r'
)

Desc types.

func (DescType) Byte added in v0.9.0

func (typ DescType) Byte() byte

Byte returns the desc type as a byte.

func (DescType) Desc added in v0.9.0

func (typ DescType) Desc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)

Desc writes a description for the verb to f.

func (DescType) Format added in v0.9.0

func (typ DescType) Format(f fmt.State, verb rune)

Format satisfies the fmt.Formatter interface.

func (DescType) Name added in v0.9.0

func (typ DescType) Name() string

Name returns the desc type's name.

type Error

type Error string

Error is a error.

const (
	// ErrInvalidId is the invalid id error.
	ErrInvalidId Error = "invalid id"
	// ErrMismatchedIdAndType is the mismatched id and type error.
	ErrMismatchedIdAndType Error = "mismatched id and type"
	// ErrInvalidCard is the invalid card error.
	ErrInvalidCard Error = "invalid card"
	// 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 Eval added in v0.9.0

type Eval struct {
	Type     Type
	HiRank   EvalRank
	HiBest   []Card
	HiUnused []Card
	LoRank   EvalRank
	LoBest   []Card
	LoUnused []Card
}

Eval contains eval info.

func EvalOf added in v0.9.0

func EvalOf(typ Type) *Eval

EvalOf creates a eval for the type.

func (*Eval) Comp added in v0.9.0

func (ev *Eval) Comp(b *Eval, low bool) int

Comp compares hi or lo eval against b.

func (*Eval) Desc added in v0.9.0

func (ev *Eval) Desc(low bool) *Desc

Desc returns the hi or low desc for the eval.

func (*Eval) Eval added in v0.9.0

func (ev *Eval) Eval(pocket, board []Card)

Eval evaluates the pocket, board.

func (*Eval) Format added in v0.9.0

func (ev *Eval) Format(f fmt.State, verb rune)

Format satisfies the fmt.Formatter interface.

func (*Eval) Hi5 added in v0.10.0

func (ev *Eval) Hi5(f RankFunc, v []Card)

Hi5 evalutes the 5 cards in v, using f.

func (*Eval) Hi6 added in v0.10.0

func (ev *Eval) Hi6(f RankFunc, v []Card)

Hi6 evalutes the 6 cards in v, using f.

func (*Eval) Hi7 added in v0.10.0

func (ev *Eval) Hi7(f RankFunc, v []Card)

Hi7 evalutes the 7 cards in v, using f.

func (*Eval) HiLo23 added in v0.10.0

func (ev *Eval) HiLo23(hi, lo RankFunc, c0, c1 Card, b []Card, max EvalRank)

HiLo23 evalutes the 2 cards c0, c1 and the 3 in b, using hi, lo.

func (*Eval) HiLo24 added in v0.10.0

func (ev *Eval) HiLo24(hi, lo RankFunc, c0, c1 Card, b []Card, max EvalRank)

HiLo24 evalutes the 2 cards c0, c1 and the 4 in b, using hi, lo.

func (*Eval) HiLo25 added in v0.10.0

func (ev *Eval) HiLo25(hi, lo RankFunc, c0, c1 Card, b []Card, max EvalRank)

HiLo25 evalutes the 2 cards c0, c1 and the 5 in b, using hi, lo.

func (*Eval) HiLo5 added in v0.10.0

func (ev *Eval) HiLo5(hi, lo RankFunc, v []Card, max EvalRank)

HiLo5 evaluates the 5 cards in v, using hi, lo.

func (*Eval) HiLo6 added in v0.10.0

func (ev *Eval) HiLo6(hi, lo RankFunc, v []Card, max EvalRank)

HiLo6 evalutes the 6 cards in v, using hi, lo.

func (*Eval) HiLo7 added in v0.10.0

func (ev *Eval) HiLo7(hi, lo RankFunc, v []Card, max EvalRank)

HiLo7 evalutes the 7 cards in v, using hi, lo.

func (*Eval) Init added in v0.9.0

func (ev *Eval) Init(n, m int, low bool)

Init inits best, unused.

func (*Eval) Max5 added in v0.10.0

func (ev *Eval) Max5(f RankFunc, v []Card, max EvalRank, low bool)

Max5 evaluates the 5 cards in v, using f, storing only if the rank is below max.

func (*Eval) Max6 added in v0.10.0

func (ev *Eval) Max6(f RankFunc, v []Card, max EvalRank, low bool)

Max6 evaluates the 6 cards in v, using f, storing only if the rank is below max.

func (*Eval) Max7 added in v0.10.0

func (ev *Eval) Max7(f RankFunc, v []Card, max EvalRank, low bool)

Max7 evaluates the 7 cards in v, using f, storing only if the rank is below max.

type EvalFunc added in v0.8.0

type EvalFunc func(*Eval, []Card, []Card)

EvalFunc is a rank eval func.

func NewBadugiEval added in v0.8.0

func NewBadugiEval() EvalFunc

NewBadugiEval creates a Badugi rank eval func.

func NewCactusEval added in v0.9.0

func NewCactusEval(low bool) EvalFunc

NewCactusEval creates a Cactus rank eval func.

func NewDallasEval added in v0.10.0

func NewDallasEval(hi RankFunc, straightHigh Rank, low bool, inv func(EvalRank) EvalRank) EvalFunc

NewDallasEval creates a Dallas rank eval func.

Uses pocket of 2 and any 3 from a board of 3, 4, or 5 to make a best-5.

func NewEval added in v0.10.0

func NewEval(f RankFunc) EvalFunc

NewEval returns a eval func that ranks 5, 6, or 7 cards using f. The returned eval func will store the results on an eval's hi.

func NewHoustonEval added in v0.10.0

func NewHoustonEval(hi RankFunc, straightHigh Rank, inv func(EvalRank) EvalRank) EvalFunc

NewHoustonEval creates a Houston rank eval func.

Uses pocket of any 2 from 3, and any 3 from a board of 3, 4, or 5 to make a best-5.

func NewHybridEval added in v0.10.0

func NewHybridEval(low, normalize bool) EvalFunc

NewHybridEval creates a hybrid Cactus and TwoPlusTwo eval rank func, using the package's RankCactus eval func for 5 and 6 cards, and a TwoPlusTwo eval func for 7 cards. Gives optimal performance when evaluating best-5 of any 5, 6, or 7 cards from a pocket and board.

func NewJacksOrBetterEval added in v0.10.0

func NewJacksOrBetterEval(low bool) EvalFunc

NewJacksOrBetterEval creates a JacksOrBetter rank eval func.

func NewLowballEval added in v0.9.0

func NewLowballEval() EvalFunc

NewLowballEval creates a Lowball rank eval func.

func NewManilaEval added in v0.9.0

func NewManilaEval() EvalFunc

NewManilaEval creates a Manila rank eval func.

func NewMaxEval added in v0.10.0

func NewMaxEval(f RankFunc, max EvalRank, low bool) EvalFunc

NewMaxEval returns a eval func that ranks 5, 6, or 7 cards using f and max. The returned eval func will store results on an eval's hi if it is lower than max.

func NewModifiedEval added in v0.10.2

func NewModifiedEval(hi RankFunc, straightHigh Rank, low bool, inv func(EvalRank) EvalRank) EvalFunc

NewModifiedEval creates a modified Cactus eval.

func NewOmahaEval added in v0.8.0

func NewOmahaEval(low bool) EvalFunc

NewOmahaEval creates a Omaha rank eval func.

func NewOmahaFiveEval added in v0.8.0

func NewOmahaFiveEval(low bool) EvalFunc

NewOmahaFiveEval creates a new OmahaFive rank eval func.

func NewOmahaSixEval added in v0.8.0

func NewOmahaSixEval(low bool) EvalFunc

NewOmahaSixEval creates a new OmahaSix rank eval func.

func NewRazzEval added in v0.8.0

func NewRazzEval() EvalFunc

NewRazzEval creates a Razz rank eval func.

func NewShortEval added in v0.8.0

func NewShortEval() EvalFunc

NewShortEval creates a Short rank eval func.

func NewSokoEval added in v0.9.0

func NewSokoEval(low bool) EvalFunc

NewSokoEval creates a Soko rank eval func.

func NewSpanishEval added in v0.10.0

func NewSpanishEval() EvalFunc

NewSpanishEval creates a Spanish rank eval func.

func NewSplitEval added in v0.10.0

func NewSplitEval(hi, lo RankFunc, max EvalRank) EvalFunc

NewSplitEval returns a eval func that ranks 5, 6, or 7 cards using hi, lo and max. The returned eval func will store results on an eval's hi and lo depending on the result of hi and lo, respectively. Will only store a lo value if it is lower than max.

type EvalRank added in v0.9.0

type EvalRank uint16

EvalRank is a poker eval rank.

Ranks are ordered low-to-high.

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

Poker eval rank values.

See: https://archive.is/G6GZg

func Cactus added in v0.8.0

func Cactus(c0, c1, c2, c3, c4 Card) EvalRank

Cactus is a Cactus Kev rank eval func, using lookup maps generated on the fly.

See: https://archive.is/G6GZg

func CactusFast added in v0.8.0

func CactusFast(c0, c1, c2, c3, c4 Card) EvalRank

CactusFast is a fast Cactus Kev rank eval func, implementing Paul Senzee's perfect hash lookup.

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

func RankAceFiveLow added in v0.10.0

func RankAceFiveLow(mask EvalRank, c0, c1, c2, c3, c4 Card) EvalRank

RankAceFiveLow is a A-to-5 low eval rank func. Aces are low, straights and flushes do not count.

func RankEightOrBetter added in v0.8.0

func RankEightOrBetter(c0, c1, c2, c3, c4 Card) EvalRank

RankEightOrBetter is a 8-or-better low eval rank func. Aces are low, straights and flushes do not count.

func RankLowball added in v0.9.0

func RankLowball(c0, c1, c2, c3, c4 Card) EvalRank

RankLowball is a 2-to-7 low eval rank func. Aces are high, straights and flushes count.

Works by adding 2 additional ranks for Ace-high straight flushes and straights.

func RankManila added in v0.10.0

func RankManila(c0, c1, c2, c3, c4 Card) EvalRank

RankManila is a Manila rank eval func.

func RankRazz added in v0.8.0

func RankRazz(c0, c1, c2, c3, c4 Card) EvalRank

RankRazz is a Razz (A-to-5) low eval rank func. Aces are low, straights and flushes do not count.

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

func RankShort added in v0.10.0

func RankShort(c0, c1, c2, c3, c4 Card) EvalRank

RankShort is a Short rank eval func.

func RankSoko added in v0.10.0

func RankSoko(c0, c1, c2, c3, c4 Card) EvalRank

RankSoko is a Soko eval rank func.

Has similar orders to Cactus, adding a Four Flush and Four Straight that beat Pairs and Nothing:

Straight Flush
Four of a Kind
Full House
Flush
Straight
Three of a Kind
Two Pair
Four Flush
Four Straight
Pair
Nothing

func RankSpanish added in v0.10.0

func RankSpanish(c0, c1, c2, c3, c4 Card) EvalRank

RankSpanish is a Spanish rank eval func.

func (EvalRank) Fixed added in v0.9.0

func (r EvalRank) Fixed() EvalRank

Fixed converts a relative eval rank to a fixed eval rank.

func (EvalRank) FromFlushOver added in v0.10.0

func (r EvalRank) FromFlushOver() EvalRank

FromFlushOver changes a rank from a Flush Over a Full House rank to a Cactus rank.

FullHouse: FullHouse(322) - FourOfAKind(166) == 156
Flush:     Flush(1599)    - FullHouse(322)   == 1277

func (EvalRank) FromLowball added in v0.10.0

func (r EvalRank) FromLowball() EvalRank

FromLowball converts a Lowball rank to a Cactus rank.

See EvalRank.ToLowball for a description of the operations performed.

func (EvalRank) Name added in v0.9.0

func (r EvalRank) Name() string

Name returns the eval rank name.

func (EvalRank) String added in v0.9.0

func (r EvalRank) String() string

String satisfies the fmt.Stringer interface.

func (EvalRank) ToFlushOver added in v0.10.0

func (r EvalRank) ToFlushOver() EvalRank

ToFlushOver changes a Cactus rank to a Flush Over a Full House rank.

FullHouse: FullHouse(322) - FourOfAKind(166) == 156
Flush:     Flush(1599)    - FullHouse(322)   == 1277

func (EvalRank) ToLowball added in v0.10.0

func (r EvalRank) ToLowball() EvalRank

ToLowball converts a Cactus rank to a Lowball rank, by inverting the rank and converting the lowest Straight and Straight Flushes (5-4-3-2-A) to different ranks.

Changes the rank in the following ways:

Moves lowest Straight Flush (10) to lowest Ace Flush (811)
Moves any rank between Straight Flush (10) < r <= lowest Ace Flush (811) down 1 rank
Moves lowest Straight (1609) to lowest Ace Nothing (6678)
Moves any rank between Straight (1609) < r <= lowest Ace Nothing (6678) down 1 rank
Inverts the rank (Nothing - r + 1)

type EvalType added in v0.9.0

type EvalType uint8

EvalType is a eval type.

const (
	EvalCactus        EvalType = 0
	EvalJacksOrBetter EvalType = 'j'
	EvalShort         EvalType = 't'
	EvalManila        EvalType = 'm'
	EvalSpanish       EvalType = 'p'
	EvalDallas        EvalType = 'a'
	EvalHouston       EvalType = 'u'
	EvalOmaha         EvalType = 'o'
	EvalOmahaFive     EvalType = 'v'
	EvalOmahaSix      EvalType = 'i'
	EvalSoko          EvalType = 'k'
	EvalLowball       EvalType = 'l'
	EvalRazz          EvalType = 'r'
	EvalBadugi        EvalType = 'b'
)

Eval types.

func (EvalType) Byte added in v0.9.0

func (typ EvalType) Byte() byte

Byte returns the eval type as a byte.

func (EvalType) Format added in v0.9.0

func (typ EvalType) Format(f fmt.State, verb rune)

Format satisfies the fmt.Formatter interface.

func (EvalType) Name added in v0.9.0

func (typ EvalType) Name() string

Name returns the eval type's name.

func (EvalType) New added in v0.9.0

func (typ EvalType) New(low bool) EvalFunc

New creates the eval type.

type ParseError added in v0.7.1

type ParseError struct {
	S   string
	N   int
	I   int
	Err error
}

ParseError is a parse error.

func (*ParseError) Error added in v0.7.1

func (err *ParseError) Error() string

Error satisfies the [error] interface.

func (*ParseError) Unwrap added in v0.7.1

func (err *ParseError) Unwrap() error

Unwrap satisfies the errors.Unwrap 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

RankFromRune returns the card rank for the rune.

func (Rank) Byte

func (rank Rank) Byte() byte

Byte returns the byte representation for the card rank.

func (Rank) Index

func (rank Rank) Index() int

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

func (Rank) Name

func (rank Rank) Name() string

Name returns the name of the card rank.

func (Rank) PluralName

func (rank Rank) PluralName() string

PluralName returns the plural name of the card rank.

func (Rank) StraightFlushName added in v0.10.0

func (rank Rank) StraightFlushName() string

StraightFlushName returns the name for a Straight Flush of rank.

func (Rank) String

func (rank Rank) String() string

String satisfies the fmt.Stringer interface.

type RankFunc added in v0.8.0

type RankFunc func(c0, c1, c2, c3, c4 Card) EvalRank

RankFunc returns the eval rank of 5 cards.

var (
	// RankCactus is the default Cactus Kev func.
	RankCactus RankFunc
)

type Result added in v0.9.0

type Result struct {
	Evals   []*Eval
	HiOrder []int
	HiPivot int
	LoOrder []int
	LoPivot int
}

Result contains dealer eval results.

func (*Result) Win added in v0.9.0

func (res *Result) Win() (*Win, *Win)

Win returns the hi and lo win.

type Run added in v0.9.2

type Run struct {
	Pockets [][]Card
	Hi      []Card
	Lo      []Card
}

Run holds pockets, and a hi/lo board for a deal.

func NewRun added in v0.9.2

func NewRun(count int) *Run

NewRun creates a new run for the pocket count.

func (*Run) Dupe added in v0.9.2

func (run *Run) Dupe() *Run

Dupe creates a duplicate of the hi and lo portions of the board, excluding any eval info collected.

func (*Run) Eval added in v0.9.2

func (run *Run) Eval(typ Type, active map[int]bool, double bool) []*Eval

Eval returns the evals for the run.

type Shuffler added in v0.5.0

type Shuffler interface {
	Shuffle(int, func(int, int))
}

Shuffler is an interface for a deck shuffler. Compatible with math/rand.Rand's Shuffle method.

type StreetDesc added in v0.8.0

type StreetDesc struct {
	// Id is the id of the street.
	Id byte
	// Name is the name of the street.
	Name string
	// Pocket is the count of cards to deal.
	Pocket int
	// PocketUp is the count of cards to reveal.
	PocketUp int
	// PocketDiscard is the count of cards to discard before pockets dealt.
	PocketDiscard int
	// PocketDraw is the count of cards to draw.
	PocketDraw int
	// Board is the count of board cards to deal.
	Board int
	// BoardDiscard is the count of cards to discard before board dealt.
	BoardDiscard int
}

StreetDesc is a type's street description.

func HoldemStreets added in v0.8.0

func HoldemStreets(pocket, discard, flop, turn, river int) []StreetDesc

HoldemStreets creates Holdem streets for the pre-flop, flop, turn, and river.

func NumberedStreets added in v0.8.0

func NumberedStreets(pockets ...int) []StreetDesc

NumberedStreets returns numbered streets (ante, first, second, ...).

func StudFiveStreets added in v0.10.0

func StudFiveStreets() []StreetDesc

StudFiveStreets creates Stud streets for the ante, third street, fourth street, and river.

func StudStreets added in v0.8.0

func StudStreets() []StreetDesc

StudStreets creates Stud streets for the ante, third street, fourth street, fifth street, sixth street and river.

func (StreetDesc) Desc added in v0.9.0

func (desc StreetDesc) Desc() string

Desc returns a description of the street.

type StreetOption added in v0.8.0

type StreetOption func(int, *StreetDesc)

StreetOption is a street option.

func WithStreetPocket added in v0.8.0

func WithStreetPocket(street, pocket int) StreetOption

WithStreetPocket is a street option to set the pocket for a street.

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

SuitFromRune returns the card suit for the rune.

func (Suit) Byte

func (suit Suit) Byte() byte

Byte returns the byte representation for the card suit.

func (Suit) Index

func (suit Suit) Index() int

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

func (Suit) Name

func (suit Suit) Name() string

Name returns the name of the card suit.

func (Suit) PluralName

func (suit Suit) PluralName() string

PluralName returns the plural name of the card suit.

func (Suit) String

func (suit Suit) String() string

String satisfies the fmt.Stringer interface.

func (Suit) UnicodeBlack

func (suit Suit) UnicodeBlack() rune

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

func (Suit) UnicodeWhite

func (suit Suit) UnicodeWhite() rune

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

type Type

type Type uint16

Type is a game eval type, providing a standard interface wrapping a TypeDesc. [DefaultType]'s are registered by default unless using the [noinit] build tag.

Holdem is a best-5 card game using a standard deck of 52 cards (see DeckFrench), having a pocket of 2 cards, 5 community board cards, and a Pre-Flop, Flop, Turn, and River streets. 2 pocket cards are dealt on the Pre-Flop, with 3 board cards on the Flop, 1 board card on the Turn, and one on the River. 1 card is discarded on the Flop, Turn, and River, prior to the board cards being dealt.

Split is the Hi/Lo variant of Holdem, using a RankEightOrBetter as the Lo eval.

Short is a Holdem variant using a Short deck (a 6+ only card deck, see DeckShort). Flush ranks over FullHouse.

Manila is a Holdem variant using a Manila deck (a 7+ only card deck, see DeckManila), forcing the use of 2 pocket cards, adding a Drop street before the Flop, and with all 5 streets (instead of 4) receiving 1 board card each. Flush ranks over FullHouse.

Spanish is a Holdem/Manila variant, using a Spanish deck (a 8+ only card deck, see DeckSpanish).

Royal is a Holdem variant using a Royal deck (a 10+ only card deck, see DeckRoyal).

Double is a Holdem variant where there are two community boards, comprising the Hi and Lo.

Showtime is a Holdem variant where folded cards are shown.

Swap is a Holdem variant where up to 2 cards may be drawn (exchanged) once.

River is a Holdem variant that deals 1 pocket card on the river instead of a shared community board card on the river, resulting in a pocket of 3 and a community board of 4.

Dallas is Holdem variant that forces the use of the 2 pocket cards and any 3 board cards. Similar to Omaha, but with 2 pocket cards instead of 4.

Houston is a Holdem variant with 3 pocket cards, 2 board cards dealt on the Flop (instead of 3), and requires using 2 of the 3 pocket cards, and any 3 board cards to make the best-5. Essentially Omaha, but with 3 pocket cards instead of 4, and a community board of 4.

Draw is a best-5 card game using a standard deck of 52 cards (see DeckFrench), comprising a pocket of 5 cards, no community cards, with a Ante, 6th, and River streets. 5 cards are dealt on the Ante, and up to 5 cards can be drawn (exchanged) on the 6th street.

DrawHiLo is the Hi/Lo variant of Draw, using a RankEightOrBetter as the Lo eval.

Stud is a best-5 card game, using a standard deck of 52 cards (see DeckFrench), comprising a pocket of 7 cards, no community cards, with Ante, 4th, 5th, 6th and River streets. 3 pocket cards are dealt on the Ante, with 1 pocket card turend up, and an additional pocket card dealt up on the 4th, 5th, and 6th streets, with a final pocket card dealt down on the 7th street for a total of 7 pocket cards.

StudHiLo is the Hi/Lo variant of Stud, using a RankEightOrBetter as the Lo eval.

StudFive is a best-5 card game using a standard deck of 52 cards (see DeckFrench), comprising a pocket of 5 cards, no community cards, with Ante, 3rd, 4th, and River streets. 2 pocket cards are dealt on the Ante, with 1 pocket card dealt up, and an additional pocket card dealt up on the 3rd, 4th, and 5th streets. It is similar to Stud, but without 5th and 6th streets.

Video is a best-5 card game, using a standard deck of 52 cards (see DeckFrench), comprising a pocket of 5 cards, no community cards, with a Ante and River. 5 pocket cards are dealt on the Ante, all up. Up to 5 cards can be drawn (exchanged) on the River. Uses a qualifier of a Jacks-or-better for Hi eval (see NewJacksOrBetterEval).

Omaha is a Holdem variant with 4 pocket cards, requiring use of 2 of the pocket and 3 of the board to make the best-5.

OmahaHiLo is the Hi/Lo variant of Omaha, using a RankEightOrBetter as the Lo eval.

OmahaDouble is a Omaha variant where there are two community boards comprising the Hi and Lo.

OmahaFive is a Holdem/Omaha variant with 5 pocket cards, requiring the use of 2 of the pocket and 3 of the board to make the best-5.

OmahaSix is a Holdem/Omaha variant with 6 pocket cards, requiring the use of 2 of the pocket and 3 of the board to make the best-5 cards.

Courchevel is a OmahaFive variant, where 1 board card is dealt on the Pre-Flop, and only 2 board cards dealt on the Flop.

Fusion is a Holdem/Omaha variant where only 2 pocket cards are dealt on the Pre-Flop, with 1 additional pocket card dealt on the Flop and Turn.

FusionHiLo is the Hi/Lo variant of Fusion, using a RankEightOrBetter as the Lo eval.

Soko is a Holdem variant with 2 additional ranks, a Four Flush (4 cards of the same suit), and a Four Straight (4 cards in sequential rank, with no wrapping straights), besting Pair and Nothing.

SokoHiLo is the Hi/Lo variant of Soko, using a RankEightOrBetter as the Lo eval.

Lowball is a best-5 low card game using a standard deck of 52 cards (see DeckFrench), comprising 5 pocket cards, no community cards, and a Ante, 6th, 7th, and River streets using a 2-to-7 low ("Lowball") inverted ranking system, where Ace's always play high, and non-Flush, and non-Straight lows are best. Up to 5 cards may be drawn (exchanged) once on either the 6th, 7th, or River streets.

LowballTriple is a Lowball multi variant that allows any 5 cards to be drawn (exchanged) on the 6th, 7th, or River streets.

Razz is a Stud variant, using a Ace-to-5 low ranking (see RankRazz/RankAceFiveLow), where Ace's play low, and Flush's and Straight's do not affect ranking.

Badugi is a unique, best-4, lowest non-matching-suit card game (see NewBadugiEval), using a standard deck of 52 cards (see DeckFrench), comprising 4 pocket cards, no community cards, and Ante, 5th, 6th, and River streets. Up to 4 cards can be drawn (exchanged) on the 5th, 6th, or River streets.

const (
	Holdem         Type = 'H'<<8 | 'h' // Hh
	Split          Type = 'H'<<8 | 'l' // Hl
	Short          Type = 'H'<<8 | 's' // Hs
	Manila         Type = 'H'<<8 | 'm' // Hm
	Spanish        Type = 'H'<<8 | 'p' // Hp
	Royal          Type = 'H'<<8 | 'r' // Hr
	Double         Type = 'H'<<8 | 'd' // Hd
	Showtime       Type = 'H'<<8 | 't' // Ht
	Swap           Type = 'H'<<8 | 'w' // Hw
	River          Type = 'H'<<8 | 'v' // Hv
	Dallas         Type = 'H'<<8 | 'a' // Ha
	Houston        Type = 'H'<<8 | 'u' // Hu
	Draw           Type = 'D'<<8 | 'h' // Dh
	DrawHiLo       Type = 'D'<<8 | 'l' // Dl
	Stud           Type = 'S'<<8 | 'h' // Sh
	StudHiLo       Type = 'S'<<8 | 'l' // Sl
	StudFive       Type = 'S'<<8 | '5' // S5
	Video          Type = 'J'<<8 | 'h' // Jh
	Omaha          Type = 'O'<<8 | '4' // O4
	OmahaHiLo      Type = 'O'<<8 | 'l' // Ol
	OmahaDouble    Type = 'O'<<8 | 'd' // Od
	OmahaFive      Type = 'O'<<8 | '5' // O5
	OmahaSix       Type = 'O'<<8 | '6' // O6
	Courchevel     Type = 'O'<<8 | 'c' // Oc
	CourchevelHiLo Type = 'O'<<8 | 'e' // Oe
	Fusion         Type = 'O'<<8 | 'f' // Of
	FusionHiLo     Type = 'O'<<8 | 'F' // OF
	Soko           Type = 'K'<<8 | 'h' // Kh
	SokoHiLo       Type = 'K'<<8 | 'l' // Kl
	Lowball        Type = 'L'<<8 | '1' // L1
	LowballTriple  Type = 'L'<<8 | '3' // L3
	Razz           Type = 'R'<<8 | 'a' // Ra
	Badugi         Type = 'B'<<8 | 'a' // Ba
)

Types.

func IdToType added in v0.9.0

func IdToType(id string) (Type, error)

IdToType converts id to a type.

func Types added in v0.8.0

func Types() []Type

Types returns registered types.

func (Type) Blinds added in v0.8.0

func (typ Type) Blinds() []string

Blinds returns the type's blind names.

func (Type) Board added in v0.9.0

func (typ Type) Board() int

Board returns the type's total dealt board cards.

func (Type) BoardDiscard added in v0.9.0

func (typ Type) BoardDiscard() int

BoardDiscard returns the type's total board discard.

func (Type) Deal

func (typ Type) Deal(shuffler Shuffler, shuffles, count int) ([][]Card, []Card)

Deal creates a new dealer for the type, shuffling the deck by shuffles and returning the count dealt pockets and hi board.

func (Type) Dealer added in v0.8.0

func (typ Type) Dealer(shuffler Shuffler, shuffles, count int) *Dealer

Dealer creates a new dealer with a deck shuffled by shuffles, for the pocket count.

func (Type) Deck

func (typ Type) Deck() *Deck

Deck returns a new deck for the type.

func (Type) DeckType added in v0.9.0

func (typ Type) DeckType() DeckType

DeckType returns the type's deck type.

func (Type) Desc added in v0.8.0

func (typ Type) Desc() TypeDesc

Desc returns the type's description.

func (Type) Double added in v0.8.0

func (typ Type) Double() bool

Double returns true when the type has double boards.

func (Type) Eval added in v0.8.0

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

Eval creates a new eval, and evaluates the type and pocket.

func (Type) EvalPockets added in v0.10.0

func (typ Type) EvalPockets(pockets [][]Card, board []Card) []*Eval

EvalPockets creates new evals and evaluates each of the pockets and board.

func (Type) Format added in v0.8.0

func (typ Type) Format(f fmt.State, verb rune)

Format satisfies the fmt.Formatter interface.

func (Type) Id added in v0.9.0

func (typ Type) Id() string

Id returns the type's id.

func (Type) Low

func (typ Type) Low() bool

Low returns true when the type supports 8-or-better lo eval.

func (Type) MarshalText

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

MarshalText satisfies the encoding.TextMarshaler interface.

func (Type) Max added in v0.8.0

func (typ Type) Max() int

Max returns the type's max players.

func (Type) Name added in v0.8.0

func (typ Type) Name() string

Name returns the type's name.

func (Type) New added in v0.9.0

func (typ Type) New() *Eval

New creates a new eval for the type and pocket.

func (Type) Once added in v0.9.0

func (typ Type) Once() bool

Once returns true when draws are limited to one time.

func (Type) Pocket added in v0.9.0

func (typ Type) Pocket() int

Pocket returns the type's total dealt pocket cards.

func (Type) PocketDiscard added in v0.9.0

func (typ Type) PocketDiscard() int

PocketDiscard returns the type's total pocket discard.

func (Type) Show added in v0.8.0

func (typ Type) Show() bool

Show returns true when the type shows folded cards.

func (Type) Streets added in v0.9.0

func (typ Type) Streets() []StreetDesc

Streets returns the type's street descriptions.

func (*Type) UnmarshalText

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

UnmarshalText satisfies the encoding.TextUnmarshaler interface.

type TypeDesc added in v0.8.0

type TypeDesc struct {
	// Num is the registered number.
	Num int
	// Type is the type.
	Type Type
	// Name is the type name.
	Name string
	// Max is the max number of players.
	Max int
	// Low is true when the type's Cactus or Omaha eval is the Hi/Lo variant,
	// enabling 8-or-better on the lo eval.
	Low bool
	// Double is true when there are double the number boards.
	Double bool
	// Show is true when folded cards are shown.
	Show bool
	// Once is true when a draw can only occur once.
	Once bool
	// Blinds are the blind names.
	Blinds []string
	// Streets are the betting streets.
	Streets []StreetDesc
	// Deck is the deck type.
	Deck DeckType
	// Eval is the eval type.
	Eval EvalType
	// HiDesc is the hi desc type.
	HiDesc DescType
	// LoDesc is the lo desc type.
	LoDesc DescType
}

TypeDesc is a type description.

func DefaultTypes added in v0.9.0

func DefaultTypes() []TypeDesc

DefaultTypes returns the default type descriptions. The returned TypeDesc's will be automatically registered, unless using the [noinit] tag.

func NewType added in v0.10.0

func NewType(id string, typ Type, name string, opts ...TypeOption) (*TypeDesc, error)

NewType creates a new type description. Any created type must be registered by calling RegisterType before it can be used for eval.

func (*TypeDesc) Apply added in v0.8.0

func (desc *TypeDesc) Apply(opts ...StreetOption)

Apply applies street options.

type TypeOption added in v0.8.0

type TypeOption func(*TypeDesc)

TypeOption is a type description option.

func WithBadugi added in v0.8.0

func WithBadugi(opts ...StreetOption) TypeOption

WithBadugi is a type description option to set Badugi definitions.

4 cards, low evaluation of separate suits
All 4 face down pre-flop
3 rounds of player discards (up to 4)

func WithCourchevel added in v0.8.0

func WithCourchevel(low bool, opts ...StreetOption) TypeOption

WithCourchevel is a type description option to set Courchevel definitions.

func WithDallas added in v0.10.0

func WithDallas(low bool, opts ...StreetOption) TypeOption

WithDallas is a type description option to set Dallas definitions.

func WithDouble added in v0.8.0

func WithDouble(opts ...StreetOption) TypeOption

WithDouble is a type description option to set Double definitions.

func WithDraw added in v0.10.0

func WithDraw(low bool, opts ...StreetOption) TypeOption

WithDraw is a type description option to set Draw definitions.

func WithFusion added in v0.8.0

func WithFusion(low bool, opts ...StreetOption) TypeOption

WithFusion is a type description option to set Fusion definitions.

func WithHoldem added in v0.8.0

func WithHoldem(low bool, opts ...StreetOption) TypeOption

WithHoldem is a type description option to set Holdem definitions.

func WithHouston added in v0.10.0

func WithHouston(low bool, opts ...StreetOption) TypeOption

WithHouston is a type description option to set Houston definitions.

func WithLowball added in v0.9.0

func WithLowball(multi bool, opts ...StreetOption) TypeOption

WithLowball is a type description option to set Lowball definitions.

func WithManila added in v0.9.0

func WithManila(opts ...StreetOption) TypeOption

WithManila is a type description option to set Manila definitions.

func WithOmaha added in v0.8.0

func WithOmaha(low bool, opts ...StreetOption) TypeOption

WithOmaha is a type description option to set Omaha definitions.

func WithOmahaDouble added in v0.8.0

func WithOmahaDouble(opts ...StreetOption) TypeOption

WithOmahaDouble is a type description option to set OmahaDouble definitions.

func WithOmahaFive added in v0.8.0

func WithOmahaFive(low bool, opts ...StreetOption) TypeOption

WithOmahaFive is a type description option to set OmahaFive definitions.

func WithOmahaSix added in v0.8.0

func WithOmahaSix(low bool, opts ...StreetOption) TypeOption

WithOmahaSix is a type description option to set OmahaSix definitions.

func WithRazz added in v0.8.0

func WithRazz(opts ...StreetOption) TypeOption

WithRazz is a type description option to set Razz definitions.

func WithRiver added in v0.10.0

func WithRiver(low bool, opts ...StreetOption) TypeOption

WithRiver is a type description option to set River definitions.

func WithRoyal added in v0.8.0

func WithRoyal(opts ...StreetOption) TypeOption

WithRoyal is a type description option to set Royal definitions.

func WithShort added in v0.8.0

func WithShort(opts ...StreetOption) TypeOption

WithShort is a type description option to set Short definitions.

func WithShowtime added in v0.8.0

func WithShowtime(low bool, opts ...StreetOption) TypeOption

WithShowtime is a type description option to set Showtime definitions.

func WithSoko added in v0.9.0

func WithSoko(low bool, opts ...StreetOption) TypeOption

WithSoko is a type description option to set Soko definitions.

func WithSpanish added in v0.10.0

func WithSpanish(opts ...StreetOption) TypeOption

WithSpanish is a type description option to set Spanish definitions.

func WithStud added in v0.8.0

func WithStud(low bool, opts ...StreetOption) TypeOption

WithStud is a type description option to set Stud definitions.

func WithStudFive added in v0.10.0

func WithStudFive(low bool, opts ...StreetOption) TypeOption

WithStudFive is a type description option to set StudFive definitions.

func WithSwap added in v0.9.0

func WithSwap(low bool, opts ...StreetOption) TypeOption

WithSwap is a type description option to set Swap definitions.

func WithVideo added in v0.10.0

func WithVideo(low bool, opts ...StreetOption) TypeOption

WithVideo is a type description option to set Video definitions.

type Win added in v0.8.0

type Win struct {
	Evals []*Eval
	Order []int
	Pivot int
	Low   bool
	Scoop bool
}

Win formats win information.

func NewWin added in v0.8.0

func NewWin(evs []*Eval, order []int, pivot int, low, scoop bool) *Win

NewWin creates a new win.

func (*Win) Desc added in v0.10.0

func (win *Win) Desc() []*Desc

Desc returns the win descriptions.

func (*Win) Format added in v0.8.0

func (win *Win) Format(f fmt.State, verb rune)

Format satisfies the fmt.Formatter interface.

func (*Win) Invalid added in v0.10.0

func (win *Win) Invalid() bool

Invalid returns true when there are no valid winners.

func (*Win) Verb added in v0.8.0

func (win *Win) Verb() string

Verb returns the win verb.

Directories

Path Synopsis
_example

Jump to

Keyboard shortcuts

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