overte-api/poker/eval.go
2026-03-17 20:17:36 -07:00

71 lines
1.9 KiB
Go

package poker
import (
"sort"
gopoker "github.com/chehsunliu/poker"
)
// HandRank evaluates the best 5-card hand from the given cards (hole + community).
// Returns a rank value where lower is better (1 = royal flush).
func HandRank(cards []string) int32 {
gocards := make([]gopoker.Card, len(cards))
for i, c := range cards {
gocards[i] = gopoker.NewCard(c)
}
return gopoker.Evaluate(gocards)
}
// HandDescription returns a human-readable description of the best hand.
func HandDescription(cards []string) string {
gocards := make([]gopoker.Card, len(cards))
for i, c := range cards {
gocards[i] = gopoker.NewCard(c)
}
return gopoker.RankString(gopoker.Evaluate(gocards))
}
// Winner represents a player and their hand rank at showdown.
type Winner struct {
Username string
Rank int32
Desc string
}
// Showdown evaluates all active players' hands against the community cards
// and returns winners sorted best to worst. Ties are included.
// hands maps username -> []string of hole cards (2 cards).
// community is the board (3-5 cards).
func Showdown(hands map[string][]string, community []string) []Winner {
results := make([]Winner, 0, len(hands))
for username, hole := range hands {
all := append(hole, community...)
rank := HandRank(all)
results = append(results, Winner{
Username: username,
Rank: rank,
Desc: HandDescription(all),
})
}
// Sort ascending — lower rank value = better hand
sort.Slice(results, func(i, j int) bool {
return results[i].Rank < results[j].Rank
})
return results
}
// Winners returns only the players who tied for best hand.
func Winners(hands map[string][]string, community []string) []Winner {
all := Showdown(hands, community)
if len(all) == 0 {
return nil
}
best := all[0].Rank
var winners []Winner
for _, w := range all {
if w.Rank == best {
winners = append(winners, w)
}
}
return winners
}