Documentation ¶
Overview ¶
Package cardrank is a library of types, utilities, and interfaces for working with playing cards, card decks, evaluating poker hand ranks, and managing deals and run outs for different game types.
Example ¶
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 names []string }{ {566, 2, 't', 3, nil, []string{"Alice", "Bob"}}, {1039, 5, 'f', 2, []int{0, 3, 4}, []string{"Alice", "Bob", "Carl", "Dave", "Elizabeth"}}, {2087, 6, 't', 2, []int{0, 5}, []string{"Alice", "Bob", "Carl", "Dave", "Elizabeth", "Frank"}}, {4022, 6, 'p', 2, []int{0, 1, 4}, []string{"Alice", "Bob", "Carl", "Dave", "Elizabeth", "Fenny"}}, } { // 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.Println("Deck:") 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]) } last := -1 for d.Next() { i, run := d.Run() if last != i { fmt.Printf("Run %d:\n", i) } last = i fmt.Printf(" %s\n", d) // display pockets if d.HasPocket() { for i := 0; i < game.players; i++ { fmt.Printf(" %d %s: %v\n", i, game.names[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 && i == 0 { if success := d.ChangeRuns(game.runs); !success { panic("unable to change runs") } // deactivate if success := d.Deactivate(game.inactive...); !success { panic("unable to deactivate positions") } } } fmt.Println("Showdown:") 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(game.names...) fmt.Printf(" Result: %S\n", hi) if lo != nil { fmt.Printf(" %S\n", 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] Run 0: p: Pre-Flop (p: 2) 0 Alice: [4h 5c] 1 Bob: [Qs 4c] f: Flop (p: 1, d: 1, b: 3) 0 Alice: [4h 5c 5d] 1 Bob: [Qs 4c 8d] Discard: [8c] Board: [As Ks 6h] t: Turn (p: 1, d: 1, b: 1) 0 Alice: [4h 5c 5d 7s] 1 Bob: [Qs 4c 8d 9s] Discard: [8c 3h] Board: [As Ks 6h Ac] r: River (d: 1, b: 1) Discard: [8c 3h Js] Board: [As Ks 6h Ac 9h] Run 1: r: River (d: 1, b: 1) Discard: [4s] Board: [As Ks 6h Ac 7d] Run 2: r: River (d: 1, b: 1) 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: Bob 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: Alice wins with Two Pair, Aces over Sevens, kicker Five Alice 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: Bob wins with Flush, Ace-high, kickers King, Queen, Nine, Eight Alice 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] Run 0: p: Pre-Flop (p: 2) 0 Alice: [2h 5h] 1 Bob: [5s 6d] 2 Carl: [Ac Th] 3 Dave: [Ts 2s] 4 Elizabeth: [Kd 6s] f: Flop (p: 1, d: 1, b: 3) 0 Alice: [2h 5h 7c] 1 Bob: [5s 6d 4h] 2 Carl: [Ac Th 8c] 3 Dave: [Ts 2s 9h] 4 Elizabeth: [Kd 6s Ah] Discard: [8s] Board: [Kc 9d 5c] t: Turn (p: 1, d: 1, b: 1) 0 Alice: [2h 5h 7c 5d] 1 Bob: [5s 6d 4h As] 2 Carl: [Ac Th 8c 4d] 3 Dave: [Ts 2s 9h 3h] 4 Elizabeth: [Kd 6s Ah 2c] Discard: [8s 7s] Board: [Kc 9d 5c 8h] r: River (d: 1, b: 1) Discard: [8s 7s 4c] Board: [Kc 9d 5c 8h 7d] Run 1: t: Turn (p: 1, d: 1, b: 1) 0 Alice: [2h 5h 7c 8d] 1 Bob: [5s 6d 4h Qs] 2 Carl: [Ac Th 8c 3c] 3 Dave: [Ts 2s 9h 7h] 4 Elizabeth: [Kd 6s Ah Jc] Discard: [Jh] Board: [Kc 9d 5c 6c] r: River (d: 1, b: 1) Discard: [Jh 3s] Board: [Kc 9d 5c 6c Qd] Showdown: Run 0: 0: inactive 1: [9d 8h 7d 6d 5s] [As Kc 5c 4h] Straight, Nine-high [8h 7d 5c 4h As] [Kc 9d 6d 5s] Eight, Seven, Five, Four, Ace-low 2: [8c 8h Ac Kc 9d] [Th 7d 5c 4d] Pair, Eights, kickers Ace, King, Nine [8h 7d 5c 4d Ac] [Kc Th 9d 8c] Eight, Seven, Five, Four, Ace-low 3: inactive 4: inactive Result: Bob wins with Straight, Nine-high Bob, Carl split with Eight, Seven, Five, Four, Ace-low Run 1: 0: inactive 1: [Qd Qs 6c 6d Kc] [9d 5c 5s 4h] Two Pair, Queens over Sixes, kicker King [] [] None 2: [Ac Kc 8c 6c 5c] [Qd Th 9d 3c] Flush, Ace-high, kickers King, Eight, Six, Five [] [] None 3: inactive 4: inactive Result: Carl scoops with Flush, Ace-high, kickers King, Eight, Six, 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] Run 0: p: Pre-Flop (p: 2) 0 Alice: [8h Kd] 1 Bob: [5d Td] 2 Carl: [5c 6s] 3 Dave: [3h As] 4 Elizabeth: [Jc 7c] 5 Frank: [6h 6c] f: Flop (p: 1, d: 1, b: 3) 0 Alice: [8h Kd 2c] 1 Bob: [5d Td Jd] 2 Carl: [5c 6s 9h] 3 Dave: [3h As 8c] 4 Elizabeth: [Jc 7c 7s] 5 Frank: [6h 6c 5s] Discard: [8d] Board: [Tc 3s Kc] t: Turn (p: 1, d: 1, b: 1) 0 Alice: [8h Kd 2c Qh] 1 Bob: [5d Td Jd Qd] 2 Carl: [5c 6s 9h 7d] 3 Dave: [3h As 8c Ks] 4 Elizabeth: [Jc 7c 7s Jh] 5 Frank: [6h 6c 5s 4s] Discard: [8d 9s] Board: [Tc 3s Kc 4h] r: River (d: 1, b: 1) Discard: [8d 9s Th] Board: [Tc 3s Kc 4h Qc] Run 1: r: River (d: 1, b: 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: Elizabeth 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: Carl wins with Straight, Six-high Carl wins with Six, Five, Four, Three, Two-low ------ FusionHiLo 4 ------ Deck: [Qc 4h 2c 7c Kc 5c 9d 5h] [3c Tc 9c Qd As 4s 5d Jc] [4c Ad 9s 8s Qh 3h Td 7h] [7s Ks 6d Kd 7d Jh 2d Js] [4d 6h Th Ah Ac Ts 3d 6c] [Jd 2s 2h 9h 3s 5s 8d 8c] [Qs 8h Kh 6s] Run 0: p: Pre-Flop (p: 2) 0 Alice: [Qc 9d] 1 Bob: [4h 5h] 2 Carl: [2c 3c] 3 Dave: [7c Tc] 4 Elizabeth: [Kc 9c] 5 Fenny: [5c Qd] f: Flop (p: 1, d: 1, b: 3) 0 Alice: [Qc 9d As] 1 Bob: [4h 5h 4s] 2 Carl: [2c 3c 5d] 3 Dave: [7c Tc Jc] 4 Elizabeth: [Kc 9c 4c] 5 Fenny: [5c Qd Ad] Discard: [9s] Board: [8s Qh 3h] t: Turn (p: 1, d: 1, b: 1) 0 Alice: [Qc 9d As Td] 1 Bob: [4h 5h 4s 7h] 2 Carl: [2c 3c 5d 7s] 3 Dave: [7c Tc Jc Ks] 4 Elizabeth: [Kc 9c 4c 6d] 5 Fenny: [5c Qd Ad Kd] Discard: [9s 7d] Board: [8s Qh 3h Jh] r: River (d: 1, b: 1) Discard: [9s 7d 2d] Board: [8s Qh 3h Jh Js] Run 1: f: Flop (p: 1, d: 1, b: 3) 0 Alice: [Qc 9d 4d] 1 Bob: [4h 5h 6h] 2 Carl: [2c 3c Th] 3 Dave: [7c Tc Ah] 4 Elizabeth: [Kc 9c Ac] 5 Fenny: [5c Qd Ts] Discard: [3d] Board: [6c Jd 2s] t: Turn (p: 1, d: 1, b: 1) 0 Alice: [Qc 9d 4d 2h] 1 Bob: [4h 5h 6h 9h] 2 Carl: [2c 3c Th 3s] 3 Dave: [7c Tc Ah 5s] 4 Elizabeth: [Kc 9c Ac 8d] 5 Fenny: [5c Qd Ts 8c] Discard: [3d Qs] Board: [6c Jd 2s 8h] r: River (d: 1, b: 1) Discard: [3d Qs Kh] Board: [6c Jd 2s 8h 6s] Showdown: Run 0: 0: inactive 1: inactive 2: [Jh Js 3c 3h 7s] [Qh 8s 5d 2c] Two Pair, Jacks over Threes, kicker Seven [] [] None 3: [Jc Jh Js Ks Qh] [Tc 8s 7c 3h] Three of a Kind, Jacks, kickers King, Queen [] [] None 4: inactive 5: [Qd Qh Jh Js Ad] [Kd 8s 5c 3h] Two Pair, Queens over Jacks, kicker Ace [] [] None Result: Dave scoops with Three of a Kind, Jacks, kickers King, Queen Run 1: 0: inactive 1: inactive 2: [6c 6s 3c 3s Jd] [Th 8h 2c 2s] Two Pair, Sixes over Threes, kicker Jack [] [] None 3: [6c 6s Ah Jd Tc] [8h 7c 5s 2s] Pair, Sixes, kickers Ace, Jack, Ten [8h 6c 5s 2s Ah] [Jd Tc 7c 6s] Eight, Six, Five, Two, Ace-low 4: inactive 5: [8c 8h 6c 6s Qd] [Jd Ts 5c 2s] Two Pair, Eights over Sixes, kicker Queen [] [] None Result: Fenny wins with Two Pair, Eights over Sixes, kicker Queen Dave wins with Eight, Six, Five, Two, Ace-low
Example (ComputerHand) ¶
package main import ( "context" "fmt" "github.com/cardrank/cardrank" ) func main() { pocket := cardrank.Must("Qh 7s") expv, ok := cardrank.Holdem.ExpValue(context.Background(), pocket) if !ok { panic("unable to calculate expected value") } fmt.Println("expected value:", expv) }
Output: expected value: 51.8% (1046780178,78084287/2097572400)
Index ¶
- Constants
- Variables
- func CactusDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)
- func FlushOverDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)
- func HashKey(c0, c1 Card) string
- func HighDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)
- func HoldemBlinds() []string
- func HoldemStarting() map[string]ExpValue
- func Init()
- func LowDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)
- func LowballDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)
- func Order(evs []*Eval, low bool) ([]int, int)
- func RazzDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)
- func RegisterDefaultTypes() error
- func RegisterType(desc TypeDesc) error
- func SokoDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)
- func StudBlinds() []string
- func ThreeDesc(f fmt.State, verb rune, rank EvalRank, best, unused []Card)
- type BinGen
- type CalcOption
- func WithActive(active map[int]bool, folded bool) CalcOption
- func WithBoard(board []Card) CalcOption
- func WithDeep(deep bool) CalcOption
- func WithDiscard(discard bool) CalcOption
- func WithOpponents(opponents int) CalcOption
- func WithPocketsBoard(pockets [][]Card, board []Card) CalcOption
- func WithRuns(runs []*Run) CalcOption
- type Card
- func (c Card) AceRank() int
- func (c Card) Format(f fmt.State, verb rune)
- func (c Card) Index() int
- func (c Card) KnightRune() rune
- func (c Card) MarshalText() ([]byte, error)
- func (c Card) Rank() Rank
- func (c Card) RankByte() byte
- func (c Card) RankIndex() int
- func (c Card) Rune() rune
- func (c Card) String() string
- func (c Card) Suit() Suit
- func (c Card) SuitByte() byte
- func (c Card) SuitIndex() int
- func (c *Card) UnmarshalText(buf []byte) error
- type Dealer
- func (d *Dealer) Board() int
- func (d *Dealer) BoardDiscard() int
- func (d *Dealer) Calc(ctx context.Context, folded bool, opts ...CalcOption) (*Odds, *Odds, bool)
- func (d *Dealer) ChangeRuns(runs int) bool
- func (d *Dealer) Deactivate(positions ...int) bool
- func (d *Dealer) Deal(street int, run *Run)
- func (d *Dealer) Discarded() []Card
- func (d *Dealer) Format(f fmt.State, verb rune)
- func (d *Dealer) HasActive() bool
- func (d *Dealer) HasBoard() bool
- func (d *Dealer) HasCalc() bool
- func (d *Dealer) HasNext() bool
- func (d *Dealer) HasPocket() bool
- func (d *Dealer) Id() byte
- func (d *Dealer) Inactive() []int
- func (d *Dealer) Name() string
- func (d *Dealer) Next() bool
- func (d *Dealer) NextId() byte
- func (d *Dealer) NextResult() bool
- func (d *Dealer) Pocket() int
- func (d *Dealer) PocketDiscard() int
- func (d *Dealer) PocketDraw() int
- func (d *Dealer) PocketUp() int
- func (d *Dealer) Reset()
- func (d *Dealer) Result() (int, *Result)
- func (d *Dealer) Run() (int, *Run)
- func (d *Dealer) Street() int
- type Deck
- type DeckType
- func (typ DeckType) Desc(short bool) string
- func (typ DeckType) Exclude(ex ...[]Card) []Card
- func (typ DeckType) Format(f fmt.State, verb rune)
- func (typ DeckType) Name() string
- func (typ DeckType) New() *Deck
- func (typ DeckType) Ordinal() int
- func (typ DeckType) Shoe(count int) *Deck
- func (typ DeckType) Shuffle(shuffler Shuffler, shuffles int) *Deck
- func (typ DeckType) Unshuffled() []Card
- type DescType
- type Error
- type Eval
- func (ev *Eval) Comp(b *Eval, low bool) int
- func (ev *Eval) Desc(low bool) *EvalDesc
- func (ev *Eval) Eval(pocket, board []Card)
- func (ev *Eval) Format(f fmt.State, verb rune)
- func (ev *Eval) Hi5(f RankFunc, v []Card)
- func (ev *Eval) Hi6(f RankFunc, v []Card)
- func (ev *Eval) Hi7(f RankFunc, v []Card)
- func (ev *Eval) HiLo23(hi, lo RankFunc, c0, c1 Card, b []Card, max EvalRank)
- func (ev *Eval) HiLo24(hi, lo RankFunc, c0, c1 Card, b []Card, max EvalRank)
- func (ev *Eval) HiLo25(hi, lo RankFunc, c0, c1 Card, b []Card, max EvalRank)
- func (ev *Eval) HiLo5(hi, lo RankFunc, v []Card, max EvalRank)
- func (ev *Eval) HiLo6(hi, lo RankFunc, v []Card, max EvalRank)
- func (ev *Eval) HiLo7(hi, lo RankFunc, v []Card, max EvalRank)
- func (ev *Eval) Max5(f RankFunc, v []Card, max EvalRank, low bool)
- func (ev *Eval) Max6(f RankFunc, v []Card, max EvalRank, low bool)
- func (ev *Eval) Max7(f RankFunc, v []Card, max EvalRank, low bool)
- type EvalDesc
- type EvalFunc
- func NewBadugiEval(normalize bool) EvalFunc
- func NewCactusEval(normalize, low bool) EvalFunc
- func NewEval(f RankFunc) EvalFunc
- func NewHighEval() EvalFunc
- func NewHybridEval(normalize, low bool) EvalFunc
- func NewJacksOrBetterEval(normalize bool) EvalFunc
- func NewLeducEval() EvalFunc
- func NewLowballEval(normalize bool) EvalFunc
- func NewMaxEval(f RankFunc, max EvalRank, low bool) EvalFunc
- func NewModifiedEval(hi RankFunc, base Rank, inv func(EvalRank) EvalRank, normalize, low bool) EvalFunc
- func NewOmahaEval(hi RankFunc, base Rank, inv func(EvalRank) EvalRank, normalize, low bool) EvalFunc
- func NewRazzEval(normalize bool) EvalFunc
- func NewSokoEval(normalize, low bool) EvalFunc
- func NewSplitEval(hi, lo RankFunc, max EvalRank) EvalFunc
- func NewThreeEval() EvalFunc
- type EvalRank
- func Cactus(c0, c1, c2, c3, c4 Card) EvalRank
- func CactusFast(c0, c1, c2, c3, c4 Card) EvalRank
- func RankAceFiveLow(mask EvalRank, c0, c1, c2, c3, c4 Card) EvalRank
- func RankEightOrBetter(c0, c1, c2, c3, c4 Card) EvalRank
- func RankLowball(c0, c1, c2, c3, c4 Card) EvalRank
- func RankManila(c0, c1, c2, c3, c4 Card) EvalRank
- func RankRazz(c0, c1, c2, c3, c4 Card) EvalRank
- func RankShort(c0, c1, c2, c3, c4 Card) EvalRank
- func RankSoko(c0, c1, c2, c3, c4 Card) EvalRank
- func RankSpanish(c0, c1, c2, c3, c4 Card) EvalRank
- func (r EvalRank) Fixed() EvalRank
- func (r EvalRank) Format(f fmt.State, verb rune)
- func (r EvalRank) FromFlushOver() EvalRank
- func (r EvalRank) FromLowball() EvalRank
- func (r EvalRank) Name() string
- func (r EvalRank) Title() string
- func (r EvalRank) ToFlushOver() EvalRank
- func (r EvalRank) ToLowball() EvalRank
- type EvalType
- type ExpValue
- type ExpValueCalc
- type Formatter
- type Odds
- type OddsCalc
- type ParseError
- type Rank
- type RankFunc
- type Result
- type Run
- type Shuffler
- type StreetDesc
- type StreetOption
- type Suit
- func (suit Suit) AlternateEmoji() string
- func (suit Suit) Byte() byte
- func (suit Suit) Emoji() string
- func (suit Suit) Index() int
- func (suit Suit) Name() string
- func (suit Suit) PluralName() string
- func (suit Suit) String() string
- func (suit Suit) UnicodeBlack() rune
- func (suit Suit) UnicodeWhite() rune
- type Type
- func (typ Type) Blinds() []string
- func (typ Type) Board() int
- func (typ Type) BoardDiscard() int
- func (typ Type) Cactus() bool
- func (typ Type) Deal(shuffler Shuffler, shuffles, count int) ([][]Card, []Card)
- func (typ Type) Dealer(shuffler Shuffler, shuffles, count int) *Dealer
- func (typ Type) Deck() *Deck
- func (typ Type) DeckType() DeckType
- func (typ Type) Desc() TypeDesc
- func (typ Type) Double() bool
- func (typ Type) Draw() bool
- func (typ Type) Eval(pocket, board []Card) *Eval
- func (typ Type) EvalPockets(pockets [][]Card, board []Card) []*Eval
- func (typ Type) ExpValue(ctx context.Context, pocket []Card, opts ...CalcOption) (*ExpValue, bool)
- func (typ Type) Format(f fmt.State, verb rune)
- func (typ Type) Id() string
- func (typ Type) Low() bool
- func (typ Type) MarshalText() ([]byte, error)
- func (typ Type) Max() int
- func (typ Type) Name() string
- func (typ Type) Odds(ctx context.Context, pockets [][]Card, board []Card, opts ...CalcOption) (*Odds, *Odds, bool)
- func (typ Type) Once() bool
- func (typ Type) Pocket() int
- func (typ Type) PocketDiscard() int
- func (typ Type) Show() bool
- func (typ Type) Streets() []StreetDesc
- func (typ *Type) UnmarshalText(buf []byte) error
- type TypeDesc
- type TypeOption
- func WithBadugi(opts ...StreetOption) TypeOption
- func WithCourchevel(low bool, opts ...StreetOption) TypeOption
- func WithDallas(low bool, opts ...StreetOption) TypeOption
- func WithDouble(opts ...StreetOption) TypeOption
- func WithDraw(low bool, opts ...StreetOption) TypeOption
- func WithFusion(low bool, opts ...StreetOption) TypeOption
- func WithHoldem(low bool, opts ...StreetOption) TypeOption
- func WithHouston(low bool, opts ...StreetOption) TypeOption
- func WithKuhn(opts ...StreetOption) TypeOption
- func WithLeduc(opts ...StreetOption) TypeOption
- func WithLowball(multi bool, opts ...StreetOption) TypeOption
- func WithManila(opts ...StreetOption) TypeOption
- func WithOmaha(low bool, opts ...StreetOption) TypeOption
- func WithOmahaDouble(opts ...StreetOption) TypeOption
- func WithOmahaFive(low bool, opts ...StreetOption) TypeOption
- func WithOmahaRoyal(opts ...StreetOption) TypeOption
- func WithOmahaSix(low bool, opts ...StreetOption) TypeOption
- func WithRazz(opts ...StreetOption) TypeOption
- func WithRhodeIsland(opts ...StreetOption) TypeOption
- func WithRiver(low bool, opts ...StreetOption) TypeOption
- func WithRoyal(opts ...StreetOption) TypeOption
- func WithShort(opts ...StreetOption) TypeOption
- func WithShowtime(low bool, opts ...StreetOption) TypeOption
- func WithSoko(low bool, opts ...StreetOption) TypeOption
- func WithSpanish(opts ...StreetOption) TypeOption
- func WithStud(low bool, opts ...StreetOption) TypeOption
- func WithStudFive(low bool, opts ...StreetOption) TypeOption
- func WithSwap(low bool, opts ...StreetOption) TypeOption
- func WithVideo(low bool, opts ...StreetOption) TypeOption
- type Win
Examples ¶
Constants ¶
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.
const ( // DeckFrench is a standard deck of 52 playing cards. DeckFrench = DeckType(Two) // DeckShort is a deck of 36 playing cards of rank 6+ (see [Short]). DeckShort = DeckType(Six) // DeckManila is a deck of 32 playing cards of rank 7+ (see [Manila]). DeckManila = DeckType(Seven) // DeckSpanish is a deck of 28 playing cards of rank 8+ (see [Spanish]). DeckSpanish = DeckType(Eight) // DeckRoyal is a deck of 20 playing cards of rank 10+ (see [Royal]). DeckRoyal = DeckType(Ten) // DeckKuhn is a deck of 3 playing cards, a [King], [Queen], and a [Jack] // (see [Kuhn]). DeckKuhn = DeckType(^uint8(0) - 1) // DeckLeduc is a deck of 6 playing cards, a [King], [Queen], and a [Jack] // of the [Spade] and [Heart] suits (see [Leduc]). DeckLeduc = DeckType(^uint8(0) - 2) )
Deck types.
const InvalidCard = ^Card(0)
InvalidCard is an invalid card.
const InvalidRank = ^Rank(0)
InvalidRank is an invalid card rank.
const InvalidSuit = ^Suit(0)
InvalidSuit is an invalid card suit.
Variables ¶
var AlternateEmoji = [4]string{
"♠️",
"♥️",
"🔷",
"☘️",
}
AlternateEmoji are alternate emoji pips.
Functions ¶
func CactusDesc ¶
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 ¶
FlushOverDesc writes a FlushOver description to f for the rank, best, and unused cards.
func HoldemStarting ¶
HoldemStarting returns the starting Holdem pockets.
func Init ¶
func Init()
Init inits the package level default variables. Must be manually called prior to using the package when built with the [noinit] build tag.
func LowballDesc ¶
LowballDesc writes a Lowball description to f for the rank, best, and unused cards.
func Order ¶
Order builds an ordered slice of indices for the provided evals, ordered by either Hi or Lo (per Eval.Comp), returning the slice of indices and a pivot into the indices indicating the winning vs losing position.
Pivot will always be 1 or higher when ordering by Hi's. When ordering by Lo's, if there are no valid (ie, qualified) evals, the returned pivot will be 0.
func RegisterDefaultTypes ¶
func RegisterDefaultTypes() error
RegisterDefaultTypes registers default types.
See DefaultTypes.
Types ¶
type BinGen ¶
type BinGen[T any] struct { // contains filtered or unexported fields }
BinGen is a binomial combination generator.
func NewBinGen ¶
NewBinGen creates a uninitialized binomial combination generator. The generator must be manually initialized by calling Init.
func NewBinGenInit ¶
NewBinGenInit creates and initializes a binomial combination generator using f and d.
func NewCombinGen ¶
NewCombinGen creates a binomial combination generator.
func NewCombinUnusedGen ¶
NewCombinUnusedGen creates a binomial combination generator that also copies the unused values.
type CalcOption ¶
type CalcOption func(interface{})
CalcOption is a calc option.
func WithActive ¶
func WithActive(active map[int]bool, folded bool) CalcOption
WithActive is a calc option to run with the active map and whether or not folded positions should be included.
func WithBoard ¶
func WithBoard(board []Card) CalcOption
WithBoard is a calc option to set the board.
func WithDeep ¶
func WithDeep(deep bool) CalcOption
WithDeep is a calc option to set whether the run should run deep calculations.
func WithDiscard ¶
func WithDiscard(discard bool) CalcOption
WithDiscard is a calc option to set whether the run's discarded cards should be excluded.
func WithOpponents ¶
func WithOpponents(opponents int) CalcOption
WithOpponents is a calc option to set the opponents.
func WithPocketsBoard ¶
func WithPocketsBoard(pockets [][]Card, board []Card) CalcOption
WithPocketsBoard is a calc option to run with the pockets, board.
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 FromRune ¶
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 ¶
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 ¶
Must parses common string representations of Card's contained in v, ignoring case and whitespace and panicing on any error.
Returns a single slice of all cards from all strings in v.
See Parse for overview of accepted string representations.
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 Parse ¶
Parse parses common string representations of Card's contained in v, ignoring case and whitespace.
Accepts the following:
- a rank followed by a suit (ex: "Ah", "ks", "10s", "Tc", "8d", "6c")
- a rank followed by a white or black unicode suit pip (ex: "J♤", "K♠")
- unicode playing card runes (ex: "🃆", "🂣").
Returns a single slice of all cards from all strings in v.
func (Card) Format ¶
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 (♤♡♢♧) e - rank (as in s) and the emoji pip (♠️ ❤️ ♦️ ♣️ ) (ex: K♠️ A❤️ ) E - emoji pip (as in e) without rank (♠️ ❤️ ♦️ ♣️ ) a - rank (as in s) and the alternate emoji pip (see [AlternateEmoji]) A - alternate emoji pip (see [AlternateEmoji]) 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 rank name
func (Card) KnightRune ¶
KnightRune returns the card's unicode playing card rune, substituting knights for Jack's.
func (Card) MarshalText ¶
MarshalText satisfies the encoding.TextMarshaler interface.
func (*Card) UnmarshalText ¶
UnmarshalText satisfies the encoding.TextUnmarshaler interface.
type Dealer ¶
type Dealer struct { TypeDesc Deck *Deck Count int Active map[int]bool Runs []*Run Results []*Result // contains filtered or unexported fields }
Dealer maintains deal state for a type, streets, deck, positions, runs, results, and wins. Use as a street and run iterator for a Type. See usage details in the package example.
func NewShuffledDealer ¶
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) BoardDiscard ¶
BoardDiscard returns the number of board cards to be discarded prior to dealing a board on the current street.
func (*Dealer) Calc ¶
Calc calculates the run odds, including whether or not to include folded positions.
func (*Dealer) ChangeRuns ¶
ChangeRuns changes the number of runs, returning true if successful.
func (*Dealer) Deactivate ¶
Deactivate deactivates positions, which will not be dealt further cards and will not be included during eval.
func (*Dealer) Deal ¶
Deal deals pocket and board cards for the street and run, discarding cards accordingly.
func (*Dealer) Format ¶
Format satisfies the fmt.Formatter interface.
func (*Dealer) HasBoard ¶
HasBoard returns true when one or more board cards are dealt for the current street.
func (*Dealer) HasPocket ¶
HasPocket returns true when one or more pocket cards are dealt for the current street.
func (*Dealer) Next ¶
Next iterates the current street and run, discarding cards prior to dealing additional pocket and board cards for each street and run. Returns true when there are at least 2 active positions for a Type having Max greater than 1 and when there are additional streets or runs.
func (*Dealer) Pocket ¶
Pocket returns the number of pocket cards to be dealt on the current street.
func (*Dealer) PocketDiscard ¶
PocketDiscard returns the number of cards to be discarded prior to dealing pockets on the current street.
func (*Dealer) PocketDraw ¶
PocketDraw returns the number of pocket cards that can be drawn on the current street.
type Deck ¶
type Deck struct {
// contains filtered or unexported fields
}
Deck is a set of playing cards.
func (*Deck) Draw ¶
Draw draws count 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) Limit ¶
Limit limits the cards for the deck, for use with card shoes composed of more than one deck of cards.
type DeckType ¶
type DeckType uint8
DeckType is a deck type.
func (DeckType) Format ¶
Format satisfies the fmt.Formatter interface.
func (DeckType) Shoe ¶
Shoe creates a card shoe composed of count number of decks of unshuffled cards.
func (DeckType) Unshuffled ¶
Unshuffled returns a set of the deck's unshuffled cards.
type DescType ¶
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' DescHigh DescType = 'h' DescThree DescType = '3' )
Description types.
func (DescType) Desc ¶
Desc writes a description to f for the rank, best, and unused cards.
Supported verbs:
d - rank formatted as a int (1, 3775, ...) e - best description, eval rank only (Two Pair, Pair, Flush, 7-Low, ...) s - best full description (Four of a Kind, Ace, kickers King) S - best description, no kickers u - unused cards with [CardFormatter] v - same as s
func (DescType) Format ¶
Format satisfies the fmt.Formatter interface.
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.
type Eval ¶
type Eval struct { Type Type HiRank EvalRank HiBest []Card HiUnused []Card LoRank EvalRank LoBest []Card LoUnused []Card }
Eval contains the eval results of a type's Hi/Lo.
func (*Eval) Format ¶
Format satisfies the fmt.Formatter interface.
type EvalFunc ¶
EvalFunc is a eval func.
func NewBadugiEval ¶
NewBadugiEval creates a Badugi eval func.
4 cards, low evaluation of separate suits All 4 face down pre-flop 3 rounds of player discards (up to 4)
func NewCactusEval ¶
NewCactusEval creates a Cactus eval func.
func NewEval ¶
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 NewHybridEval ¶
NewHybridEval creates a hybrid Cactus and TwoPlusTwo eval func, using RankCactus for 5 and 6 cards, and a TwoPlusTwo eval func for 7 cards.
Gives optimal performance when evaluating the best-5 of any 5, 6, or 7 cards of a combined pocket and board.
func NewJacksOrBetterEval ¶
NewJacksOrBetterEval creates a JacksOrBetter eval func, used for Video.
func NewLeducEval ¶
func NewLeducEval() EvalFunc
NewLeducEval creates a matching high card eval func.
func NewLowballEval ¶
NewLowballEval creates a Lowball eval func.
func NewMaxEval ¶
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 only when lower than max.
func NewModifiedEval ¶
func NewModifiedEval(hi RankFunc, base Rank, inv func(EvalRank) EvalRank, normalize, low bool) EvalFunc
NewModifiedEval creates a modified Cactus eval.
func NewOmahaEval ¶
func NewOmahaEval(hi RankFunc, base Rank, inv func(EvalRank) EvalRank, normalize, low bool) EvalFunc
NewOmahaEval creates a Omaha eval func.
Uses any 2 from 2, 3, 4, 5, or 6 pocket cards, and any 3 from 3, 4 or 5 board cards to make a best-5.
func NewSokoEval ¶
NewSokoEval creates a Soko eval func.
func NewSplitEval ¶
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 store the Lo value only when lower than max.
func NewThreeEval ¶
func NewThreeEval() EvalFunc
NewThreeEval creates a best-3 eval func.
Straight Flush Three of a Kind Straight Flush One Pair High Card
type EvalRank ¶
type EvalRank uint16
EvalRank is a 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) )
Eval ranks.
func CactusFast ¶
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 ¶
RankAceFiveLow is a A-to-5 low rank eval func. Ace's are low, Straight's and Flush's do not count.
func RankEightOrBetter ¶
RankEightOrBetter is a 8-or-better low rank eval func. Ace's are low, Straight's and Flush's do not count.
func RankLowball ¶
RankLowball is a Lowball (2-to-7) low rank eval func. Ace's are high, Straight's and Flush's count.
Works by adding 2 additional ranks for Ace-high StraightFlush's and Straight's.
See EvalRank.ToLowball.
func RankManila ¶
RankManila is a Manila rank eval func.
func RankRazz ¶
RankRazz is a Razz (A-to-5) low rank eval func. Ace's are low, Straight's and Flush's do not count.
When there is a Pair (or higher) of matching ranks, will be the inverted Cactus value.
func RankSoko ¶
RankSoko is a Soko rank eval func.
Has ranks to Cactus, adding a Four Flush and Four Straight that beat Pair's 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 ¶
RankSpanish is a Spanish rank eval func.
func (EvalRank) Format ¶
Format satisfies the fmt.Formatter interface.
func (EvalRank) FromFlushOver ¶
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 ¶
FromLowball converts a Lowball rank to a Cactus rank.
See EvalRank.ToLowball for a description of the operations performed.
func (EvalRank) ToFlushOver ¶
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 ¶
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 as follows:
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 ¶
type EvalType uint8
EvalType is a eval type.
const ( EvalCactus EvalType = 0 EvalJacksOrBetter EvalType = 'j' EvalShort EvalType = 't' EvalManila EvalType = 'm' EvalSpanish EvalType = 'p' EvalOmaha EvalType = 'o' EvalSoko EvalType = 'k' EvalLowball EvalType = 'l' EvalRazz EvalType = 'r' EvalBadugi EvalType = 'b' EvalHigh EvalType = 'h' EvalThree EvalType = '3' )
Eval types.
func (EvalType) Format ¶
Format satisfies the fmt.Formatter interface.
type ExpValue ¶
ExpValue is the result of a expected value calculation.
func NewExpValue ¶
NewExpValue creates a new expected value.
func StartingExpValue ¶
StartingExpValue returns the starting pocket expected value.
func (*ExpValue) Format ¶
Format satisfies the fmt.Formatter interface.
type ExpValueCalc ¶
type ExpValueCalc struct {
// contains filtered or unexported fields
}
ExpValueCalc is a expected value calculator.
Example ¶
package main import ( "context" "fmt" "github.com/cardrank/cardrank" ) func main() { pocket, board := cardrank.Must("Kh 3h"), cardrank.Must("Ah 8h 3c") expv, ok := cardrank.Holdem.ExpValue(context.Background(), pocket, cardrank.WithBoard(board)) if !ok { panic("unable to calculate expected value") } fmt.Println("expected value:", expv) }
Output: expected value: 75.6% (802371,13659/1070190)
func NewExpValueCalc ¶
func NewExpValueCalc(typ Type, pocket []Card, opts ...CalcOption) *ExpValueCalc
NewExpValueCalc creates a new expected value calculator.
func (*ExpValueCalc) Calc ¶
func (c *ExpValueCalc) Calc(ctx context.Context) (*ExpValue, bool)
Calc calculates the expected value.
func (*ExpValueCalc) NewExpValue ¶
func (c *ExpValueCalc) NewExpValue() *ExpValue
NewExpValue creates a new expected value.
type Formatter ¶
type Formatter []Card
Formatter wraps formatting a set of cards. Allows `go test` to function without disabling vet.
type Odds ¶
type Odds struct { // Total is the total number of outcomes. Total int // Counts is each position's outcome count for wins and splits. Counts []int // Outs are map of the available outs for a position. Outs []map[Card]bool }
Odds are calculated run odds.
func (*Odds) Format ¶
Format satisfies the fmt.Formatter interface.
type OddsCalc ¶
type OddsCalc struct {
// contains filtered or unexported fields
}
OddsCalc calculates run odds.
Example ¶
package main import ( "context" "fmt" "github.com/cardrank/cardrank" ) func main() { pockets := [][]cardrank.Card{ cardrank.Must("Ah As Jc Qs"), cardrank.Must("3h 2h Ks Tc"), } board := cardrank.Must("6h 6s Jh") odds, _, ok := cardrank.Omaha.Odds(context.Background(), pockets, board) if !ok { panic("unable to calculate odds") } for i := range pockets { fmt.Printf("%d: %*v\n", i, i, odds) } }
Output: 0: 66.1% (542/820) 1: 33.9% (278/820)
func NewOddsCalc ¶
func NewOddsCalc(typ Type, opts ...CalcOption) *OddsCalc
NewOddsCalc creates a new run odds calc.
type ParseError ¶
ParseError is a parse error.
func (*ParseError) Error ¶
func (err *ParseError) Error() string
Error satisfies the [error] interface.
func (*ParseError) Unwrap ¶
func (err *ParseError) Unwrap() error
Unwrap satisfies the errors.Unwrap interface.
type Rank ¶
type Rank uint8
Rank is a card rank.
Card ranks.
func (Rank) PluralName ¶
PluralName returns the card rank plural name.
func (Rank) StraightFlushName ¶
StraightFlushName returns the card rank StraightFlush name.
type RankFunc ¶
RankFunc returns the eval rank of 5 cards.
var ( // RankCactus is the default Cactus Kev func. RankCactus RankFunc )
type Result ¶
Result contains dealer eval results.
type Run ¶
Run holds pockets, and a Hi/Lo board for a deal.
type Shuffler ¶
Shuffler is an interface for a deck shuffler. Compatible with math/rand.Rand's Shuffle method.
type StreetDesc ¶
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 ¶
func HoldemStreets(pocket, discard, flop, turn, river int) []StreetDesc
HoldemStreets creates Holdem streets (Pre-Flop, Flop, Turn, and River).
func NumberedStreets ¶
func NumberedStreets(pockets ...int) []StreetDesc
NumberedStreets creates numbered streets (Ante, 1st, 2nd, ..., River) for each of the pockets.
func StudStreets ¶
func StudStreets() []StreetDesc
StudStreets creates Stud streets (Ante, 3rd, 4th, 5th, 6th, and River).
func (StreetDesc) Desc ¶
func (desc StreetDesc) Desc() string
Desc returns a description of the street.
type Suit ¶
type Suit uint8
Suit is a card suit.
func (Suit) AlternateEmoji ¶
ALterEmoji returns the card suit alternate pip emoji.
func (Suit) PluralName ¶
PluralName returns the card suit plural name.
func (Suit) UnicodeBlack ¶
UnicodeBlack returns the card suit black unicode pip rune.
func (Suit) UnicodeWhite ¶
UnicodeWhite returns the card suit white unicode pip rune.
type Type ¶
type Type uint16
Type wraps a registered type description (see TypeDesc), providing a standard way to use the DefaultTypes, or a custom type registered with RegisterType. DefaultTypes are registered by default unless using the noinit build tag.
Standard Types ¶
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 1 board card 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 Eight-or-better qualifier (see RankEightOrBetter) for the Lo.
Short is a Holdem variant using a Short deck of 36 cards, having only cards with ranks of 6+ (see DeckShort). Flush ranks over FullHouse.
Manila is a Holdem variant using a Manila deck of 32 cards, having only cards with ranks of 7+ (see DeckManila), forcing the use of the 2 pocket cards, adding a Drop street before the Flop, and with all 5 streets receiving 1 board card each. Flush ranks over FullHouse.
Spanish is a Holdem/Manila variant, using a Spanish deck of 28 cards, having only cards with ranks of 8+ (see DeckSpanish).
Royal is a Holdem variant using a Royal deck of 20 cards, having only cards with ranks of 10+ (see DeckRoyal).
Double is a Holdem variant having two separate Hi and Lo community boards.
Showtime is a Holdem variant where folded cards are shown.
Swap is a Holdem variant where up to 2 pocket cards may be drawn (exchanged) exactly once on the Flop, Turn, or River.
River is a Holdem variant that deals 1 pocket card on the River instead of to the community board, resulting in a total pocket of 3 cards and a community board of 4 cards. Any of the 3 pocket cards or 4 board cards may be used to create the best-5.
Dallas is Holdem variant that forces the use of the 2 pocket cards and any 3 of the 5 board cards to make the best-5. Comparable to Omaha, but with 2 pocket cards instead of 4.
Houston is a Holdem/Dallas variant with 3 pocket cards, instead of 2, where only 2 board cards are dealt on the Flop, instead of 3. Requires using 2 of the 3 pocket cards and any 3 of the 4 board cards to make the best-5. Comparable to 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 pocket cards can be drawn (exchanged) on the 6th street.
DrawHiLo is the Hi/Lo variant of Draw, using a Eight-or-better qualifier (see RankEightOrBetter) for the Lo.
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. 2 pocket cards are dealt down and 1 pocket card up on the Ante, and 1 additional pocket card dealt up on the 4th, 5th, and 6th streets, with 1 final additional pocket card dealt down on the 7th street.
StudHiLo is the Hi/Lo variant of Stud, using a Eight-or-better qualifier (see RankEightOrBetter) for the Lo.
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. 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 pocket cards can be drawn (exchanged) on the River. Uses a qualifier of a Jack's-or-better for Hi eval (see NewJacksOrBetterEval).
Omaha is a Holdem variant with 4 pocket cards instead of 2, requiring use of 2 of 4 the pocket cards and any 3 of the 5 board cards to make the best-5.
OmahaHiLo is the Hi/Lo variant of Omaha, using a Eight-or-better qualifier (see RankEightOrBetter) for the Lo.
OmahaDouble is a Omaha variant having two separate Hi and Lo community boards.
OmahaFive is a Holdem/Omaha variant with 5 pocket cards, requiring the use of 2 of the 5 pocket cards and any 3 of the 5 board cards to make the best-5.
OmahaSix is a Holdem/Omaha variant with 6 pocket cards, requiring the use of 2 of the 6 pocket cards and any 3 of the 5 board cards to make the best-5.
OmahaRoyal is a Omaha variant using a Royal deck of 20 cards, having only cards with ranks of 10+ (see DeckRoyal).
Courchevel is a OmahaFive variant, where 1 board card is dealt on the Pre-Flop, and only 2 board cards dealt on the Flop.
CourchevelHiLo is the Hi/Lo variant of Courchevel, using a Eight-or-better qualifier (see RankEightOrBetter) for the Lo.
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 Eight-or-better qualifier (see RankEightOrBetter) for the Lo.
Soko is a Stud/StudFive 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, with only a Ante and River streets where 2 pocket cards are dealt on the Ante, and 3 pocket cards are dealt, up, on the River.
SokoHiLo is the Hi/Lo variant of Soko, using a Eight-or-better qualifier (see RankEightOrBetter) for the Lo.
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 Two-to-Seven low inverted ranking system, where Ace's are always high, and non-Flush, and non-Straight lows are best. Up to 5 pocket cards may be drawn (exchanged) exactly once on either the 6th, 7th, or River streets.
LowballTriple is a Lowball variant, where up to 5 pocket cards may be drawn (exchanged) on any of the 6th, 7th, or River streets.
Razz is a Stud low variant, using a Ace-to-Five ranking (see RankRazz), where Ace's play low, and Flush's and Straight's do not affect ranking.
Badugi is a best-4 low non-matching-suit card game, 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) multiple times on the 5th, 6th, or River streets. See NewBadugiEval for more details.
Kuhn is a best high card game, using a 3 card deck (King, Queen, Jack), having 1 pocket card and no community board cards. Useful for game tree testing. See Kuhn poker.
Leduc is a best high card game, using a 6 card deck (King, Queen, Jack each of the Spade and Heart), having 1 pocket card and 1 community card. Useful for game tree testing. See Deepstack Leduc.
RhodeIsland is a best-3 card game that is simplified version of Holdem, using a standard deck of 52 cards (see DeckFrench), having 1 pocket card, and 1 community board cards dealt each on the Flop and Turn. Useful for game tree testing. See Gilpin & Sandholm.
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♥] [T♠ 8♥] 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
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 OmahaRoyal Type = 'O'<<8 | 'r' // Or 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 Kuhn Type = 'K'<<8 | 'u' // Ku Leduc Type = 'L'<<8 | 'e' // Le RhodeIsland Type = 'R'<<8 | 'I' // RI )
Types.
func (Type) BoardDiscard ¶
BoardDiscard returns the type's total board discard.
func (Type) Deal ¶
Deal creates a new dealer for the type, shuffling the deck by shuffles, returning the specified pocket count and Hi board.
func (Type) Dealer ¶
Dealer creates a new dealer with a deck shuffled by shuffles, with specified pocket count.
func (Type) EvalPockets ¶
EvalPockets creates new evals for the type, evaluating each of the pockets and board.
func (Type) ExpValue ¶
ExpValue calculates expected value for a single pocket. Use WithBoard to pass a board.
func (Type) Format ¶
Format satisfies the fmt.Formatter interface.
func (Type) MarshalText ¶
MarshalText satisfies the encoding.TextMarshaler interface.
func (Type) Odds ¶
func (typ Type) Odds(ctx context.Context, pockets [][]Card, board []Card, opts ...CalcOption) (*Odds, *Odds, bool)
Odds calculates the odds for the pockets, board.
func (Type) PocketDiscard ¶
PocketDiscard returns the type's total pocket discard.
func (Type) Streets ¶
func (typ Type) Streets() []StreetDesc
Streets returns the type's street descriptions.
func (*Type) UnmarshalText ¶
UnmarshalText satisfies the encoding.TextUnmarshaler interface.
type TypeDesc ¶
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 enabling the Hi/Lo variant, with an 8-or-better // evaluated Lo. Low bool // Double is true when there are double community boards where the first // and second board is evaluated as the Hi and Lo, respectively. 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 description type. HiDesc DescType // LoDesc is the Lo description type. LoDesc DescType // contains filtered or unexported fields }
TypeDesc is a type description.
func DefaultTypes ¶
func DefaultTypes() []TypeDesc
DefaultTypes returns the default type descriptions. The returned TypeDesc's will be automatically registered, unless using the noinit tag.
func NewType ¶
NewType creates a new type description. Created type descriptions must be registered with RegisterType before being used for eval.
func (*TypeDesc) Apply ¶
func (desc *TypeDesc) Apply(opts ...StreetOption)
Apply applies street options.
type TypeOption ¶
type TypeOption func(*TypeDesc)
TypeOption is a type description option.
func WithBadugi ¶
func WithBadugi(opts ...StreetOption) TypeOption
WithBadugi is a type description option to set Badugi definitions.
func WithCourchevel ¶
func WithCourchevel(low bool, opts ...StreetOption) TypeOption
WithCourchevel is a type description option to set Courchevel definitions.
func WithDallas ¶
func WithDallas(low bool, opts ...StreetOption) TypeOption
WithDallas is a type description option to set Dallas definitions.
func WithDouble ¶
func WithDouble(opts ...StreetOption) TypeOption
WithDouble is a type description option to set Double definitions.
func WithDraw ¶
func WithDraw(low bool, opts ...StreetOption) TypeOption
WithDraw is a type description option to set Draw definitions.
func WithFusion ¶
func WithFusion(low bool, opts ...StreetOption) TypeOption
WithFusion is a type description option to set Fusion definitions.
func WithHoldem ¶
func WithHoldem(low bool, opts ...StreetOption) TypeOption
WithHoldem is a type description option to set Holdem definitions.
func WithHouston ¶
func WithHouston(low bool, opts ...StreetOption) TypeOption
WithHouston is a type description option to set Houston definitions.
func WithKuhn ¶
func WithKuhn(opts ...StreetOption) TypeOption
WithKuhn is a type description option to set Kuhn definitions.
func WithLeduc ¶
func WithLeduc(opts ...StreetOption) TypeOption
WithLeduc is a type description option to set Leduc definitions.
func WithLowball ¶
func WithLowball(multi bool, opts ...StreetOption) TypeOption
WithLowball is a type description option to set Lowball definitions.
func WithManila ¶
func WithManila(opts ...StreetOption) TypeOption
WithManila is a type description option to set Manila definitions.
func WithOmaha ¶
func WithOmaha(low bool, opts ...StreetOption) TypeOption
WithOmaha is a type description option to set Omaha definitions.
func WithOmahaDouble ¶
func WithOmahaDouble(opts ...StreetOption) TypeOption
WithOmahaDouble is a type description option to set OmahaDouble definitions.
func WithOmahaFive ¶
func WithOmahaFive(low bool, opts ...StreetOption) TypeOption
WithOmahaFive is a type description option to set OmahaFive definitions.
func WithOmahaRoyal ¶
func WithOmahaRoyal(opts ...StreetOption) TypeOption
WithOmahaRoyal is a type description option to set OmahaRoyal definitions.
func WithOmahaSix ¶
func WithOmahaSix(low bool, opts ...StreetOption) TypeOption
WithOmahaSix is a type description option to set OmahaSix definitions.
func WithRazz ¶
func WithRazz(opts ...StreetOption) TypeOption
WithRazz is a type description option to set Razz definitions.
func WithRhodeIsland ¶
func WithRhodeIsland(opts ...StreetOption) TypeOption
WithRhodeIsland is a type description option to set RhodeIsland definitions.
func WithRiver ¶
func WithRiver(low bool, opts ...StreetOption) TypeOption
WithRiver is a type description option to set River definitions.
func WithRoyal ¶
func WithRoyal(opts ...StreetOption) TypeOption
WithRoyal is a type description option to set Royal definitions.
func WithShort ¶
func WithShort(opts ...StreetOption) TypeOption
WithShort is a type description option to set Short definitions.
func WithShowtime ¶
func WithShowtime(low bool, opts ...StreetOption) TypeOption
WithShowtime is a type description option to set Showtime definitions.
func WithSoko ¶
func WithSoko(low bool, opts ...StreetOption) TypeOption
WithSoko is a type description option to set Soko definitions.
func WithSpanish ¶
func WithSpanish(opts ...StreetOption) TypeOption
WithSpanish is a type description option to set Spanish definitions.
func WithStud ¶
func WithStud(low bool, opts ...StreetOption) TypeOption
WithStud is a type description option to set Stud definitions.
func WithStudFive ¶
func WithStudFive(low bool, opts ...StreetOption) TypeOption
WithStudFive is a type description option to set StudFive definitions.
func WithSwap ¶
func WithSwap(low bool, opts ...StreetOption) TypeOption
WithSwap is a type description option to set Swap definitions.
func WithVideo ¶
func WithVideo(low bool, opts ...StreetOption) TypeOption
WithVideo is a type description option to set Video definitions.