I am trying to write a Spider Solitaire player as an exercise in learning Clojure. I am trying to figure out how to deal the cards.
I have created (with the help of stackoverflow), a shuffled sequence of 104 cards from two standard decks. Each card is represented as a
(defstruct card :rank :suit :face-up)
The tableau for Spider will be represented as follows:
(defstruct tableau :stacks :complete)
where :stacks is a vector of card vectors, 4 of which contain 5 cards face down and 1 card face up, and 6 of which contain 4 cards face down and 1 card face up, for a total of 54 cards, and :complete is an (initially) empty vector of completed sets of ace-king (represented as, for example, king-hearts, for printing purposes). The remainder of the undealt deck should be saved in a ref
(def deck (ref seq))
During the game, a tableau may contain, for example:
(struct-map tableau
:stacks [[AH 2C KS ...]
[6D QH JS ...]
...
]
:complete [KC KS])
where “AH” is a card containing {:rank :ace :suit :hearts :face-up false}, etc.
How can I write a function to deal the stacks and then save the remainder in the ref?
You could write a function to take
chunksvectors ofsizeitems each from a given sequence and another one to drop those chunks from the front:Then maybe add a function to do both (modelled after
split-atandsplit-with):Assuming that each card is initially
{:face-up false}, you can use the following function to turn the last card on a stack:Then a function to deal out the initial stacks / chunks from the the given deck:
The return value is a doubleton vector whose first element is the remainder of the deck and whose second element is a vector of the initial stacks.
Then use this in a transaction to take the Ref into account:
Better yet, keep the whole state of the game in a single Ref or Atom and switch from
ref-settoalter/swap!(I’ll use a Ref for this example, omit thedosyncand switchaltertoswap!to use an atom instead):Disclaimer: None of this has received the slightest amount of testing attention (though I think it should work fine, modulo any silly typos I might have missed). It’s your exercise, though, so I think leaving the testing / polishing part to you is fine. 🙂