Sheet1
Page 1
CS 61A
Project #1
(TwentyOne)
Solutions
(Note:
Although these posted solutions do not include transcripts,
the handout required you to provide transcripts showing that your
procedures work correctly.
One of the things you are supposed to
be learning is how to test a program.
For example, in this project,
it's not good enough to test a strategy just by playing a game with
it and seeing that it doesn't blow up, like this:
> (twentyone somestrategy)
1
The transcript must show that the strategy procedure actually
carries out the desired strategy, either by invoking the procedure
directly with wellchosen arguments or by playing several games
with the strategy procedure traced.)
1.
besttotal
The most straightforward way to do this is to go through the
hand, keep track of total points (with some fixed value for
aces) and also keep track of the number of aces, and perhaps
adjust the total once the whole hand has been tallied.
Because
you need to keep track of two values at once, this is a case
where an iterative subprocedure with extra state variables
is useful.
Should you initially count aces as 1 or as 11?
Either is possible.
Here is a solution counting aces as 11:
(define (besttotal hand)
(define (value rank)
(cond ((number? rank) rank)
((equal? rank 'A) 11)
(else 10)))
(define (lower aces points)
(cond ((<= points 21) points)
((= aces 0) points)
(else (lower ( aces 1) ( points 10))) ))
(define (total aces points hand)
(if (empty? hand)
(lower aces points)
(let ((rank (bl (first hand))))
(total (if (equal? rank 'A) (+ aces 1) aces)
(+ points (value rank))
(bf hand)) )))
(total 0 0 hand))
The final computation is a little simpler (avoiding the
recursive call in LOWER) if you realize that at most one
ace should be counted as 11 points.
If you initially
count aces as 1, you end up with this:
This preview has intentionally blurred sections. Sign up to view the full version.
View Full Document
Sheet1
Page 2
(define (besttotal hand)
(define (value rank)
(cond ((number? rank) rank)
((equal? rank 'A) 1)
(else 10)))
(define (raise aces points)
(if (and (<= points 11) (> aces 0))
(+ points 10)
points ))
(define (total aces points hand)
(if (empty? hand)
(raise aces points)
(let ((rank (bl (first hand))))
(total (if (equal? rank 'A) (+ aces 1) aces)
(+ points (value rank))
(bf hand)) )))
(total 0 0 hand))
I used BUTLAST rather than FIRST to extract the rank of a card
because tens have a twocharacter rank.
(bl '10s) is the correct
10 but (first '10s) is just 1.
2.
stopat17
One way that people messed up on this problem was to try to copy the
code in playdealer.
But the latter isn't a strategy procedure
is, it doesn't take a hand and a card as arguments and return #t or
#f as its value.
The decision process is the same, but the
context is different.
This is the end of the preview.
Sign up
to
access the rest of the document.
 Fall '08
 Harvey

Click to edit the document details