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