Vous pouvez écrire une fonction pour prendre chunks
vecteurs de size
éléments chacun d'une séquence donnée et l'autre pour laisser tomber ces morceaux de l'avant:
;; note the built-in assumption that s contains enough items;
;; if it doesn't, one chunk less then requested will be produced
(defn take-chunks [chunks size s]
(map vec (partition size (take (* chunks size) s))))
;; as above, no effort is made to handle short sequences in some special way;
;; for a short input sequence, an empty output sequence will be returned
(defn drop-chunks [chunks size s]
(drop (* chunks size) s))
ajouter ensuite peut-être une fonction de faire les deux (sur le modèle split-at
et split-with
):
(defn split-chunks [chunks size s]
[(take-chunks chunks size s)
(drop-chunks chunks size s)])
en supposant que chaque carte est d'abord {:face-up false}
, vous pouvez utiliser la fonction suivante pour activer la dernière carte sur une pile:
(defn turn-last-card [stack]
(update-in stack [(dec (count stack)) :face-up] not))
Ensuite, une fonction pour traiter les piles initiales/morceaux du pont suivant:
(defn deal-initial-stacks [deck]
(dosync
(let [[short-stacks remaining] (split-chunks 6 5 deck)
[long-stacks remaining] (split-chunks 4 6 remaining)]
[remaining
(vec (map turn-last-card
(concat short-stacks long-stacks)))])))
La valeur de retour est un vecteur doubleton dont le premier élément est le reste de la plate-forme et dont la seconde element est un vecteur des piles initiales.
Ensuite, utilisez ceci dans une transaction pour prendre les Ref compte:
(dosync (let [[new-deck stacks] (deal-initial-stacks @deck-ref)]
(ref-set deck-ref new-deck)
stacks))
Mieux encore, garder tout l'état du jeu dans un seul Ref ou Atom et commutateur ref-set
-alter
/swap!
(I « ll utiliser Aref pour cet exemple, omettre le dosync
et passer alter
-swap!
d'utiliser un atome à la place):
;; the empty vector is for the stacks
(def game-state-ref (ref [(get-initial-deck) []]))
;; deal-initial-stacks only takes a deck as an argument,
;; but the fn passed to alter will receive a vector of [deck stacks];
;; the (% 0) bit extracts the first item of the vector,
;; that is, the deck; you could instead change the arguments
;; vector of deal-initial-stacks to [[deck _]] and pass the
;; modified deal-initial-stacks to alter without wrapping in a #(...)
(dosync (alter game-state-ref #(deal-initial-stacks (% 0))))
Avertissement: Rien de tout cela a reçu la moindre quantité d'attention de test (bien que je pense que cela devrait fonctionner correctement, modulo toute fautes de frappe stupide que je pourrais avoir manqué).C'est votre exercice, cependant, donc je pense que laisser la partie test/polissage est bien. :-)