Task: Playing cards


C++: #include <deque>
#include <algorithm>
#include <ostream>
#include <iterator>

namespace cards
{
class card
{
public:
    enum pip_type { two, three, four, five, six, seven, eight, nine, ten,
                    jack, queen, king, ace, pip_count };
    enum suite_type { hearts, spades, diamonds, clubs, suite_count };
    enum { unique_count = pip_count * suite_count };

    card(suite_type s, pip_type p): value(s + suite_count * p) {}

    explicit card(unsigned char v = 0): value(v) {}

    pip_type pip() { return pip_type(value / suite_count); }

    suite_type suite() { return suite_type(value % suite_count); }

private:
    unsigned char value;
};

const char* const pip_names[] =
    { "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
      "jack", "queen", "king", "ace" };

std::ostream& operator<<(std::ostream& os, card::pip_type pip)
{
    return os << pip_names[pip];
}

const char* const suite_names[] =
    { "hearts", "spades", "diamonds", "clubs" };

std::ostream& operator<<(std::ostream& os, card::suite_type suite)
{
    return os << suite_names[suite];
}

std::ostream& operator<<(std::ostream& os, card c)
{
    return os << c.pip() << " of " << c.suite();
}

class deck
{
public:
    deck()
    {
        for (int i = 0; i < card::unique_count; ++i) {
            cards.push_back(card(i));
        }
    }

    void shuffle() { std::random_shuffle(cards.begin(), cards.end()); }

    card deal() { card c = cards.front(); cards.pop_front(); return c; }

    typedef std::deque<card>::const_iterator const_iterator;
    const_iterator begin() const { return cards.cbegin(); }
    const_iterator end() const { return cards.cend(); }
private:
    std::deque<card> cards;
};

inline std::ostream& operator<<(std::ostream& os, const deck& d)
{
    std::copy(d.begin(), d.end(), std::ostream_iterator<card>(os, "\n"));
    return os;
}
}



Go: package cards

import (
	"math/rand"
)


type Suit uint8


const (
	Spade   Suit = 3
	Heart   Suit = 2
	Diamond Suit = 1
	Club    Suit = 0
)

func (s Suit) String() string {
	const suites = "CDHS" 
	return suites[s : s+1]
}


type Rank uint8


const (
	Ace   Rank = 1
	Two   Rank = 2
	Three Rank = 3
	Four  Rank = 4
	Five  Rank = 5
	Six   Rank = 6
	Seven Rank = 7
	Eight Rank = 8
	Nine  Rank = 9
	Ten   Rank = 10
	Jack  Rank = 11
	Queen Rank = 12
	King  Rank = 13
)

func (r Rank) String() string {
	const ranks = "A23456789TJQK"
	return ranks[r-1 : r]
}




type Card uint8


func NewCard(r Rank, s Suit) Card {
	return Card(13*uint8(s) + uint8(r-1))
}


func (c Card) RankSuit() (Rank, Suit) {
	return Rank(c%13 + 1), Suit(c / 13)
}


func (c Card) Rank() Rank {
	return Rank(c%13 + 1)
}


func (c Card) Suit() Suit {
	return Suit(c / 13)
}

func (c Card) String() string {
	return c.Rank().String() + c.Suit().String()
}


type Deck []Card


func NewDeck() Deck {
	d := make(Deck, 52)
	for i := range d {
		d[i] = Card(i)
	}
	return d
}



func (d Deck) String() string {
	s := ""
	for i, c := range d {
		switch {
		case i == 0: 
		case i%13 == 0:
			s += "\n"
		default:
			s += " "
		}
		s += c.String()
	}
	return s
}


func (d Deck) Shuffle() {
	for i := range d {
		j := rand.Intn(i + 1)
		d[i], d[j] = d[j], d[i]
	}
}


func (d Deck) Contains(tc Card) bool {
	for _, c := range d {
		if c == tc {
			return true
		}
	}
	return false
}


func (d *Deck) AddDeck(decks ...Deck) {
	for _, o := range decks {
		*d = append(*d, o...)
	}
}


func (d *Deck) AddCard(c Card) {
	*d = append(*d, c)
}



func (d *Deck) Draw(n int) Deck {
	old := *d
	*d = old[n:]
	return old[:n:n]
}




func (d *Deck) DrawCard() (Card, bool) {
	if len(*d) == 0 {
		return 0, false
	}
	old := *d
	*d = old[1:]
	return old[0], true
}








func (d *Deck) Deal(cards int, hands ...Deck) ([]Deck, bool) {
	for i := 0; i < cards; i++ {
		for j := range hands {
			if len(*d) == 0 {
				return hands, false
			}
			hands[j] = append(hands[j], (*d)[0])
			*d = (*d)[1:]
		}
	}
	return hands, true
}