Kartenstapel

Die Klasse deck repräsentiert einen Kartenstapel beim Poker. Die Klasse ist nicht von anderen Klassen abgeleitet.

  (defclass deck ())

Der Konstruktor der Klasse füllt ein Array mit einer Karte für jede Kombination aus Wert und Farbe (für *ranks* und *suits* siehe Karte).

  (defmethod initialize ((this deck)) t
    (let
      ((suit-count (length *suits*))
       (rank-count (length *ranks*)))
      (progn
        (assignq this lock (make-lock))
        (assignq this cards (make-array (list (* suit-count rank-count))))
        (assignq this position 0)
        (dotimes (i suit-count)
          (dotimes (j rank-count)
            (set-array-element
              (slot-value this (quote cards))
              (list (+ (* i rank-count) j))
              (new card (nth *suits* i) (nth *ranks* j)))))
        this)))

Die Methode shuffle bringt die Karten im Stapel in eine zufällige Reihenfolge. Die Position für die nächste zu gebende Karte wird auf den Anfang gestellt.

  (defmethod shuffle ((this deck)) t
    (with-slots-read-only (cards) this
      (with-slots (position) this
        (progn
          (setq position 0)
          (let
            ((count (first (array-dimensions cards))))
            (dotimes (k (- count 2))
              (let
                ((i (- count k 1))
                 (j (random (- count k 1))))
                (let
                  ((ci (get-array-element cards (list i)))
                   (cj (get-array-element cards (list j))))
                  (progn
                    (set-array-element cards (list i) cj)
                    (set-array-element cards (list j) ci))))))))))

Die Methode get-card nimmt die Karte vom Stapel, die an der Reihe ist und erhöht dann die Position.

  (defmethod get-card ((this deck)) t
    (synchronized lock this
      (with-slots-read-only (cards) this
        (with-slots (position) this
          (prog1
            (get-array-element cards (list position))
            (setq position (+ 1 position)))))))

Die Methode get-hands mischt den Kartenstapel und erzeugt dann die angegebene Anzahl von Händen (siehe Hand) mit jeweils sieben Karten.

  (defmethod get-hands ((this deck) count)
    (integer? count)
    (progn
      (shuffle this)
      (let
        ((hands nil))
        (dotimes (i count hands)
          (push
            (new hand
              (list
                (get-card this)
                (get-card this)
                (get-card this)
                (get-card this)
                (get-card this)
                (get-card this)
                (get-card this)))
            hands)))))