placate checkdoc
This commit is contained in:
parent
209ebdc02a
commit
99cf31930b
21 changed files with 506 additions and 416 deletions
|
|
@ -58,12 +58,14 @@
|
|||
(if (= rank 0) 13 rank))
|
||||
|
||||
(defun card-games-pres-card-string (card)
|
||||
"Return the display string for CARD (a middot for nil)."
|
||||
(if (null card) "·"
|
||||
(concat (aref card-games-pres-ranks (cdr card)) (card-games-suit-glyph (car card)))))
|
||||
|
||||
(defsubst card-games-pres-red-p (card) (and card (card-games-red-suit-p (car card))))
|
||||
(defsubst card-games-pres-red-p (card) "Return non-nil when CARD is red." (and card (card-games-red-suit-p (car card))))
|
||||
|
||||
(defun card-games-pres--deck ()
|
||||
"Return a fresh shuffled 52-card deck."
|
||||
(card-games-shuffle (cl-loop for s below 4 append
|
||||
(cl-loop for r below 13 collect (cons s r)))))
|
||||
|
||||
|
|
@ -78,14 +80,16 @@
|
|||
((vname :initform "President"))
|
||||
"A game of President (Scum).")
|
||||
|
||||
(defsubst card-games-pres--hand (game s) (aref (card-games-get game :hands) s))
|
||||
(defsubst card-games-pres--set-hand (game s v) (aset (card-games-get game :hands) s v))
|
||||
(defsubst card-games-pres--hand (game s) "Return seat S's hand in GAME." (aref (card-games-get game :hands) s))
|
||||
(defsubst card-games-pres--set-hand (game s v) "Set seat S's hand in GAME to V." (aset (card-games-get game :hands) s v))
|
||||
(defsubst card-games-pres--name (_game s)
|
||||
"Return the display name of seat S."
|
||||
(if (= s 0) "You" (format "Player %d" s)))
|
||||
|
||||
;;;; Dealing and the inter-game exchange
|
||||
|
||||
(cl-defmethod card-games-pres--deal ((game card-games-president-game))
|
||||
"Deal a new round into GAME (3-6 players)."
|
||||
(let* ((n (max 3 (min 6 card-games-president-players)))
|
||||
(deck (card-games-pres--deck))
|
||||
(hands (make-vector n nil))
|
||||
|
|
@ -114,7 +118,7 @@
|
|||
(defun card-games-pres--worst (hand k) "The K lowest-power cards of HAND." (cl-subseq (card-games-pres--sort hand) 0 k))
|
||||
|
||||
(cl-defmethod card-games-pres--exchange ((game card-games-president-game))
|
||||
"Trade cards by rank from the previous deal's finishing order, if any."
|
||||
"Trade GAME cards by rank from the previous deal's finishing order, if any."
|
||||
(let ((order (card-games-get game :order)) (n (card-games-get game :nplayers)))
|
||||
(when (and order (= (length order) n) (>= n 4))
|
||||
(let* ((prez (nth 0 order)) (scum (nth (1- n) order))
|
||||
|
|
@ -125,7 +129,7 @@
|
|||
(card-games-pres--give game vp vice 1 t)))))
|
||||
|
||||
(defun card-games-pres--give (game from to k &optional worst)
|
||||
"Move K cards (best, or WORST) from seat FROM to seat TO."
|
||||
"Move K cards (best, or WORST) from GAME seat FROM to seat TO."
|
||||
(let* ((cards (if worst (card-games-pres--worst (card-games-pres--hand game from) k)
|
||||
(card-games-pres--best (card-games-pres--hand game from) k))))
|
||||
(card-games-pres--set-hand game from
|
||||
|
|
@ -136,14 +140,14 @@
|
|||
;;;; Move logic
|
||||
|
||||
(defun card-games-pres--rank-counts (game s)
|
||||
"Return an alist (RANK . COUNT) for seat S's hand."
|
||||
"Return an alist (RANK . COUNT) for GAME seat S's hand."
|
||||
(let ((tbl nil))
|
||||
(dolist (c (card-games-pres--hand game s))
|
||||
(setf (alist-get (cdr c) tbl 0) (1+ (alist-get (cdr c) tbl 0))))
|
||||
tbl))
|
||||
|
||||
(defun card-games-pres--legal-ranks (game s)
|
||||
"Return the ranks seat S may legally play now."
|
||||
"Return the ranks GAME seat S may legally play now."
|
||||
(let ((cnt (card-games-get game :count)) (top (card-games-get game :top)))
|
||||
(cl-loop for (r . c) in (card-games-pres--rank-counts game s)
|
||||
when (if (= cnt 0) t (and (>= c cnt) (> (card-games-pres--power r) top)))
|
||||
|
|
@ -157,18 +161,18 @@
|
|||
(nreverse out)))
|
||||
|
||||
(defun card-games-pres--in-game (game)
|
||||
"Seats that still hold cards."
|
||||
"Return GAME seats that still hold cards."
|
||||
(cl-loop for s below (card-games-get game :nplayers)
|
||||
unless (memq s (card-games-get game :out)) collect s))
|
||||
|
||||
(defun card-games-pres--round-active (game)
|
||||
"Seats that can still act on the current pile."
|
||||
"Return GAME seats that can still act on the current pile."
|
||||
(cl-loop for s below (card-games-get game :nplayers)
|
||||
unless (or (memq s (card-games-get game :out)) (aref (card-games-get game :passed) s))
|
||||
collect s))
|
||||
|
||||
(defun card-games-pres--next (game from)
|
||||
"Next seat after FROM that is still in the round."
|
||||
"Return the next GAME seat after FROM still in the round."
|
||||
(let ((n (card-games-get game :nplayers)) (s from) (res nil))
|
||||
(dotimes (_ n)
|
||||
(setq s (mod (1+ s) n))
|
||||
|
|
@ -179,7 +183,7 @@
|
|||
(or res from)))
|
||||
|
||||
(defun card-games-pres--clear (game)
|
||||
"Clear the pile; the last player to play leads (or the next active seat)."
|
||||
"Clear GAME's pile; the last player to play leads, else the next active seat."
|
||||
(card-games-put game :count 0) (card-games-put game :top -1)
|
||||
(card-games-put game :passed (make-vector (card-games-get game :nplayers) nil))
|
||||
(let ((last (card-games-get game :last-player)))
|
||||
|
|
@ -188,7 +192,7 @@
|
|||
(card-games-put game :message "Pile cleared."))
|
||||
|
||||
(defun card-games-pres--check-finish (game)
|
||||
"End the game when only one player still holds cards (the Scum)."
|
||||
"End GAME when only one player still has cards (the Scum)."
|
||||
(let ((in (card-games-pres--in-game game)))
|
||||
(when (<= (length in) 1)
|
||||
(when in (card-games-put game :out (append (card-games-get game :out) in)))
|
||||
|
|
@ -199,7 +203,7 @@
|
|||
t)))
|
||||
|
||||
(defun card-games-pres--advance (game)
|
||||
"Decide the next turn or clear the pile after a move."
|
||||
"Decide GAME's next turn or clear the pile after a move."
|
||||
(unless (card-games-pres--check-finish game)
|
||||
(let* ((active (card-games-pres--round-active game))
|
||||
(last (card-games-get game :last-player))
|
||||
|
|
@ -209,7 +213,7 @@
|
|||
(card-games-put game :turn (card-games-pres--next game (card-games-get game :turn)))))))
|
||||
|
||||
(defun card-games-pres--play (game seat rank n)
|
||||
"Seat SEAT plays N cards of RANK."
|
||||
"Have GAME seat SEAT play N cards of RANK."
|
||||
(card-games-pres--set-hand game seat (card-games-pres--remove-n (card-games-pres--hand game seat) rank n))
|
||||
(card-games-put game :count n) (card-games-put game :top (card-games-pres--power rank))
|
||||
(card-games-put game :last-player seat)
|
||||
|
|
@ -220,13 +224,13 @@
|
|||
(card-games-pres--advance game))
|
||||
|
||||
(defun card-games-pres--pass (game seat)
|
||||
"Seat SEAT passes for the current pile."
|
||||
"Have GAME seat SEAT pass on the current pile."
|
||||
(aset (card-games-get game :passed) seat t)
|
||||
(card-games-put game :message (format "%s passes." (card-games-pres--name game seat)))
|
||||
(card-games-pres--advance game))
|
||||
|
||||
(defun card-games-pres--ai-move (game seat)
|
||||
"Make seat SEAT's move: lead low, beat low, or pass."
|
||||
"Make GAME seat SEAT's move: lead low, beat low, or pass."
|
||||
(let* ((cnt (card-games-get game :count)) (top (card-games-get game :top))
|
||||
(counts (card-games-pres--rank-counts game seat)))
|
||||
(if (= cnt 0)
|
||||
|
|
@ -240,7 +244,7 @@
|
|||
(card-games-pres--pass game seat))))))
|
||||
|
||||
(defun card-games-pres--result (game)
|
||||
"Return a finishing summary string."
|
||||
"Return a finishing summary string for GAME."
|
||||
(let* ((order (card-games-get game :order)) (n (length order)) (parts nil))
|
||||
(dotimes (i n)
|
||||
(let ((title (cond ((= i 0) "President") ((= i (1- n)) "Scum")
|
||||
|
|
@ -255,12 +259,12 @@
|
|||
(defvar-local card-games-pres--game nil "The President game in the current buffer.")
|
||||
|
||||
(defun card-games-pres--run (game)
|
||||
"Advance AI seats until it is the human's turn or the game ends."
|
||||
"Advance GAME's AI seats until the human's turn or the game ends."
|
||||
(while (and (eq (card-games-get game :phase) 'play) (/= (card-games-get game :turn) 0))
|
||||
(card-games-pres--ai-move game (card-games-get game :turn))))
|
||||
|
||||
(defun card-games-pres--hand-ranks (game)
|
||||
"Distinct ranks in seat 0's hand, ordered by power."
|
||||
"Return the distinct ranks in GAME seat 0's hand, ordered by power."
|
||||
(let ((rs (delete-dups (mapcar #'cdr (card-games-pres--hand game 0)))))
|
||||
(cl-sort rs #'< :key #'card-games-pres--power)))
|
||||
|
||||
|
|
@ -316,7 +320,7 @@
|
|||
:type 'boolean :group 'card-games)
|
||||
|
||||
(defun card-games-pres--svg (game)
|
||||
"Return a propertized, clickable SVG row of the hand: one card per rank.
|
||||
"Return a propertized, clickable SVG row of GAME's hand: one card per rank.
|
||||
Each rank maps to a (hand . INDEX) region and a card-size slider sits below."
|
||||
(let* ((w card-games-svg-card-width) (h card-games-svg-card-height) (pad 10)
|
||||
(gap (+ card-games-svg-card-gap 8)) (ranks (card-games-pres--hand-ranks game))
|
||||
|
|
@ -379,6 +383,7 @@ Each rank maps to a (hand . INDEX) region and a card-size slider sits below."
|
|||
(_ (cl-call-next-method))))
|
||||
|
||||
(defun card-games-pres--redisplay ()
|
||||
"Redraw the current President buffer."
|
||||
(let ((game card-games-pres--game) (inhibit-read-only t))
|
||||
(setq card-games-current-game game card-games-redisplay-function #'card-games-pres--redisplay)
|
||||
(setq-local mode-line-process (format " [%s]" (card-games-get game :phase)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue