<< Todd said: A deck, hand, pile, all can be implemented as just an OrderedCollection. You might start with a Deal or BridgeRound or something. It might have some methods like:
initialize | hands deck | deck := Card bridgeDeck shuffled asOrderedCollection. "just like english" north := OrderedCollection new. south := OrderedCollection new. east := OrderedCollection new. west := OrderedCollection new. trick := OrderedCollection new.
-- snip -- >>
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.
cheers AB
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 refinements:
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 refinement
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
north ^ hands at: #north
because I think it is prettier to say
self north doSomethingOrOther
than
(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.
beginners@lists.squeakfoundation.org