Fun with card tricks (Matt Gertz)

Anthony D. Green [MSFT]

Back when I first started writing code, I got interested in game writing, and was fairly sure I could write out text-based games as well as the other offerings one could find on mainframes and, later, on the Commodores/TRS/Apples of the day.   The flow of those games were really very easy – you’d present a block of text to the user to read to set up the situation, and then simply prompt the user for a pseudo-English sentence which you’d parse for keywords (“GO NORTH,” “PICK UP  SWORD,” “SHOOT BOB,” etc) – you’d then proceed to the next block of text, and so on.  Easy to write, easy to amaze your friends with your epic tales of mayhem and mystery.

Later, being somewhat more ambitious, I decided to look into the world of “sprites.”  A sprite was a simply a block of pixels (8×8 on the C-64, for example) which you “poked” into memory, and then you could move it around on the screen.  Generally, you made the sprite respond to a joystick or arrow keys.  A programmer could write code to see when sprites intersected and react appropriately to it, checking this in an infinite loop, so the games that I wrote at this time were generally shoot-em-up games or car races.

When I started writing code for the MacPlus around the mid-eighties, though, I was totally at a loss –message loops had me mystified for a long time.  “Hidden” code bothered me and I had a hard time figuring out how code could be completely controlled in that world.  Where did it start?  Where did it end?  How could you block on input?  But what I ultimately realized much later is that message-driven programming was simply taking the boilerplate responsibilities away from me – surely a good thing.

Nevertheless, it’s still not exactly obvious how to write code for a (for example) forms game where you need to block on user input.  Let’s take the case of a card game program.  At the beginning, everything is nice and uninterrupted – you shuffle the cards and deal them out, a very straightforward process.  Now, however, comes the bidding and playing.  You need to loop over the players and see what they want to do with their cards.  If they were all AI, then again there’s no problem – flow can continue uninterrupted.  However, ideally there’s at least one human playing the game, and that user needs to interact with the application – you need to block execution on their input without freezing the form.  There is no equivalent to a console app’s “get” in a visual environment, so how does this work?

Over the next few posts (spaced about every two days), I’m going to present an implementation of a card game as a WinForms app.  In the process, I’ll be demonstrating several concepts in VB .NET programming, including event handling, user controls, text-to-speech, and deployment; the use of several different kinds of controls, including rich text editing, timers, and tooltips; the use of several kinds of resources including strings, images, icons, and sounds; extensive use of the “My” functionality for playing sound, accessing resources.  Since, for me, the development is always intertwined with the design, I’ll be walking through my thought processes there as well.

Euchre is the name of the game

Euchre (pronounced YOO-ker) isn’t just a passion where I grew up; it’s an obsession.  For those of you who’ve never heard of it, it’s a trick-based trump card game where the idea is to score points by playing the highest card each round.  The game is partner based, similar in many ways to its distant cousin, Bridge (or Whist, if you prefer), but the rounds are faster and the company is, perhaps, less genteel.  Being a good Euchre partner was a sure invitation to a party when I was young; if you didn’t play Euchre, though, well then you were probably a radical and certainly going to be viewed with some suspicion. J

So, let’s start working on our Euchre game & see what’s interesting in the technology.  If you can make it through all of these posts, you will find a free and complete high-quality Euchre game at the end, personally written by Yours Truly and tested by some mean-tempered, no-nonsense Euchre aficionados (i.e., my relatives).  I’ll throw in the source code as well, so that you can see how everything works together.  (Note that it is copyrighted, though, meaning that if you take this game and sell it for profit, I’ll have to hunt you down.  Or, better yet, I’ll have Paul “Two-Fisted Death” Yuknewicz do it for me.  You don’t want mess with Paul…)

Don’t worry about the rules, by the way… I’ll introduce them if and as they become appropriate to the coding.  For now, just assume that we have to deal out the cards to four people, and each person gets a turn to put a card down on each round.

Coding a Euchre Game, Part 1: Working with lots of controls in the forms editor

I’m a very visual programmer and I like to have my classes and objects match up with real-world “nouns” wherever possible.  So, in this case, what are our “nouns?”

          A card table

          The deck, which contains cards

          The players

Let’s focus on the card table for a bit.  The default form will be our card table.  What needs to be on the table?

(1)    Places for the cards to go, both in the hands, in the “unused” pile, and when played.  We’ll use labels to mark where the cards should land – we can leverage their image property to actually display the cards later.

(2)    Places for the score to be shown.  Again, labels make the most sense here.

(3)    A place where the user can see what the actions are of the default players.  Ideally, this should scroll so that the user can look back in time to see what cards have been played, etc.  We’ll use a Rich Text Edit control for this.

(4)    A “Continue” button so that the player can cause play to proceed after reviewing the cards played.

(5)    A label to prompt the user to play a card, and labels to say what the trump suit is and who called it, all of which I’ll hide or show as needed.

(6)    Groupboxes to show who the dealer is this round, hiding and showing them as necessary.

(7)    Various decorations, all of which can use labels or bitmap controls.

What I want is a table that looks like the one I’ve attached to this post — go take a look at EuchreForm1.jpg.

“Holy catfish, Matt!” I hear you cry.  “That’s a lot of controls to lay down!  Surely you don’t expect me to drag out all of those from the toolbox!”  In fact, that screenshot shows nearly 50 controls, and indeed if you had to lay all of those out and assign properties to them individually, it would certainly be an exercise in tedium. 

Control-Drag

Fortunately, there’s a shortcut – many of the controls share properties with each other.  For example, there are 28 “card” controls (actually simple labels), and that’s over half of the content right there.  All you need to do is drag out one label control, size it to represent a vertical card, and add the appropriate properties.  (For each card, that’s just BorderStyle=FixedSingle, Visible=False, and Size={80,104}).  Now, holding down the control key and dragging the label, you’ll create a duplicate of that label when you release the mouse button.  Position it, select both labels, control-drag, and now you have four of the cards.  Continue this until you have all of the vertical cards. 

Now, for the horizontal cards, control-drag one vertical card, flip its size to be {104,80}, and then use the resulting card to control-drag out all of the other horizontal cards.  In less than five minutes, nearly half of the work is done!  You can repeat this control-drag timesaver for the score areas (the violet labels I show above), the group boxes around the hands, the labels for the player identification, and so on.  Really, the only solo controls are the yellow rich edit text box at the bottom, the fancy bitmap in the middle, the “Continue” button, and the prompt to “Please select a card to play.”  Except the score labels, the player identifiers, and the text box, all of the controls will be set to invisible by default, and will be shown as needed.

Now, you’ll want to rename all of those controls to something more appropriate for coding, and ideally they should involve some sequence so that it’s clear when I’m working with the player’s card #1 or partner’s card #3, for example.  Unfortunately, there’s no good easy way to do that other than selecting each control and renaming it in the property grid.  You could rename them in the hidden partial class file EuchreTable.Designer.vb (which can be seen if you select “Show All Files”), but the problem is that you can’t be easily sure which label is which.  So, we’ll do this the hard way, and simply change each label in the forms editor to “PlayerCard1,” “PlayerCard2,” etc.

I also set “Localizable” to True for the form, so that the resources’ text will be defined in a resource file instead of hard-coded.

So, that’s the easy part done.  There’s nothing terribly technically challenging yet, but that will change in subsequent posts.  In part 2, I’m going to discuss image management.  See you then!

–Matt–*

EuchreForm1.jpg

0 comments

Leave a comment

Feedback usabilla icon