I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Playing cards/E

Playing cards/E is part of Playing Cards. You may find other members of Playing Cards at Category:Playing Cards.

The E language is designed to permit cooperation among multiple mutually suspicious ("untrusted" if you like) programs. Therefore, it is appropriate to design a deck which can be shared without allowing card holders to cheat. In particular, even though the cards are ordinary objects, which can have multiple references to them, nobody should be able to both give away a card and keep it.

Therefore, this implementation adds an extra feature: the `take` operation on cards, which returns a new reference to a card and invalidates the old one. Therefore, any player or game rule can, when given a card, take sole possession of it.

A "stack" is just a collection of cards, whether a hand or a deck. This implementation does not attempt to simulate the hidden information of a face-down deck, though this would be possible.

`def makeStack(cardsIn) {    def cards := cardsIn.diverge()    def stack {        to __printOn(out) {            out.print("<cards: ", cards, ">")        }        to shuffle() {            # Per http://rosettacode.org/wiki/Knuth_shuffle            for bound in (2..(cards.size())).descending() {                def i := entropy.nextInt(bound)                def swapTo := bound - 1                def t := cards[swapTo]                cards[swapTo] := cards[i]                cards[i] := t            }        }        to deal(count :int) {            def hand := cards.removeRun(0, count)            return makeStack(hand)        }        to size() { return cards.size() }        to get(index) { return cards.get(index) }        to take(index :int) {            def [card] := cards.removeRun(index, index + 1)            return card        }    }    return stack} def makeDeck() {    interface CardG guards CardS {}    def Card {        to coerce(specimen, ejector) {            def card := CardG.coerce(specimen, ejector)            if (card.taken()) {                throw.eject(ejector, `This card has been taken`)            }            return card        }    }     def makeCard(rank, suit) {        var taken := false        def card implements CardS {            to __printOn(out) {                out.print(`the \$rank of \$suit`)                if (taken) {                   out.print(" (taken)")                }            }            to take() {                taken := true                return makeCard(rank, suit)            }            to taken() { return taken }        }        return card    }     var cards := []    for suit in ["spades", "hearts", "diamonds", "clubs"] {        for rank in 1..13 {            cards with= makeCard(rank, suit)        }    }     return [makeStack(cards), Card]}`

A sample session with a deck, showing dealing and taking:

```? def [deck, Card] := makeDeck()

? def hand := deck.deal(5)

? def card := hand.take(0)
# value: the 1 of spades

? hand