Playing cards: Difference between revisions

Content added Content deleted
m (added related tasks)
(Replaced by a more complete version usable for other tasks ans compatible with Nim 1.4.)
Line 3,937: Line 3,937:


=={{header|Nim}}==
=={{header|Nim}}==
<lang nim>import math
<lang nim>import random, strutils
randomize()

proc shuffle[T](x: var seq[T]) =
for i in countdown(x.high, 0):
let j = random(i + 1)
swap(x[i], x[j])


type
type
Suit = enum ♥, ♦, ♣, ♠
Suit* = enum ♥, ♦, ♣, ♠


Rank* {.pure.} = enum
Pip = enum c02, c03, c04, c05, c06, c07, c08, c09, c10, cQu, cKi, cAs
Ace = (1, "A")
Two = (2, "2")
Three = (3, "3")
Four = (4, "4")
Five = (5, "5")
Six = (6, "6")
Seven = (7, "7")
Eight = (8, "8")
Nine = (9, "9")
Ten = (10, "10")
Jack = (11, "J")
Queen = (12, "Q")
King = (13, "K")


Card = object
Card* = tuple[rank: Rank; suit: Suit]
pip: Pip
suit: Suit


# Sequences of cards: synonyms for seq[Card].
Deck = object
cards: seq[Card]
Deck* = seq[Card]
Hand* = seq[Card]


var initRandom = false # True if "randomize" has been called.
proc `$`(c: Card): string = $c.pip & $c.suit



proc initDeck(): Deck =
proc `$`*(c: Card): string =
result = Deck(cards: @[])
## Return the representation of a card.
$c.rank & $c.suit


proc initDeck*(): Deck =
## Initialize a deck.
for suit in Suit:
for suit in Suit:
for pip in Pip:
for rank in Rank:
result.cards.add Card(pip: pip, suit: suit)
result.add (rank, suit)


proc shuffle*(cards: var seq[Card]) =
## Shuffle a list of cards (deck or hand).
if not initRandom:
randomize()
initRandom = true
random.shuffle(cards)


func `$`*(cards: seq[Card]): string =
## Return the representation of a list o cards.
cards.join(" ")


func dealOne*(cards: var seq[Card]): Card =
## Deal one card from a list of cards.
assert cards.len > 0
cards.pop()


## Draw one card from a list of cards.
let draw* = dealOne


func deal*(deck: var Deck; nPlayers: Positive; nCards: Positive): seq[Hand] =
## Deal "nCards" cards to "nPlayers" players.
assert deck.len >= nCards * nPlayers
result.setLen(nPlayers)
for n in 1..nCards:
for p in 0..<nPlayers:
result[p].add deck.pop()


when isMainModule:
import strformat

var deck = initDeck()
deck.shuffle()
echo "Initial deck after shuffling: "
for i in 0..2: echo deck[(i * 13)..(i * 13 + 12)], " ..."
echo deck[^13..^1]

echo "\nDeal eight cards for five players from the deck:"
var hands = deck.deal(5, 8)
for i, hand in hands: echo &"Player {i + 1} hand: ", hand
echo "Remaining cards: ", deck


echo "\nAfter player 1 drawn a card from the deck: "
proc `$`(d: Deck): string = $d.cards
hands[0].add deck.draw()
echo "Player 1 hand: ", hands[0]
echo "Remaining cards: ", deck</lang>


{{out}}
proc shuffle(d: var Deck) = shuffle(d.cards)
<pre>Initial deck after shuffling:
A♦ Q♣ 2♣ A♥ 10♣ 3♠ Q♦ 7♦ A♣ 4♠ 9♥ 4♦ 7♠ ...
6♣ J♦ 7♥ 6♦ 9♠ 2♥ 8♥ 8♣ 8♦ 8♠ 4♣ 5♠ 2♦ ...
3♣ 9♦ 6♠ K♦ K♣ 5♦ 3♦ 10♠ J♠ 9♣ Q♥ 10♦ Q♠ ...
6♥ 5♣ 2♠ J♣ 3♥ K♠ A♠ 4♥ J♥ K♥ 10♥ 7♣ 5♥


Deal eight cards for five players from the deck:
proc deal(d: var Deck): Card =
Player 1 hand: 5♥ 4♥ 2♠ Q♥ 5♦ 3♣ 8♦ 6♦
d.shuffle()
Player 2 hand: 7♣ A♠ 5♣ 9♣ K♣ 2♦ 8♣ 7♥
d.cards.pop()
Player 3 hand: 10♥ K♠ 6♥ J♠ K♦ 5♠ 8♥ J♦
Player 4 hand: K♥ 3♥ Q♠ 10♠ 6♠ 4♣ 2♥ 6♣
Player 5 hand: J♥ J♣ 10♦ 3♦ 9♦ 8♠ 9♠ 7♠
Remaining cards: A♦ Q♣ 2♣ A♥ 10♣ 3♠ Q♦ 7♦ A♣ 4♠ 9♥ 4♦


After player 1 drawn a card from the deck:
var d = initDeck()
Player 1 hand: 5♥ 4♥ 2♠ Q♥ 5♦ 3♣ 8♦ 6♦ 4♦
echo "40 cards from a deck:"
Remaining cards: A♦ Q♣ 2♣ A♥ 10♣ 3♠ Q♦ 7♦ A♣ 4♠ 9♥</pre>
for i in 0..4:
for j in 0..7:
stdout.write($d.deal(), " ")
echo ""
echo "The remaining cards are: ", $d</lang>
Output:
<pre>40 cards from a deck:
c10♦ c06♥ cKi♠ c09♥ c06♣ c02♦ c10♣ c08♣
c03♥ cQu♠ c07♠ c02♣ c04♦ c09♠ c07♦ c09♦
c02♠ c06♠ cKi♥ cAs♦ cAs♥ c04♥ c05♣ c02♥
cQu♥ c03♠ cQu♣ c05♦ c08♥ c04♠ c10♥ cQu♦
c04♣ c03♣ c03♦ cAs♠ c10♠ cKi♣ cKi♦ c05♠
The remaining cards are: @[c07♣, cAs♣, c05♥, c06♦, c08♦, c08♠, c09♣, c07♥]</pre>


=={{header|OCaml}}==
=={{header|OCaml}}==