|
- (in-package #:subdecadence.core)
-
- (defclass aeon ()
- ((deck :accessor deck
- :initform (subd::shuffle
- (copy-list subd::+base-deck+))
- :type list
- :documentation
- "The deck of cards.")
-
- (cross-set :accessor cross-set
- :initform nil
- :type list
- :documentation
- "The Set-1 cards. They go on the cross.")
-
- (match-set :accessor match-set
- :initform nil
- :type list
- :documentation
- "The Set-2 cards. They are dealt face-down.")
-
- (score :accessor score
- :initform 0
- :type integer
- :documentation
- "The score for the current draw.")
-
- (total-score :accessor total-score
- :initform 0
- :type integer
- :documentation
- "The total score for this Aeon."))
-
- (:documentation "A game of Subdecadence."))
-
- (defmethod reset-deck ((self aeon))
- "Create a new deck to continue an Aeon."
- (setf (deck self) (subd::shuffle
- (copy-list subd::+base-deck+))))
-
- (defmethod draw-sets ((self aeon))
- "Draw 5 cards for cross-set, 5 for match-set, and update deck."
- (with-slots (deck cross-set match-set) self
- (setf cross-set (subseq deck 0 5))
- (setf match-set (subseq deck 5 10))
- (setf deck (nthcdr 10 deck))))
-
- (defmethod get-match ((self aeon) &key card)
- "Find pairs for a card and calculate score."
- (unless (typep card 'fixnum) (error "Card must be a fixnum."))
- (with-slots (score match-set) self
- (loop :for match :in match-set
- :for index :from 0
- :do (setq match (subd::strip-suit match))
- ;; if there's a pair, remove matched card from set to avoid
- :when (= (+ card match) 9) ; interfering with later matches
- :do (setf match-set (subd::remove-nth match-set index))
- :and :return (setf score ; and add the diff. of pair to score
- (+ score (subd::diff card match)))
- ;; otherwise, subtract card # from score
- :finally (setf score (- score card)))))
-
- (defmethod make-matches ((self aeon))
- "Call get-match for every card on the cross."
- (with-slots (cross-set match-set) self
- (loop :for card :in cross-set
- :do (get-match self :card (subd::strip-suit card)))))
-
- (defmethod play-draw ((self aeon))
- "Play a single draw of an Aeon."
- (with-slots (cross-set match-set score) self
- (draw-sets self)
- (subd::display-cross cross-set)
- (format t "~A~%~%" match-set)
- (make-matches self)
- (format t "Score: ~A~%" score)))
-
- (defmethod play-aeon ((self aeon))
- "Play a single Aeon."
- (play-draw self)
- (with-slots (total-score score deck) self
- (unless deck
- (reset-deck self))
-
- (setf total-score (+ total-score score))
- (format t "Total Score: ~A~%" total-score)
-
- (when (> score 0)
- (progn
- (setf score 0)
- (play-aeon self)))))
|