cardrank

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 22, 2022 License: MIT Imports: 9 Imported by: 0

README

cardrank

Package cardrank provides types and utilities for working with playing cards and evaluating poker hands.

Using

See Go documentation.

Documentation

Overview

Package cardrank provides types and utilities for working with playing cards and evaluating poker hands.

Example (Holdem)
package main

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

	"cardrank.io/cardrank"
)

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

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

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

	"cardrank.io/cardrank"
)

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

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

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

	"cardrank.io/cardrank"
)

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

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

Index

Examples

Constants

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

Unicode card runes.

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

Variables

This section is empty.

Functions

func CactusMaps

func CactusMaps() (map[uint32]uint16, map[uint32]uint16)

CactusMaps builds the cactus flush and unique5 maps.

func NewHybridRanker

func NewHybridRanker(f RankerFunc, f7 func([]Card) HandRank) func([]Card) HandRank

NewHybridRanker creates a hybrid ranker.

func OrderHands

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

OrderHands orders hands by rank, low to high, returning 'pivot' of winning vs losing hands.

func PlayingCardKnightRune

func PlayingCardKnightRune(r Rank, s Suit) rune

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

func PlayingCardRune

func PlayingCardRune(r Rank, s Suit) rune

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

Types

type Card

type Card uint32

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

Example (Unmarshal)
package main

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

	"cardrank.io/cardrank"
)

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

[3s 4c 5c Ah 2d]

func FromRune

func FromRune(r rune) (Card, error)

FromRune creates a card from a unicode playing card rune.

Example
package main

import (
	"fmt"
	"log"

	"cardrank.io/cardrank"
)

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

A♠

func FromString

func FromString(str string) (Card, error)

FromString creates a card from a string.

func Must

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

Must creates a hand from v.

func MustCard

func MustCard(s string) Card

MustCard creates card from s.

Example
package main

import (
	"fmt"

	"cardrank.io/cardrank"
)

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

Ace of Hearts (A♥)

func New

func New(r Rank, s Suit) Card

New creates a card for the specified rank and suit.

func Parse

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

Parse parses card representations in v.

func Unshuffled

func Unshuffled() []Card

Unshuffled generates an unshuffled set of standard playing cards.

func UnshuffledExclude

func UnshuffledExclude(exclude []Card) []Card

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

func UnshuffledShortDeck

func UnshuffledShortDeck() []Card

UnshuffledShortDeck generates an unshuffled set of short deck cards (ie, excluding card ranks 2 through 5).

func (Card) BitRank

func (c Card) BitRank() uint32

BitRank returns the bit rank of the card.

func (Card) Format

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

Format satisfies the fmt.Formatter interface.

Supported verbs:

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

func (Card) MarshalText

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

MarshalText satisfies the encoding.TextMarshaler interface.

func (Card) Prime

func (c Card) Prime() uint32

Prime returns the prime value of the card.

func (Card) Rank

func (c Card) Rank() Rank

Rank returns the rank of the card.

func (Card) RankByte

func (c Card) RankByte() byte

RankByte returns the rank byte of the card.

func (Card) RankIndex

func (c Card) RankIndex() int

RankIndex returns the rank index of the card.

func (Card) String

func (c Card) String() string

String satisfies the fmt.Stringer interface.

func (Card) Suit

func (c Card) Suit() Suit

Suit returns the suit of the card.

func (Card) SuitByte

func (c Card) SuitByte() byte

SuitByte returns the suit byte of the card.

func (Card) SuitIndex

func (c Card) SuitIndex() int

SuitIndex returns the suit index of the card.

func (*Card) UnmarshalText

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

UnmarshalText satisfies the encoding.TextUnmarshaler interface.

type Deck

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

Deck is a set of playing cards.

func NewDeck

func NewDeck(cards ...Card) *Deck

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

func NewDeckShoe

func NewDeckShoe(n int) *Deck

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

func NewShortDeck

func NewShortDeck() *Deck

NewShortDeck creates a new deck of short cards.

func (*Deck) Board

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

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

func (*Deck) Deal

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

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

func (*Deck) Draw

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

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

Example
package main

import (
	"fmt"
	"math/rand"

	"cardrank.io/cardrank"
)

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

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

func (*Deck) Empty

func (d *Deck) Empty() bool

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

func (*Deck) Holdem

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

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

func (*Deck) HoldemSimple

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

HoldemSimple draws hands for Texas Holdem, returning the set of pockets (one per hand) and board cards. Useful for examples. Deals 5 board cards prior to dealing pocket cards for each hand.

func (*Deck) Omaha

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

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

func (*Deck) OmahaSimple

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

OmahaSimple draws hands for Omaha, returning the set of pockets (one per hand) and board cards. Useful for examples. Deals 5 board cards prior to dealing pocket cards for each hand.

func (*Deck) Remaining

func (d *Deck) Remaining() int

Remaining returns the number of remaining cards in the deck.

func (*Deck) SetLimit

func (d *Deck) SetLimit(limit int)

SetLimit sets a limit for the deck.

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

func (*Deck) Shuffle

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

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

func (*Deck) ShuffleN

func (d *Deck) ShuffleN(f func(n int, swap func(i, j int)), n int)

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

func (*Deck) Simple

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

Simple draws board cards and hands of n cards. Useful for examples.

type Error

type Error string

Error is a error.

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

Error values.

func (Error) Error

func (err Error) Error() string

Error satisfies the error interface.

type Hand

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

Hand is a poker hand.

func NewHand

func NewHand(pocket, board []Card, f func([]Card) HandRank) *Hand

NewHand creates a new poker hand.

Example
package main

import (
	"fmt"
	"math/rand"

	"cardrank.io/cardrank"
)

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

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

