// Simple design exercise: represent a deck of cards for blackjack. package main import ( "math/rand" "fmt" "os" ) type Card int8 type Suit int8 const ( Spades Suit = iota Hearts Clubs Diamonds ) type Rank int8 // 1 = ace, 2 = deuce, 10 = 10, 11 = jack, etc. func (c Card) Suit() Suit { return Suit(c / 13) } func (c Card) Rank() Rank { return Rank(int8(c % 13) + 1) } func (r Rank) String() string { if r == 1 { return "A" } else if r < 11 { return fmt.Sprintf("%d", r) } else { return []string{"J", "Q", "K"}[r - 11] } } func (s Suit) String() string { return string(([]rune("♠♥♣♢"))[s]) } func (c Card) String() string { return fmt.Sprintf("%v%v", c.Rank(), c.Suit()) } type Hand []Card func (hand Hand) BlackjackValue() int { total := 0 aces := 0 for _, c := range hand { rank := c.Rank() if rank > 9 { total += 10 } else if rank > 1 { total += int(rank) } else { // ace aces++ total += 1 } } for total < 21 && aces > 0 { aces-- total += 10 } return total } func Shuffle() []Card { var cards [52]Card for j, c := range rand.Perm(len(cards)) { cards[j] = Card(c) } return cards[0:len(cards)] } func main() { rand.Seed(int64(os.Getpid())) deck := Shuffle() hand := Hand(deck[0:4]) for _, card := range hand { fmt.Printf("%v ", card) } fmt.Printf("→ %v\n", hand.BlackjackValue()) }