crowns/card.go

114 lines
1.7 KiB
Go

package main
import (
"fmt"
"math/rand"
)
type Suit int
func (s Suit) String() string {
switch s {
case 0:
return "♠"
case 1:
return "♥"
case 2:
return "♦"
case 3:
return "♣"
case 4:
return "★"
default:
panic("bad suit")
}
}
type Card int
func (c Card) Joker() bool {
return (c == 0)
}
func (c Card) Masked() bool {
return (c == -1)
}
func (c Card) Suit() Suit {
if c.Joker() || c.Masked() {
panic("Suit on invalid")
}
return Suit(int(c) % 5)
}
func (c Card) Face() int {
if c.Joker() || c.Masked() {
panic("Face on invalid")
}
return int(c) / 5
}
func (c Card) String() string {
if c.Joker() {
return "Jok" // 🂿 U+1F0BF
}
if c.Masked() {
return "INV" // Invalid
}
switch c.Face() {
case 11:
return fmt.Sprintf(" J%s", c.Suit().String())
case 12:
return fmt.Sprintf(" Q%s", c.Suit().String())
case 13:
return fmt.Sprintf(" K%s", c.Suit().String())
default:
return fmt.Sprintf("%2d%s", c.Face(), c.Suit().String())
}
}
func NewMasked() Card {
return Card(-1)
}
func NewJoker() Card {
return Card(0)
}
func NewCardFrom(face int, suit Suit) Card {
return Card(face*5 + int(suit))
}
func Shuffle(c []Card, entropy *rand.Rand) {
entropy.Shuffle(len(c), func(i, j int) {
c[i], c[j] = c[j], c[i]
})
}
const DeckSize = 58 * 2
func Deck() []Card {
// The full game deck is two 58-card decks
// Each 58-card deck has 3 jokers plus {3..10 J Q K} in 5 suits.
ret := make([]Card, 0, DeckSize)
for i := 0; i < 6; i++ {
ret = append(ret, NewJoker()) // Joker
}
for s := 0; s < 5; s++ {
for f := 3; f < 14; f++ {
ret = append(ret, NewCardFrom(f, Suit(s)), NewCardFrom(f, Suit(s)))
}
}
return ret
}