func NewHandOf

func NewHandOf(typ Type, pocket, board []Card, f func([]Card) HandRank) *Hand

NewHandOf creates a new poker hand of the specified type.

func (*Hand) Best

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

Best returns the poker hand's best-five cards.

func (*Hand) Board

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

Board returns the poker hand's board.

func (*Hand) Compare

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

Compare compares the hand ranks.

func (*Hand) Description

func (h *Hand) Description() string

Description describes the hand's best-five cards.

Examples:

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

func (*Hand) Fixed

func (h *Hand) Fixed() HandRank

Fixed returns the poker hand's fixed rank.

func (*Hand) Format

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

Format satisfies the fmt.Formatter interface.

func (*Hand) Hand

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

Hand returns the poker hand's hand.

func (*Hand) Pocket

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

Pocket returns the poker hand's pocket.

func (*Hand) Rank

func (h *Hand) Rank() HandRank

Rank returns the poker hand's rank.

func (*Hand) Type

func (h *Hand) Type() Type

Type returns the poker hand's type.

func (*Hand) Unused

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

Unused returns the hand's unused cards.

type HandFormatter

type HandFormatter []Card

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

func (HandFormatter) Format

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

Format satisfies the fmt.Formatter interface.

type HandRank

type HandRank uint16

HandRank is a poker hand rank.

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

Poker hand rank values.

func (HandRank) Fixed

func (r HandRank) Fixed() HandRank

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

func (HandRank) Name

func (r HandRank) Name() string

Name returns the hand rank name.

func (HandRank) String

func (r HandRank) String() string

String satisfies the fmt.Stringer interface.

type Rank

type Rank uint8

Rank is a card rank.

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

Card ranks.

func RankFromRune

func RankFromRune(r rune) (Rank, error)

RankFromRune returns the card rank for the rune.

func (Rank) Byte

func (r Rank) Byte() byte

Byte returns the byte representation for the card rank.

func (Rank) Index

func (r Rank) Index() int

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

func (Rank) Name

func (r Rank) Name() string

Name returns the name of the card rank.

func (Rank) PluralName

func (r Rank) PluralName() string

PluralName returns the plural name of the card rank.

func (Rank) String

func (r Rank) String() string

String satisfies the fmt.Stringer interface.

type Ranker

type Ranker int

Ranker are the types of hand rankers.

const (
	Cactus Ranker = iota
	CactusFast
	TwoPlus
	Hybrid
	ShortDeckFast
)

Ranker values.

func (Ranker) Available

func (r Ranker) Available() bool

Available indicates if the ranker is available.

func (Ranker) Rank

func (r Ranker) Rank(hand []Card) HandRank

Rank ranks the hand.

func (Ranker) String

func (r Ranker) String() string

String satisfies the fmt.Stringer interface.

type RankerFunc

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

RankerFunc is a wrapper for ranking funcs.

func NewCactusFastRanker

func NewCactusFastRanker() RankerFunc

NewCactusFastRanker creates a new cactus fast short deck hand ranker.

func NewCactusRanker

func NewCactusRanker() RankerFunc

NewCactusRanker creates a cactus hand ranker.

func NewShortDeckRanker

func NewShortDeckRanker(f RankerFunc) RankerFunc

NewShortDeckRanker creates a new cactus fast short deck hand ranker.

func (RankerFunc) Rank

func (f RankerFunc) Rank(hand []Card) HandRank

Rank satisfies the Ranker interface.

type Suit

type Suit uint8

Suit is a card suit.

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

Card suits.

func SuitFromRune

func SuitFromRune(r rune) (Suit, error)

SuitFromRune returns the card suit for the rune.

func (Suit) Byte

func (s Suit) Byte() byte

Byte returns the byte representation for the card suit.

func (Suit) Index

func (s Suit) Index() int

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

func (Suit) Name

func (s Suit) Name() string

Name returns the name of the card suit.

func (Suit) PluralName

func (s Suit) PluralName() string

PluralName returns the plural name of the card suit.

func (Suit) String

func (s Suit) String() string

String satisfies the fmt.Stringer interface.

func (Suit) UnicodeBlack

func (s Suit) UnicodeBlack() rune

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

func (Suit) UnicodeWhite

func (s Suit) UnicodeWhite() rune

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

type TwoPlusRanker

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

TwoPlusRanker is a two plus hand ranker.

func NewTwoPlusRanker

func NewTwoPlusRanker() *TwoPlusRanker

NewTwoPlusRanker creates a new two plus hand ranker.

func (*TwoPlusRanker) Rank

func (p *TwoPlusRanker) Rank(hand []Card) HandRank

Rank satisfies the Ranker interface.

type Type

type Type uint32

Type is a type of game.

const (
	Holdem    Type = 0x0010
	ShortDeck Type = 0x0011
	Omaha     Type = 0x0100
	OmahaHiLo Type = 0x0101
	Stud      Type = 0x1000
	StudHiLo  Type = 0x1001
	Razz      Type = 0x1010
)

Type values.

func (Type) Best

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

Best returns the best hand and rank for the provided pocket, board using f to evaluate ranks of possible hands.

func (Type) Deal

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

Deal deals cards for the type.

func (Type) Deck

func (typ Type) Deck() *Deck

NewDeck returns a new deck for the type.

func (Type) Max

func (typ Type) Max() int

Max returns the max players for the type.

func (Type) MultiShuffleDeal

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

MultiShuffleDeal shuffles a deck multiple times and deals cards for the type.

func (Type) RankHand

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

RankHand ranks the hand.

func (Type) RankHands

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

RankHands ranks the hands.

func (Type) String

func (typ Type) String() string

String satisfies the fmt.Stringer interface.

Jump to

Keyboard shortcuts

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