about summary refs log tree commit diff stats
path: root/js/games/nluqo.github.io/~bh/ssch9/bridge
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2023-08-23 07:52:19 -0400
committerelioat <elioat@tilde.institute>2023-08-23 07:52:19 -0400
commit562a9a52d599d9a05f871404050968a5fd282640 (patch)
tree7d3305c1252c043bfe246ccc7deff0056aa6b5ab /js/games/nluqo.github.io/~bh/ssch9/bridge
parent5d012c6c011a9dedf7d0a098e456206244eb5a0f (diff)
downloadtour-562a9a52d599d9a05f871404050968a5fd282640.tar.gz
*
Diffstat (limited to 'js/games/nluqo.github.io/~bh/ssch9/bridge')
-rw-r--r--js/games/nluqo.github.io/~bh/ssch9/bridge254
1 files changed, 254 insertions, 0 deletions
diff --git a/js/games/nluqo.github.io/~bh/ssch9/bridge b/js/games/nluqo.github.io/~bh/ssch9/bridge
new file mode 100644
index 0000000..6d4cede
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/ssch9/bridge
@@ -0,0 +1,254 @@
+\input bkmacs
+\projchap{Project: Scoring Bridge Hands}
+\write\toc{\begingroup\blskip{1}} %%% ends in leap.tex
+
+At the beginning of a game of bridge, each player assigns a value to his or
+her hand by counting {\it points.\/}  Bridge players use these points in the
+first part of the game, the ``bidding,'' to decide how high to bid.  (A
+bid is a promise about how well you'll do in the rest of the game.  If you
+succeed in meeting your bid you win, and if you don't meet the bid, you
+lose.)  For example, if you have fewer than six points, you generally don't
+bid anything at all.
+
+You're going to write a computer program to look at a bridge hand and decide
+how many points it's worth.  You won't have to know anything about the rest
+of the game; we'll tell you the rules for counting points.
+
+A bridge hand contains thirteen cards.  Each ace in the hand is worth four
+\justidx{bridge points}
+\justidx{points, bridge}
+points, each king is worth three points, each queen two points, and each
+jack one.  The other cards, twos through tens, have no point value.
+So if your hand has two aces, a king, two jacks, and eight other
+cards, it's worth thirteen points.
+
+A bridge hand might also have some ``distribution'' points, which are points
+having to do with the distribution of the thirteen cards among the four
+suits.  If your hand has only two cards of a particular suit, then it is
+worth an extra point.  If it has a ``singleton,'' only one card of a
+particular suit, that's worth two extra points.  A ``void,'' no cards in a
+particular suit, is worth three points.
+
+In our program, we'll represent a card by a word like {\tt h5} (five of
+hearts) or {\tt dk} (king of diamonds).\footnt{Why not {\tt 5h}?  Scheme
+words that begin with a digit but aren't numbers have to be surrounded with
+double-quote marks.  Putting the suit first avoids that.} A hand will be a
+sentence of cards, like this:
+
+{\prgex%
+(sa s10 s7 s6 s2 hq hj h9 ck c4 dk d9 d3)
+}
+
+This hand is worth 14 points:\ ace of spades (4), plus queen of hearts
+(2), plus jack of hearts (1), plus king of clubs (3), plus king of diamonds
+(3), plus one more for having only two clubs.
+
+To find the suit of a card, we take its {\tt first}, and to find the rank, we
+take the {\tt butfirst}.  (Why not the {\tt last}?)
+
+We have a particular program structure in mind.  We'll describe all of the
+procedures you need to write; if you turn each description into a working
+procedure, then you should have a complete program.  In writing each
+procedure, take advantage of the ones you've already written.  Our
+descriptions are ordered {\it \idx{bottom-up}\/}, which means that for each
+procedure you will already have written the helper procedures you need.
+(This ordering will help you write the project, but it means that we're
+beginning with small details.  If we were describing a project to help you
+understand its structure, we'd do it in {\it \idx{top-down}\/} order,
+starting with the most general procedures.  We'll do that in the next
+chapter, in which we present a tic-tac-toe program as a larger Scheme
+programming example.)
+
+\function{Card-val}
+
+Write a procedure {\tt \ufun{card-val}} that takes a single card as its
+argument and returns the value of that card.
+
+{\prgex%
+> (card-val 'cq)
+2
+
+> (card-val 's7)
+0
+
+> (card-val 'ha)
+4
+}
+
+\solution
+{\prgex%
+(define (card-val card)
+  (cond ((equal? (bf card) 'a) 4)
+	((equal? (bf card) 'k) 3)
+	((equal? (bf card) 'q) 2)
+	((equal? (bf card) 'j) 1)
+	(else 0)))
+}
+@
+
+\function{High-card-points}
+
+Write a procedure {\tt \ufun{high-card-points}} that takes a hand as its
+argument and returns the total number of points from high cards in the
+hand.  (This procedure does {\it not\/} count distribution points.)
+
+{\prgex%
+> (high-card-points '(sa s10 hq ck c4))
+9
+
+> (high-card-points '(sa s10 s7 s6 s2 hq hj h9 ck c4 dk d9 d3))
+13
+}
+
+\solution
+{\prgex%
+(define (high-card-points hand)
+  (accumulate + (every card-val hand)))
+}
+@
+
+\function{Count-suit}
+
+Write a procedure {\tt \ufun{count-suit}} that takes a suit and a hand as
+arguments and returns the number of cards in the hand with the given suit.
+
+{\prgex%
+> (count-suit 's '(sa s10 hq ck c4))
+2
+
+> (count-suit 'c '(sa s10 s7 s6 s2 hq hj h9 ck c4 dk d9 d3))
+2
+
+> (count-suit 'd '(h3 d7 sk s3 c10 dq d8 s9 s4 d10 c7 d4 s2))
+5
+}
+
+\solution
+{\prgex%
+(define (count-suit suit hand)
+  (count (keep (lambda (card) (equal? (first card) suit)) hand)))
+}
+
+Thinking about domain and range really helps in this problem;
+there are many ways to get confused about what to use as argument
+to which helper function.  In particular, it's important to
+distinguish among the data types suit, card, and hand.
+@
+
+\function{Suit-counts}
+
+Write a procedure {\tt \ufun{suit-counts}} that takes a hand as its argument
+and returns a sentence containing the number of spades, the number of hearts,
+the number of clubs, and the number of diamonds in the hand.
+
+{\prgex%
+> (suit-counts '(sa s10 hq ck c4))
+(2 1 2 0)
+
+> (suit-counts '(sa s10 s7 s6 s2 hq hj h9 ck c4 dk d9 d3))
+(5 3 2 3)
+
+> (suit-counts '(h3 d7 sk s3 c10 dq d8 s9 s4 d10 c7 d4 s2))
+(5 1 2 5)
+}
+
+\solution
+{\prgex%
+(define (suit-counts hand)
+  (every (lambda (suit) (count-suit suit hand))
+	 '(s h c d)))
+}
+
+This solution is not obvious, because the second argument to
+{\tt every} is a constant, rather than one of the original
+arguments.  Students may find it easier to understand this
+less elegant alternative:
+
+{\prgex%
+(define (suit-counts hand)
+  (se (count-suit 's hand)
+      (count-suit 'h hand)
+      (count-suit 'c hand)
+      (count-suit 'd hand)))
+}
+@
+
+\function{Suit-dist-points}
+
+Write {\tt \ufun{suit-dist-points}} that takes a number as its argument,
+interpreting it as the number of cards in a suit.  The procedure should
+return the number of distribution points your hand gets for having that
+number of cards in a particular suit.
+
+{\prgex%
+> (suit-dist-points 2)
+1
+
+> (suit-dist-points 7)
+0
+
+> (suit-dist-points 0)
+3
+}
+
+\solution
+{\prgex%
+(define (suit-dist-points n)
+  (if (<= n 2)
+      (- 3 n)
+      0))
+}
+
+\noindent or, the slightly less elegant way:
+
+{\prgex%
+(define (suit-dist-points n)
+  (cond ((= n 0) 3)
+	((= n 1) 2)
+	((= n 2) 1)
+	(else 0)))
+}
+@
+
+\function{Hand-dist-points}
+
+Write {\tt \ufun{hand-dist-points}}, which takes a hand as its argument and
+returns the number of distribution points the hand is worth.
+
+{\prgex%
+> (hand-dist-points '(sa s10 s7 s6 s2 hq hj h9 ck c4 dk d9 d3))
+1
+
+> (hand-dist-points '(h3 d7 sk s3 c10 dq d8 s9 s4 d10 c7 d4 s2))
+3
+}
+
+\solution
+{\prgex%
+(define (hand-dist-points hand)
+  (accumulate + (every suit-dist-points (suit-counts hand))))
+}
+@
+
+\function{Bridge-val}
+
+Write a procedure {\tt \ufun{bridge-val}} that takes a hand as its argument
+and returns the total number of points that the hand is worth.
+
+{\prgex%
+> (bridge-val '(sa s10 s7 s6 s2 hq hj h9 ck c4 dk d9 d3))
+14
+
+> (bridge-val '(h3 d7 sk s3 c10 dq d8 s9 s4 d10 c7 d4 s2))
+8
+}
+
+\solution
+{\prgex%
+(define (bridge-val hand)
+  (+ (high-card-points hand)
+     (hand-dist-points hand)))
+}
+@
+
+\bye