| 1 | ;; controller-test3.lisp
|
|---|
| 2 |
|
|---|
| 3 | ;; Test window that shows an assoc-array using an NSOutlineView to show
|
|---|
| 4 | ;; each level of the array (which are nested hash-tables).
|
|---|
| 5 |
|
|---|
| 6 | (eval-when (:compile-toplevel :load-toplevel :execute)
|
|---|
| 7 | (require :lisp-controller)
|
|---|
| 8 | (require :ns-string-utils)
|
|---|
| 9 | (require :list-utils)
|
|---|
| 10 | (require :assoc-array))
|
|---|
| 11 |
|
|---|
| 12 | (defpackage :controller-test3
|
|---|
| 13 | (:nicknames :ct3)
|
|---|
| 14 | (:use :ccl :common-lisp :iu :lc)
|
|---|
| 15 | (:export test-deal))
|
|---|
| 16 |
|
|---|
| 17 | (in-package :ct3)
|
|---|
| 18 |
|
|---|
| 19 | (defclass hand-of-cards (ns:ns-window-controller)
|
|---|
| 20 | ((lisp-ctrl :foreign-type :id :accessor lisp-ctrl))
|
|---|
| 21 | (:metaclass ns:+ns-object))
|
|---|
| 22 |
|
|---|
| 23 | (objc:defmethod (#/initWithNibPath: :id)
|
|---|
| 24 | ((self hand-of-cards) (nib-path :id))
|
|---|
| 25 | (let* ((init-self (#/initWithWindowNibPath:owner: self nib-path self)))
|
|---|
| 26 | init-self))
|
|---|
| 27 |
|
|---|
| 28 | (objc:defmethod (#/deal: :void)
|
|---|
| 29 | ((self hand-of-cards) (sender :id))
|
|---|
| 30 | (declare (ignore sender))
|
|---|
| 31 | (unless (eql (lisp-ctrl self) (%null-ptr))
|
|---|
| 32 | (setf (root (lisp-ctrl self)) (deal-cards))))
|
|---|
| 33 |
|
|---|
| 34 | (defun hand-children (hand)
|
|---|
| 35 | ;; hand will be an assoc-array
|
|---|
| 36 | (iu::index1-ht hand))
|
|---|
| 37 |
|
|---|
| 38 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|---|
| 39 | ;;
|
|---|
| 40 | ;; Utility Functions for hands
|
|---|
| 41 | ;;
|
|---|
| 42 | ;; A hand is represented as a bit vector that is 52 bits long. Cards in the hand
|
|---|
| 43 | ;; have a corresponding bit value of 1. Cards not in the hand have a corresponding
|
|---|
| 44 | ;; bit of 0.
|
|---|
| 45 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|---|
| 46 |
|
|---|
| 47 | (deftype rank-list ()
|
|---|
| 48 | '(satisfies all-ranks))
|
|---|
| 49 |
|
|---|
| 50 | (defconstant *aces* #*1000000000000100000000000010000000000001000000000000)
|
|---|
| 51 | (defconstant *kings* #*0100000000000010000000000001000000000000100000000000)
|
|---|
| 52 | (defconstant *queens* #*0010000000000001000000000000100000000000010000000000)
|
|---|
| 53 | (defconstant *jacks* #*0001000000000000100000000000010000000000001000000000)
|
|---|
| 54 | (defconstant *spades* #*1111111111111000000000000000000000000000000000000000)
|
|---|
| 55 | (defconstant *hearts* #*0000000000000111111111111100000000000000000000000000)
|
|---|
| 56 | (defconstant *diamonds* #*0000000000000000000000000011111111111110000000000000)
|
|---|
| 57 | (defconstant *clubs* #*0000000000000000000000000000000000000001111111111111)
|
|---|
| 58 | (defconstant *card-ranks* '("A" "K" "Q" "J" "10" "9" "8" "7" "6" "5" "4" "3" "2"))
|
|---|
| 59 | (defconstant *card-suits* '("Spades" "Hearts" "Diamonds" "Clubs"))
|
|---|
| 60 | (defconstant *hand-suits* '("Spades" "Hearts" "Diamonds" "Clubs" "North" "East" "South" "West"))
|
|---|
| 61 |
|
|---|
| 62 | (defun full-deck ()
|
|---|
| 63 | (make-array '(52) :element-type 'bit :initial-element 1))
|
|---|
| 64 |
|
|---|
| 65 | (defun card-rank (card)
|
|---|
| 66 | ;; card is a bit index
|
|---|
| 67 | (nth (mod card 13) *card-ranks*))
|
|---|
| 68 |
|
|---|
| 69 | (defun all-ranks (rank-list)
|
|---|
| 70 | (and (listp rank-list)
|
|---|
| 71 | (null (set-difference rank-list *card-ranks* :test #'string=))))
|
|---|
| 72 |
|
|---|
| 73 | (defun hand-suit-order (a b)
|
|---|
| 74 | (< (position a *hand-suits* :test #'string=) (position b *hand-suits* :test #'string=)))
|
|---|
| 75 |
|
|---|
| 76 | (defun higher-rank (r1 r2)
|
|---|
| 77 | (< (position r1 *card-ranks* :test #'string=) (position r2 *card-ranks* :test #'string=)))
|
|---|
| 78 |
|
|---|
| 79 | (defun sorted-by-rank (rlist)
|
|---|
| 80 | (when (typep rlist 'rank-list)
|
|---|
| 81 | (format nil "~{~a~^, ~}" (sort-list-in-place rlist #'higher-rank))))
|
|---|
| 82 |
|
|---|
| 83 | (defun card-suit (card)
|
|---|
| 84 | ;; card is a bit index
|
|---|
| 85 | (nth (floor card 13) *card-suits*))
|
|---|
| 86 |
|
|---|
| 87 | (defun pick-random-card (deck)
|
|---|
| 88 | ;; returns a card index
|
|---|
| 89 | (let* ((cnt (count 1 deck))
|
|---|
| 90 | (card (1+ (random cnt))))
|
|---|
| 91 | (position-if #'(lambda (bit)
|
|---|
| 92 | (when (plusp bit)
|
|---|
| 93 | (decf card))
|
|---|
| 94 | (zerop card))
|
|---|
| 95 | deck)))
|
|---|
| 96 |
|
|---|
| 97 | (defun add-card (deal hand card)
|
|---|
| 98 | (setf (assoc-aref deal hand (card-suit card))
|
|---|
| 99 | (cons (card-rank card) (assoc-aref deal hand (card-suit card)))))
|
|---|
| 100 |
|
|---|
| 101 | (defun remove-card (card deck)
|
|---|
| 102 | ;; card is a bit index
|
|---|
| 103 | (setf (aref deck card) 0))
|
|---|
| 104 |
|
|---|
| 105 | (defun deal-cards ()
|
|---|
| 106 | ;; randomizes and returns four unique hands
|
|---|
| 107 | (let ((deck (full-deck))
|
|---|
| 108 | (deal (make-instance 'assoc-array :rank 2))
|
|---|
| 109 | (card nil))
|
|---|
| 110 | (dotimes (i 13)
|
|---|
| 111 | (setf card (pick-random-card deck))
|
|---|
| 112 | (add-card deal "West" card)
|
|---|
| 113 | (remove-card card deck)
|
|---|
| 114 | (setf card (pick-random-card deck))
|
|---|
| 115 | (add-card deal "North" card)
|
|---|
| 116 | (remove-card card deck)
|
|---|
| 117 | (setf card (pick-random-card deck))
|
|---|
| 118 | (add-card deal "East" card)
|
|---|
| 119 | (remove-card card deck)
|
|---|
| 120 | (setf card (pick-random-card deck))
|
|---|
| 121 | (add-card deal "South" card)
|
|---|
| 122 | (remove-card card deck))
|
|---|
| 123 | deal))
|
|---|
| 124 |
|
|---|
| 125 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|---|
| 126 | ;; Test Function
|
|---|
| 127 |
|
|---|
| 128 | (defun test-deal ()
|
|---|
| 129 | (let* ((nib-name (lisp-to-temp-nsstring
|
|---|
| 130 | (namestring (truename "ip:Controller Test 3;lc-test3.nib"))))
|
|---|
| 131 | (wc (make-instance 'hand-of-cards
|
|---|
| 132 | :with-nib-path nib-name)))
|
|---|
| 133 | (#/window wc)
|
|---|
| 134 | wc))
|
|---|
| 135 |
|
|---|
| 136 | (provide :controller-test3)
|
|---|