195 lines
3.8 KiB
Go
195 lines
3.8 KiB
Go
package pokercore
|
|
|
|
import (
|
|
"fmt"
|
|
"slices"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/logrusorgru/aurora/v4"
|
|
)
|
|
|
|
type Card struct {
|
|
Rank Rank
|
|
Suit Suit
|
|
}
|
|
|
|
func NewRankFromString(rank string) Rank {
|
|
switch rank {
|
|
case "2":
|
|
return Rank(DEUCE)
|
|
case "3":
|
|
return Rank(THREE)
|
|
case "4":
|
|
return Rank(FOUR)
|
|
case "5":
|
|
return Rank(FIVE)
|
|
case "6":
|
|
return Rank(SIX)
|
|
case "7":
|
|
return Rank(SEVEN)
|
|
case "8":
|
|
return Rank(EIGHT)
|
|
case "9":
|
|
return Rank(NINE)
|
|
case "T":
|
|
return Rank(TEN)
|
|
case "J":
|
|
return Rank(JACK)
|
|
case "Q":
|
|
return Rank(QUEEN)
|
|
case "K":
|
|
return Rank(KING)
|
|
case "A":
|
|
return Rank(ACE)
|
|
}
|
|
return Rank(0)
|
|
}
|
|
|
|
func NewSuitFromString(suit string) Suit {
|
|
switch suit {
|
|
case string(SPADE):
|
|
return Suit(SPADE)
|
|
case string(CLUB):
|
|
return Suit(CLUB)
|
|
case string(HEART):
|
|
return Suit(HEART)
|
|
case string(DIAMOND):
|
|
return Suit(DIAMOND)
|
|
}
|
|
return Suit(0)
|
|
}
|
|
|
|
func NewCardFromString(card string) (Card, error) {
|
|
// FIXME extend this later to common format strings like "9s"
|
|
if len(card) != 2 {
|
|
return Card{}, fmt.Errorf("Invalid card string %s", card)
|
|
}
|
|
rank := NewRankFromString(card[0:1])
|
|
suit := NewSuitFromString(card[1:2])
|
|
if rank == Rank(0) || suit == Suit(0) {
|
|
return Card{}, fmt.Errorf("Invalid card string %s", card)
|
|
}
|
|
return Card{Rank: rank, Suit: suit}, nil
|
|
}
|
|
|
|
func NewCardsFromString(cards string) (Cards, error) {
|
|
// supports a string like 9♠,9♣,Q♥,Q♦,K♣
|
|
// FIXME extend this later to common format strings like "9c Qh Qd Kc"
|
|
// with or without commas
|
|
var newCards Cards
|
|
cardStrings := strings.Split(cards, ",")
|
|
for _, cardString := range cardStrings {
|
|
card, err := NewCardFromString(cardString)
|
|
if err != nil {
|
|
return Cards{}, err
|
|
}
|
|
newCards = append(newCards, card)
|
|
}
|
|
if len(newCards) == 0 {
|
|
return Cards{}, fmt.Errorf("No cards found in string %s", cards)
|
|
}
|
|
return newCards, nil
|
|
}
|
|
|
|
func (c *Card) String() string {
|
|
return fmt.Sprintf("%s%s", string(c.Rank), string(c.Suit))
|
|
}
|
|
|
|
type Cards []Card
|
|
|
|
func (c Cards) First() Card {
|
|
return c[0]
|
|
}
|
|
|
|
func (c Cards) Second() Card {
|
|
return c[1]
|
|
}
|
|
|
|
func (c Cards) Third() Card {
|
|
return c[2]
|
|
}
|
|
|
|
func (c Cards) Fourth() Card {
|
|
return c[3]
|
|
}
|
|
|
|
func (c Cards) Fifth() Card {
|
|
return c[4]
|
|
}
|
|
|
|
func (c Cards) Last() Card {
|
|
return c[len(c)-1]
|
|
}
|
|
|
|
func (c Cards) SortByRankAscending() Cards {
|
|
newCards := make(Cards, len(c))
|
|
copy(newCards, c)
|
|
sort.Slice(newCards, func(i, j int) bool {
|
|
return newCards[i].Rank.Score() < newCards[j].Rank.Score()
|
|
})
|
|
|
|
return newCards
|
|
}
|
|
|
|
func (c Cards) PrintToTerminal() {
|
|
fmt.Printf("%s", c.FormatForTerminal())
|
|
}
|
|
|
|
type SortOrder int
|
|
|
|
const (
|
|
AceHighAscending SortOrder = iota
|
|
AceHighDescending
|
|
)
|
|
|
|
func (c Cards) FormatForTerminalSorted(order SortOrder) string {
|
|
sorted := c.SortByRankAscending() // this is ascending
|
|
if order == AceHighDescending {
|
|
slices.Reverse(sorted)
|
|
}
|
|
return sorted.FormatForTerminal()
|
|
}
|
|
|
|
func (c Cards) FormatForTerminal() string {
|
|
var cardstrings []string
|
|
for i := 0; i < len(c); i++ {
|
|
cardstrings = append(cardstrings, c[i].FormatForTerminal())
|
|
}
|
|
return strings.Join(cardstrings, ",")
|
|
}
|
|
|
|
func (c Card) FormatForTerminal() string {
|
|
var rank string
|
|
var suit string
|
|
color := aurora.Red
|
|
switch c.Suit {
|
|
case Suit(DIAMOND):
|
|
color = aurora.Blue
|
|
case Suit(HEART):
|
|
color = aurora.Red
|
|
case Suit(CLUB):
|
|
color = aurora.Green
|
|
case Suit(SPADE):
|
|
color = aurora.Black
|
|
}
|
|
|
|
rank = fmt.Sprintf("%s", aurora.Bold(color(c.Rank.Symbol())))
|
|
suit = fmt.Sprintf("%s", aurora.Bold(color(c.Suit.Symbol())))
|
|
return fmt.Sprintf("%s%s", rank, suit)
|
|
}
|
|
|
|
func (c Cards) HighestRank() Rank {
|
|
sorted := c.SortByRankAscending()
|
|
return sorted[len(sorted)-1].Rank
|
|
}
|
|
|
|
func (s Cards) String() (output string) {
|
|
var cardstrings []string
|
|
for i := 0; i < len(s); i++ {
|
|
cardstrings = append(cardstrings, s[i].String())
|
|
}
|
|
output = strings.Join(cardstrings, ",")
|
|
return output
|
|
}
|