[Newbies] The Bridge Playing example

Todd Blanchard tblanchard at mac.com
Mon Aug 25 07:16:03 UTC 2008

I'm sitting here watching Bootcamp install Windows XP - guess I'll  
kill some time. :-)

On Aug 24, 2008, at 4:58 PM, Andy Burnett wrote:

> Todd, thanks for writing that up. I found it really interesting to  
> see how you tackled the problem.  I think it would be great if - as  
> time permits - the experts of the list could take a problem - nice  
> simple ones would be good, and show how you might solve it.  It is  
> also very interesting to see how you refine/modify each others'  
> solutions.

Well my knowledge of bridge is pretty superficial and it is possible I  
have just hit the bottom.  You guys pose problems and I'm sure someone  
will point you towards a solution.  I totally empathize with the whole  
"Just can't get started" problem. Anyhow, some obvious initial  

1) Randal is absolutely right that the variables north,east,south,west  
should probably be put into some kind of indexed storage because you  
tend to access them in a kind of sequence (going around the circle  
either playing or dealing) and you do the same thing to each.  So his  

hands := IdentityDictionary newFrom:
  (#(north east south west) collect: [:each | each -> Set new]).

is good.  It creates a dictionary where the keys are symbols and the  
values are Sets.  So now, if you want north's cards, you say

(hands at: #north)

and to "go around the circle" you could say

#(north east south west) do: [:position | (hands at: position)  
doSomethingOrOther ]

 From a style perspective, I'm not thrilled about pulling things out  
of dictionaries constantly and I'd be likely to implement accessors  
for convenience

    ^ hands at: #north

because I think it is prettier to say

self north doSomethingOrOther


(hands at: #north) doSomethingOrOther

but you could argue that, given the cyclic nature of a card game,  
you'd probably never use them.

2) How to model a hand

I started with OrderedCollection because cards are dealt in an order  
and I half-thought the order might matter.  However, it turns out that  
it doesn't really matter in Bridge which is probably why Randal chose  
Set.  Set has no concept of ordering and has the added nice property  
of disallowing a card from being in a hand twice, which is somewhat  
more realistic in Bridge but not so much in a game like Pinochle where  
you can have two of the same card.  You could solve that by using  
IdentitySet I suppose.

Incidentally, that is why Card responds to bridgeDeck rather than just  
deck.  You might add pinochleDeck or canastaDeck.  These are decks  
made out of the same kinds of cards, but composed differently (I dated  
a cards fiend in college - I've forgotten most of the rules but  
remember a few basics).

Actually, in Bridge, players invariably sort their hands by suit, then  
rank as soon as they are dealt so maybe a SortedCollection with a  
custom sort block makes more sense.  At least if you are displaying  
the cards to human users.  Something like:

bySuitsThenRank := : [:x :y | ((x suit) = (y suit)) ifTrue: [x rank <  
y rank] ifFalse: [x suit < y suit]]. " block value is true if x and y  
are in right order, false if not"

now you get

hands := IdentityDictionary newFrom:
  (#(north east south west) collect: [:each | each ->  
(SortedCollection sortBlock:  bySuitsThenRank) ]).

This gives me a typical hand looking like:
a SortedCollection(Ace of Clubs Jack of Clubs Ace of Hearts 3 of  
Hearts 4 of Hearts 5 of Hearts Ace of Diamonds 6 of Diamonds 10 of  
Diamonds Jack of Diamonds 2 of Spades 3 of Spades Queen of Spades)

which is how I typically sort my bridge hands.

If you want to do your own card game, I recommend trying to write  
blackjack.  That's a program I used to assign my C students.  Write a  
program that lets a person play the computer (who is dealer). The  
rules are dead easy (dealer hits on 16, stays on 17 I think) but there  
are nuances in evaluating the current hand when aces are involved.   
Also, in BJ, I'd go back to OrderedCollection for representing a hand  
because order matters - the first card is the 'down' card and is not  
revealed to the other players until the end of the round.

Just tossing ideas.

More information about the Beginners mailing list