Bridge Hands

The bridge hands problem on programming praxis in Common Lisp.

(defvar deck
 (loop for n from 0 to 51
 collect n))

(defun shuffle (deck &optional results)
 (if (not deck)
 (let* ((num-cards (length deck))
 (card (nth (random num-cards) deck)))
 (shuffle (remove card deck) (cons card results)))))

(defun deal (shuffled-deck)
 (loop for i from 0 to 3
 for deck = shuffled-deck then (subseq deck 13)
 for hand = (subseq deck 0 13)
 collect hand))

(defconstant empty-hand
 (list (list) (list) (list) (list)))

(defun add-to-hand (my-hand card)
 (let ((suit (floor card 13)))
 (setf (nth suit my-hand) (cons card (nth suit my-hand)))

(defun build-hand (card-list)
 (let ((my-hand (copy-tree empty-hand)))
 (loop for card in card-list do
 (setf my-hand (add-to-hand my-hand card))
 finally (return my-hand))))

(defun shuffle-deal-build ()
 (loop for card-list in (deal (shuffle deck))
 collect (build-hand card-list)))

(defun translate-card (card)
 (let ((card-strings
 #("2" "3" "4" "5" "6" "7" "8" "9" "10" "J" "Q" "K" "A")))
 (aref card-strings (rem card 13))))

(defun print-suit (card-list suit)
 (let ((sorted (sort card-list #'>))
 (suit-strings #("C: " "D: " "H: " "S: ")))
 (format t "~a" (aref suit-strings suit))
 (loop for card in sorted do
 (format t "~a " (translate-card card)))))

(defun print-hand (my-hand)
 (loop for suit from 3 downto 0 do
 (print-suit (nth suit my-hand) suit)
 (format t "~%"))))

(defun print-all-hands (shuffled-deck)
 for hand in shuffled-deck
 for tag in '("NORTH" "EAST" "SOUTH" "WEST")
 (format t "~a~%" tag)
 (print-hand hand)
 (format t "~%"))))