111 lines
2.6 KiB
D
111 lines
2.6 KiB
D
import std.stdio, std.random, std.algorithm, std.string, std.range;
|
|
|
|
struct Card {
|
|
static immutable suits = "Club Heart Diamond Spade".split;
|
|
static immutable pips = "Ace 2 3 4 5 6 7 8 9 10 J Q K".split;
|
|
enum nPack = suits.length * pips.length;
|
|
|
|
static bool rankAceTop = true;
|
|
int pip, suit;
|
|
|
|
string toString() pure const {
|
|
return format("%3s of %-7s", pips[pip], suits[suit])
|
|
.rightJustify(15);
|
|
}
|
|
|
|
@property int order() const nothrow {
|
|
immutable pipOrder = (!rankAceTop) ?
|
|
pip :
|
|
(pip ? pip - 1 : 12);
|
|
return pipOrder * suits.length + suit;
|
|
}
|
|
|
|
bool opEqual(in Card rhs) const pure nothrow {
|
|
return pip == rhs.pip && suit == rhs.suit;
|
|
}
|
|
|
|
int opCmp(in Card rhs) const nothrow {
|
|
return order - rhs.order;
|
|
}
|
|
}
|
|
|
|
final class Deck {
|
|
private Card[] cards;
|
|
|
|
this(in bool initShuffle = true, in int pack = 0) {
|
|
cards.length = 0;
|
|
foreach (immutable p; 0 .. pack)
|
|
foreach (immutable c; 0 .. Card.nPack)
|
|
cards ~= Card((c / Card.suits.length) %
|
|
Card.pips.length,
|
|
c % Card.suits.length);
|
|
|
|
if (initShuffle)
|
|
cards.randomShuffle;
|
|
}
|
|
|
|
@property size_t length() const pure nothrow {
|
|
return cards.length;
|
|
}
|
|
|
|
Deck add(in Card c) pure nothrow {
|
|
cards ~= c;
|
|
return this;
|
|
}
|
|
|
|
Deck deal(in int loc, Deck toDeck = null) pure nothrow {
|
|
if (toDeck !is null)
|
|
toDeck.add(cards[loc]);
|
|
cards = cards[0 .. loc] ~ cards[loc + 1 .. $];
|
|
return this;
|
|
}
|
|
|
|
Deck dealTop(Deck toDeck = null) pure nothrow {
|
|
return deal(length - 1, toDeck);
|
|
}
|
|
|
|
Card opIndex(in int loc) const pure nothrow {
|
|
return cards[loc];
|
|
}
|
|
|
|
alias opIndex peek;
|
|
|
|
Deck showDeck() {
|
|
this.writeln;
|
|
return this;
|
|
}
|
|
|
|
Deck shuffle() {
|
|
cards.randomShuffle;
|
|
return this;
|
|
}
|
|
|
|
Deck sortDeck() {
|
|
cards.sort!q{a > b};
|
|
return this;
|
|
}
|
|
|
|
override string toString() pure const {
|
|
return format("%(%(%s%)\n%)", cards.chunks(4));
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
Deck[4] guests;
|
|
foreach (ref g; guests)
|
|
g = new Deck; // Empty deck.
|
|
|
|
auto host = new Deck(false, 1);
|
|
writeln("Host");
|
|
host.shuffle.showDeck;
|
|
|
|
while (host.length > 0)
|
|
foreach (ref g; guests)
|
|
if (host.length > 0)
|
|
host.dealTop(g);
|
|
|
|
foreach (immutable i, g; guests) {
|
|
writefln("Player #%d", i + 1);
|
|
g.sortDeck.showDeck;
|
|
}
|
|
}
|