{"id":6563,"date":"2007-03-12T17:40:00","date_gmt":"2007-03-12T17:40:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2007\/03\/12\/fun-with-card-tricks-matt-gertz\/"},"modified":"2024-07-05T14:50:19","modified_gmt":"2024-07-05T21:50:19","slug":"fun-with-card-tricks-matt-gertz","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/fun-with-card-tricks-matt-gertz\/","title":{"rendered":"Fun with card tricks (Matt Gertz)"},"content":{"rendered":"<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">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.<span>&nbsp;&nbsp; <\/span>The flow of those games were really very easy \u2013 you\u2019d 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\u2019d parse for keywords (\u201cGO NORTH,\u201d \u201cPICK UP<span>&nbsp; <\/span>SWORD,\u201d \u201cSHOOT BOB,\u201d etc) \u2013 you\u2019d then proceed to the next block of text, and so on.<span>&nbsp; <\/span>Easy to write, easy to amaze your friends with your epic tales of mayhem and mystery.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Later, being somewhat more ambitious, I decided to look into the world of \u201csprites.\u201d<span>&nbsp; <\/span>A sprite was a simply a block of pixels (8&#215;8 on the C-64, for example) which you \u201cpoked\u201d into memory, and then you could move it around on the screen.<span>&nbsp; <\/span>Generally, you made the sprite respond to a joystick or arrow keys.<span>&nbsp; <\/span>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.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">When I started writing code for the MacPlus around the mid-eighties, though, I was totally at a loss \u2013message loops had me mystified for a long time.<span>&nbsp; <\/span>\u201cHidden\u201d code bothered me and I had a hard time figuring out how code could be completely controlled in that world.<span>&nbsp; <\/span>Where did it start?<span>&nbsp; <\/span>Where did it end?<span>&nbsp; <\/span>How could you block on input?<span>&nbsp; <\/span>But what I ultimately realized much later is that message-driven programming was simply taking the boilerplate responsibilities away from me \u2013 surely a good thing.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Nevertheless, it\u2019s still not exactly obvious how to write code for a (for example) forms game where you need to block on user input.<span>&nbsp; <\/span>Let\u2019s take the case of a card game program.<span>&nbsp; <\/span>At the beginning, everything is nice and uninterrupted \u2013 you shuffle the cards and deal them out, a very straightforward process.<span>&nbsp; <\/span>Now, however, comes the bidding and playing.<span>&nbsp; <\/span>You need to loop over the players and see what they want to do with their cards.<span>&nbsp; <\/span>If they were all AI, then again there\u2019s no problem \u2013 flow can continue uninterrupted.<span>&nbsp; <\/span>However, ideally there\u2019s at least one human playing the game, and that user needs to interact with the application \u2013 you need to block execution on their input without freezing the form.<span>&nbsp; <\/span>There is no equivalent to a console app\u2019s \u201cget\u201d in a visual environment, so how does this work?<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Over the next few posts (spaced about every two days), I\u2019m going to present an implementation of a card game as a WinForms app.<span>&nbsp; <\/span>In the process, I\u2019ll 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 \u201cMy\u201d functionality for playing sound, accessing resources.<span>&nbsp; <\/span>Since, for me, the development is always intertwined with the design, I\u2019ll be walking through my thought processes there as well.<\/font><\/p>\n<h2><font face=\"Cambria\" color=\"#4f81bd\" size=\"4\">Euchre is the name of the game<\/font><\/h2>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">Euchre (pronounced YOO-ker) isn\u2019t just a passion where I grew up; it\u2019s an obsession.<span>&nbsp; <\/span>For those of you who\u2019ve never heard of it, it\u2019s a trick-based trump card game where the idea is to score points by playing the highest card each round.<span>&nbsp; <\/span>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.<span>&nbsp; <\/span>Being a good Euchre partner was a sure invitation to a party when I was young; if you didn\u2019t play Euchre, though, well then you were probably a radical and certainly going to be viewed with some suspicion. <\/font><span><span>J<\/span><\/span><\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">So, let\u2019s start working on our Euchre game &amp; see what\u2019s interesting in the technology.<span>&nbsp; <\/span>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).<span>&nbsp; <\/span>I\u2019ll throw in the source code as well, so that you can see how everything works together.<span>&nbsp; <\/span>(Note that it is copyrighted, though, meaning that if you take this game and sell it for profit, I\u2019ll have to hunt you down.<span>&nbsp; <\/span>Or, better yet, I\u2019ll have Paul \u201cTwo-Fisted Death\u201d Yuknewicz do it for me.<span>&nbsp; <\/span>You don\u2019t want mess with Paul\u2026)<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Don\u2019t worry about the rules, by the way\u2026 I\u2019ll introduce them if and as they become appropriate to the coding.<span>&nbsp; <\/span>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.<\/font><\/p>\n<h2><font face=\"Cambria\" color=\"#365f91\" size=\"5\">Coding a Euchre Game, Part 1: Working with lots of controls in the forms editor<\/font><\/h2>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">I\u2019m a very visual programmer and I like to have my classes and objects match up with real-world \u201cnouns\u201d wherever possible.<span>&nbsp; <\/span>So, in this case, what are our \u201cnouns?\u201d<\/font><\/p>\n<p class=\"MsoListParagraphCxSpFirst\"><span><span><font face=\"Calibri\" size=\"3\">&#8211;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">A card table<\/font><\/p>\n<p class=\"MsoListParagraphCxSpMiddle\"><span><span><font face=\"Calibri\" size=\"3\">&#8211;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">The deck, which contains cards<\/font><\/p>\n<p class=\"MsoListParagraphCxSpLast\"><span><span><font face=\"Calibri\" size=\"3\">&#8211;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">The players<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Let\u2019s focus on the card table for a bit.<span>&nbsp; <\/span>The default form will be our card table.<span>&nbsp; <\/span>What needs to be on the table?<\/font><\/p>\n<p class=\"MsoListParagraphCxSpFirst\"><span><span><font face=\"Calibri\" size=\"3\">(1)<\/font><span>&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Places for the cards to go, both in the hands, in the \u201cunused\u201d pile, and when played.<span>&nbsp; <\/span>We\u2019ll use labels to mark where the cards should land \u2013 we can leverage their image property to actually display the cards later.<\/font><\/p>\n<p class=\"MsoListParagraphCxSpMiddle\"><span><span><font face=\"Calibri\" size=\"3\">(2)<\/font><span>&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Places for the score to be shown.<span>&nbsp; <\/span>Again, labels make the most sense here.<\/font><\/p>\n<p class=\"MsoListParagraphCxSpMiddle\"><span><span><font face=\"Calibri\" size=\"3\">(3)<\/font><span>&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">A place where the user can see what the actions are of the default players.<span>&nbsp; <\/span>Ideally, this should scroll so that the user can look back in time to see what cards have been played, etc.<span>&nbsp; <\/span>We\u2019ll use a Rich Text Edit control for this.<\/font><\/p>\n<p class=\"MsoListParagraphCxSpMiddle\"><span><span><font face=\"Calibri\" size=\"3\">(4)<\/font><span>&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">A \u201cContinue\u201d button so that the player can cause play to proceed after reviewing the cards played.<\/font><\/p>\n<p class=\"MsoListParagraphCxSpMiddle\"><span><span><font face=\"Calibri\" size=\"3\">(5)<\/font><span>&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">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\u2019ll hide or show as needed.<\/font><\/p>\n<p class=\"MsoListParagraphCxSpMiddle\"><span><span><font face=\"Calibri\" size=\"3\">(6)<\/font><span>&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Groupboxes to show who the dealer is this round, hiding and showing them as necessary.<\/font><\/p>\n<p class=\"MsoListParagraphCxSpLast\"><span><span><font face=\"Calibri\" size=\"3\">(7)<\/font><span>&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Various decorations, all of which can use labels or bitmap controls.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">What I want is a table that looks like the one I&#8217;ve attached to this post &#8212; go take a look at EuchreForm1.jpg.<\/font><\/p>\n<p class=\"MsoNormal\" align=\"center\"><span><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">\u201cHoly catfish, Matt!\u201d I hear you cry.<span>&nbsp; <\/span>\u201cThat\u2019s a lot of controls to lay down!<span>&nbsp; <\/span>Surely you don\u2019t expect me to drag out all of those from the toolbox!\u201d<span>&nbsp; <\/span>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.<span>&nbsp; <\/span><\/font><\/font><\/p>\n<h2><font face=\"Cambria\" color=\"#4f81bd\" size=\"4\">Control-Drag<\/font><\/h2>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">Fortunately, there\u2019s a shortcut \u2013 many of the controls share properties with each other.<span>&nbsp; <\/span>For example, there are 28 \u201ccard\u201d controls (actually simple labels), and that\u2019s over half of the content right there.<span>&nbsp; <\/span>All you need to do is drag out one label control, size it to represent a vertical card, and add the appropriate properties.<span>&nbsp; <\/span>(For each card, that\u2019s just BorderStyle=FixedSingle, Visible=False, and Size={80,104}).<span>&nbsp; <\/span>Now, holding down the control key and dragging the label, you\u2019ll create a duplicate of that label when you release the mouse button.<span>&nbsp; <\/span>Position it, select both labels, control-drag, and now you have four of the cards.<span>&nbsp; <\/span>Continue this until you have all of the vertical cards.<span>&nbsp; <\/span><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">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.<span>&nbsp; <\/span>In less than five minutes, nearly half of the work is done!<span>&nbsp; <\/span>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.<span>&nbsp; <\/span>Really, the only solo controls are the yellow rich edit text box at the bottom, the fancy bitmap in the middle, the \u201cContinue\u201d button, and the prompt to \u201cPlease select a card to play.\u201d<span>&nbsp; <\/span>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.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Now, you\u2019ll want to rename all of those controls to something more appropriate for coding, and ideally they should involve some sequence so that it\u2019s clear when I\u2019m working with the player\u2019s card #1 or partner\u2019s card #3, for example.<span>&nbsp; <\/span>Unfortunately, there\u2019s no good easy way to do that other than selecting each control and renaming it in the property grid.<span>&nbsp; <\/span>You could rename them in the hidden partial class file EuchreTable.Designer.vb (which can be seen if you select \u201cShow All Files\u201d), but the problem is that you can\u2019t be easily sure which label is which.<span>&nbsp; <\/span>So, we\u2019ll do this the hard way, and simply change each label in the forms editor to \u201cPlayerCard1,\u201d \u201cPlayerCard2,\u201d etc.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">I also set \u201cLocalizable\u201d to True for the form, so that the resources\u2019 text will be defined in a resource file instead of hard-coded. <\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">So, that\u2019s the easy part done.<span>&nbsp; <\/span>There\u2019s nothing terribly technically challenging yet, but that will change in subsequent posts.<span>&nbsp; <\/span>In part 2, I\u2019m going to discuss image management.<span>&nbsp; <\/span>See you then!<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&#8211;Matt&#8211;*<\/font><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/EuchreForm1.jpg\">EuchreForm1.jpg<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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.&nbsp;&nbsp; The flow of those games were really very easy \u2013 you\u2019d present a [&hellip;]<\/p>\n","protected":false},"author":258,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[22,195],"tags":[101,165],"class_list":["post-6563","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-matt-gertz","category-visual-basic","tag-matt-gertz","tag-vb2005"],"acf":[],"blog_post_summary":"<p>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.&nbsp;&nbsp; The flow of those games were really very easy \u2013 you\u2019d present a [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/6563","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/258"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=6563"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/6563\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=6563"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=6563"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=6563"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}