This commit is contained in:
Jeffrey Paul 2024-05-18 23:55:15 -07:00
parent 6c66adf8d3
commit e26b79751f

158
card.go
View File

@ -19,55 +19,52 @@ func NewCardFromString(card string) (Card, error) {
// FIXME extend this later to common format strings like "9s" // FIXME extend this later to common format strings like "9s"
length := utf8.RuneCountInString(card) length := utf8.RuneCountInString(card)
if length != 2 { if length != 2 {
return Card{}, fmt.Errorf("Invalid card string %s", card) return Card{}, fmt.Errorf("invalid card string %s, must be 2 characters", card)
}
var rank Rank
var suit Suit
if strings.ContainsRune(card, rune(SPADE)) {
suit = Suit(SPADE)
} else if strings.ContainsRune(card, rune(HEART)) {
suit = Suit(HEART)
} else if strings.ContainsRune(card, rune(DIAMOND)) {
suit = Suit(DIAMOND)
} else if strings.ContainsRune(card, rune(CLUB)) {
suit = Suit(CLUB)
} else {
return Card{}, fmt.Errorf("Invalid card string %s", card)
} }
if strings.ContainsRune(card, rune(DEUCE)) { rankMap := map[rune]Rank{
rank = Rank(DEUCE) rune(DEUCE): DEUCE,
} else if strings.ContainsRune(card, rune(THREE)) { rune(THREE): THREE,
rank = Rank(THREE) rune(FOUR): FOUR,
} else if strings.ContainsRune(card, rune(FOUR)) { rune(FIVE): FIVE,
rank = Rank(FOUR) rune(SIX): SIX,
} else if strings.ContainsRune(card, rune(FIVE)) { rune(SEVEN): SEVEN,
rank = Rank(FIVE) rune(EIGHT): EIGHT,
} else if strings.ContainsRune(card, rune(SIX)) { rune(NINE): NINE,
rank = Rank(SIX) rune(TEN): TEN,
} else if strings.ContainsRune(card, rune(SEVEN)) { rune(JACK): JACK,
rank = Rank(SEVEN) rune(QUEEN): QUEEN,
} else if strings.ContainsRune(card, rune(EIGHT)) { rune(KING): KING,
rank = Rank(EIGHT) rune(ACE): ACE,
} else if strings.ContainsRune(card, rune(NINE)) { }
rank = Rank(NINE)
} else if strings.ContainsRune(card, rune(TEN)) { suitMap := map[rune]Suit{
rank = Rank(TEN) rune(SPADE): SPADE,
} else if strings.ContainsRune(card, rune(JACK)) { rune(HEART): HEART,
rank = Rank(JACK) rune(DIAMOND): DIAMOND,
} else if strings.ContainsRune(card, rune(QUEEN)) { rune(CLUB): CLUB,
rank = Rank(QUEEN) }
} else if strings.ContainsRune(card, rune(KING)) {
rank = Rank(KING) var rank Rank
} else if strings.ContainsRune(card, rune(ACE)) { var suit Suit
rank = Rank(ACE) for r := range rankMap {
} else { if strings.ContainsRune(card, r) {
return Card{}, fmt.Errorf("Invalid card string %s", card) rank = rankMap[r]
break
}
}
for s := range suitMap {
if strings.ContainsRune(card, s) {
suit = suitMap[s]
break
}
} }
if rank == Rank(0) || suit == Suit(0) { if rank == Rank(0) || suit == Suit(0) {
return Card{}, fmt.Errorf("Invalid card string %s", card) return Card{}, fmt.Errorf("invalid card string %s", card)
} }
return Card{Rank: rank, Suit: suit}, nil return Card{Rank: rank, Suit: suit}, nil
} }
@ -75,18 +72,17 @@ func NewCardsFromString(cards string) (Cards, error) {
// supports a string like 9♠,9♣,Q♥,Q♦,K♣ // supports a string like 9♠,9♣,Q♥,Q♦,K♣
// FIXME extend this later to common format strings like "9c Qh Qd Kc" // FIXME extend this later to common format strings like "9c Qh Qd Kc"
// with or without commas // with or without commas
var newCards Cards
newCards = make(Cards, 0)
cardStrings := strings.Split(cards, ",") cardStrings := strings.Split(cards, ",")
for _, cardString := range cardStrings { newCards := make(Cards, len(cardStrings))
for i, cardString := range cardStrings {
card, err := NewCardFromString(cardString) card, err := NewCardFromString(cardString)
if err != nil { if err != nil {
return Cards{}, err return nil, err
} }
newCards = append(newCards, card) newCards[i] = card
} }
if len(newCards) == 0 { if len(newCards) == 0 {
return Cards{}, fmt.Errorf("No cards found in string %s", cards) return nil, fmt.Errorf("no cards found in string %s", cards)
} }
return newCards, nil return newCards, nil
} }
@ -97,42 +93,41 @@ func (c *Card) String() string {
type Cards []Card type Cards []Card
func (c Cards) First() Card { func (cards Cards) First() Card {
return c[0] return cards[0]
} }
func (c Cards) Second() Card { func (cards Cards) Second() Card {
return c[1] return cards[1]
} }
func (c Cards) Third() Card { func (cards Cards) Third() Card {
return c[2] return cards[2]
} }
func (c Cards) Fourth() Card { func (cards Cards) Fourth() Card {
return c[3] return cards[3]
} }
func (c Cards) Fifth() Card { func (cards Cards) Fifth() Card {
return c[4] return cards[4]
} }
func (c Cards) Last() Card { func (cards Cards) Last() Card {
return c[len(c)-1] return cards[len(cards)-1]
} }
func (c Cards) SortByRankAscending() Cards { func (cards Cards) SortByRankAscending() Cards {
newCards := make(Cards, len(c)) sortedCards := make(Cards, len(cards))
copy(newCards, c) copy(sortedCards, cards)
sort.Slice(newCards, func(i, j int) bool { sort.Slice(sortedCards, func(i, j int) bool {
return newCards[i].Rank.Score() < newCards[j].Rank.Score() return sortedCards[i].Rank.Score() < sortedCards[j].Rank.Score()
}) })
return sortedCards
return newCards
} }
func (c Cards) PrintToTerminal() { func (cards Cards) PrintToTerminal() {
fmt.Printf("%s", c.FormatForTerminal()) fmt.Printf("%s", cards.FormatForTerminal())
} }
type SortOrder int type SortOrder int
@ -142,18 +137,18 @@ const (
AceHighDescending AceHighDescending
) )
func (c Cards) FormatForTerminalSorted(order SortOrder) string { func (cards Cards) FormatForTerminalSorted(order SortOrder) string {
sorted := c.SortByRankAscending() // this is ascending sorted := cards.SortByRankAscending() // this is ascending
if order == AceHighDescending { if order == AceHighDescending {
slices.Reverse(sorted) slices.Reverse(sorted)
} }
return sorted.FormatForTerminal() return sorted.FormatForTerminal()
} }
func (c Cards) FormatForTerminal() string { func (cards Cards) FormatForTerminal() string {
var cardstrings []string var cardstrings []string
for i := 0; i < len(c); i++ { for i := 0; i < len(cards); i++ {
cardstrings = append(cardstrings, c[i].FormatForTerminal()) cardstrings = append(cardstrings, cards[i].FormatForTerminal())
} }
return strings.Join(cardstrings, ",") return strings.Join(cardstrings, ",")
} }
@ -178,16 +173,15 @@ func (c Card) FormatForTerminal() string {
return fmt.Sprintf("%s%s", rank, suit) return fmt.Sprintf("%s%s", rank, suit)
} }
func (c Cards) HighestRank() Rank { func (cards Cards) HighestRank() Rank {
sorted := c.SortByRankAscending() sorted := cards.SortByRankAscending()
return sorted[len(sorted)-1].Rank return sorted[len(sorted)-1].Rank
} }
func (s Cards) String() (output string) { func (cards Cards) String() string {
var cardstrings []string var cardstrings []string
for i := 0; i < len(s); i++ { for i := 0; i < len(cards); i++ {
cardstrings = append(cardstrings, s[i].String()) cardstrings = append(cardstrings, cards[i].String())
} }
output = strings.Join(cardstrings, ",") return strings.Join(cardstrings, ",")
return output
} }