APPENDIX: SOLUTION TO BRIDGE HANDS PROJECT

Please familiarize yourself with this and then copy/paste it into DrRacket.

; Bridge hands starter kit

; When dealing with bridge hands, we really want to be talking about
; cards and their ranks and suits. If you asked a friend what the
; butfirst of a card was, they would think you were crazy. So we will
; create an abstraction for cards that allows us to think in terms of
; cards, ranks, and suits, and we will then use those functions.

; Constructor for cards: make-card takes a suit and rank and returns a card
(define (make-card suit rank)
   (word suit rank))

; Selectors for cards: rank, suit (incredibly useful for this project)
(define (rank card) (bf card))
(define (suit card) (first card))

; Get the numeric rank of a card (useful for poker project)
(define (numeric-rank card)  ; allows us to do math on ranks
  (let ((r (rank card)))
    (cond ((equal? r 'a) 14)
          ((equal? r 'k) 13)
          ((equal? r 'q) 12)
          ((equal? r 'j) 11)
          (else r))))

; Sentences that may or may not be useful, but list all the possibilities
(define ranks '(a k q j 10 9 8 7 6 5 4 3 2))
(define numeric-ranks (every numeric-rank ranks))
(define suits '(s h d c))

; Rank functions
(define (card-val card)
  (max (- (numeric-rank card) 10) 0))
(define (high-card-points hand)
  (accumulate + (every card-val hand)))

; Suit functions
(define (count-suit s hand)
  (count (keep (lambda (card) (equal? s (suit card))) hand)))
(define (suit-counts hand)
  (every (lambda (s) (count-suit s hand)) suits))
(define (suit-dist-points num-cards-in-suit)
  (max 0 (- 3 num-cards-in-suit)))
(define (hand-dist-points hand)
  (accumulate + (every suit-dist-points (suit-counts hand))))

; Put it all together
(define (bridge-val hand)
  (+ (high-card-points hand) (hand-dist-points hand)))