July 2004 - Posts
You can check out the previous entry here Watch out for "Power Toys", sometimes you get more than you bargained for. However, I'm more interested in examining why the failure occurs when adding a label. This is an issue that one of the users found when playing with the Toaster. Since I had to do some examination to find the underlying issue I can walk you through the process. What are we given?
- Adding a Button doesn't cause the failure adding a Label does. That means I can look at differences in the code.
- He gives me a stack trace, which I'm also able to reproduce so I can use that as well.
- The top of the stack is in the DibGraphicsBufferManager, one of the most infamous pieces of work to date.
I added that last one there, the infamous part, because many users have trouble with double buffering under Windows Forms when doing animations.
Well, it does appear Windows Forms isn't AnimateWindow friendly. A rogue series of WM_PAINT messages are being processed by the label and then the allocation of a graphics buffer for double buffering is failing. Why? Well, I didn't go far enough to find out exactly why, but there are two options. Either the window has already changed size by the time the message is processed which is the most likely, or AnimateWindow doesn't like the creation of buffers while it is running. I think the issue would lie in the first option because it doesn't appear any work is done to prevent a double buffered control from allocating a buffer based on an old bounding region. There isn't any error control around any of the buffer allocations failing at all.
There are some more interesting notes that I'll point out:
- It doesn't fail unless the label is large ;-) This is because the code-path is exercised for temporary buffers.
- Docking the Label generally builds up the appropriate size for it to fail.
- It only happens on double buffered controls. Any other controls will not fail in this manner.
Could the buffer manager be fixed to be resilient to this failure? Yes, it wouldn't be that hard. It would be nice if you didn't have to animate a window using a timer. The problem with a timer and animating a window is that it isn't nearly as fast as using AnimateWindow and doesn't have any of the built in drawing enhancements. The easiest fix is to add a ThreadExceptionEventHandler around your animation block when toasting. This is the easiest fix for the problem, so I'll throw it out and hopefully unblock some people that might have wanted to use the toasting code but couldn't.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Threading;
public class AnimateWindowShow : Form {
[DllImport("user32.dll")]
static extern bool AnimateWindow(IntPtr hwnd, uint dwTime, uint dwFlags);
public AnimateWindowShow() {
Label lbl = new Label();
lbl.Dock = DockStyle.Fill;
this.Controls.Add(lbl);
ShowInTaskbar = false;
lbl.Click += new EventHandler(Form_Click);
Click += new EventHandler(Form_Click);
}
private void Form_Click(object sender, EventArgs e) {
GraphicsPath gp = new GraphicsPath(); gp.AddEllipse(ClientRectangle);
this.Region = new Region(gp);
Application.ThreadException += new ThreadExceptionEventHandler(this.Handle_Exceptions);
AnimateWindow(this.Handle, (uint) 1000, (uint) 0x90000);
DateTime end = DateTime.Now.AddSeconds(3);
while(end > DateTime.Now) { System.Threading.Thread.Sleep(0); }
AnimateWindow(this.Handle, (uint) 1000, (uint) 0x80000);
Application.ThreadException -= new ThreadExceptionEventHandler(this.Handle_Exceptions);
}
private void Handle_Exceptions(object sender, ThreadExceptionEventArgs e) {
}
[STAThread]
private static void Main(string[] args) {
Application.Run(new AnimateWindowShow());
}
}
Enjoy, and play with the values for AnimateWindow styles. You can achieve a number of effects. Remember that the event happens asynchronously so if you are hoping to animate the hiding of a window then you have to wait until the animation is done before you dispose of it. I'll show you how to do this another time.
Well, I figured I'd throw my presentation decks up in a zip format so that people could download those without having to view the entire web-cast. I'm not sure if just the decks are available over the MSDN website, and since I couldn't find the link, I assume others might have some trouble. If anyone knows how to get a transcripted version of the web-casts or links to the slide-decks on a network that doesn't cost me money, then let me know so I could change the links ;-)
Developing a Poker Game in C# Express 2005.zip 297KB
Developing an RTC Application in C# Express 2005.zip 3.4MB
The RTC demo contains some whiteboard pictures and for some odd reason I couldn't get the pictures to compress very well. Saving them as JPEG files gives them a really bad dithering effect, so I've been resorting to TIFF since that gives me the best visuals. Realizing the whiteboard stuff is only black and white should mean that a black and white scale gif should work well, but I've had poor luck with GIF file formats as well. Anyway, becoming a master at file compression techniques using a disparate collection of tools isn't in my list of things to do, but if I get the chance to write some software for the process maybe I'll look at providing a better format for the images later.
Anyway, for those waiting on some source code for the RTC webcast, shortly, and for the Solitaire sample, also shortly. I wound up doing some extra work on the book to provide some heavily enhanced samples. For those wondering, check out the hand-drawn deck and how well it is coming together. The artist is done with these and we'll be using them as is, along with some compositing features to produce the final embossed card.


Okay, so I was checking out the VB PowerToys, and I have to say they are kind of nice. I can always appreciate a free download especially if it saves me some time. However, you don't reinvent the wheel when creating a new component and then append the word Power to it. The VB Power Toys are relying on a partial combination of Windows Forms, Windows Forms hacks, and P/Invoke calls, but even with a license to use such features they only use them in a half-arsed manner.
Currently, for the animation, the developer uses ShowWindow in order to get around the activation issues with Windows Forms, but then turns around and uses custom animation routines. Custom animation routines when working with Forms really suck because they involve a LOT of screen popping as you continuously redraw the form contents. This is not bad if you animate an empty window, called a representative, and then show the actual form with controls at the end. This reduces repainting, so at the very least I would recommend the Power Toys use this method.
Otherwise, take advantage of the system darnit. AnimateWindow, a well documented Win32 API, is capable of doing all of the animation available in the NotificationWindow with a minimum of code. I applaud some of the cool designer features for blends and what not, but not taking advantage of a built-in, and very fast API for animating the window (much faster than custom animation) is just not cool. Anyway, if you want your own “Toast” windows without all of the extra garbage all you really need to do is make a call to AnimateWindow over top of your normal forms. A sample Form that hides then shows using a fade, as well as taking advantage of a Region while doing it, can be found in the following snip:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class AnimateWindowShow : Form {
[DllImport("user32.dll")]
static extern bool AnimateWindow(IntPtr hwnd, uint dwTime, uint dwFlags);
public AnimateWindowShow() {
ShowInTaskbar = false;
Click += new EventHandler(Form_Click);
}
private void Form_Click(object sender, EventArgs e) {
GraphicsPath gp = new GraphicsPath(); gp.AddEllipse(ClientRectangle);
this.Region = new Region(gp);
AnimateWindow(this.Handle, (uint) 1000, (uint) 0x90000);
DateTime end = DateTime.Now.AddSeconds(3);
while(end > DateTime.Now) { System.Threading.Thread.Sleep(0); }
AnimateWindow(this.Handle, (uint) 1000, (uint) 0x80000);
}
[STAThread]
private static void Main(string[] args) {
Application.Run(new AnimateWindowShow());
}
}
The above isn't complete at all, and isn't meant to be. The point is you don't need a PowerToy for most of this stuff because the functionality is one API call away and not 50+ lines of animation code. In addition to the Show methods in the PowerToy, AnimateWindow actually has many additional settings. Not to mention it handles the whole activation logic with a simple flag that gets Or'ed in with the rest of the flags. Slide, Blend, Roll, swipes from center, horiztonally or vertically. It is a cool API and won't put a large hurting on your system.
Even better is the SystemParametersInfo where you can get information on whether users even have animations enabled by default. By doing some checks with this method you can get loads of information on tuning your UI to make sure it works best with the user's system.
Don't get me wrong, some of the PowerToys are excellent and cool. Just be aware of what you are getting and the alternatives. Maybe the developer didn't know about the AnimateWindow API, or possibly there were some issues I'm overlooking. I'll be interested in hearing about it. There are some notes on the API about when certain flags are supported, but it returns a bool true/false and lets you know if it succeeds, so you can check that and return appropriate error information.
I just checked my email for the first time today at 1:30 am (technically Tuesday I guess) and saw an email subject with a possible name for my book. At least the subject line appears to be what everyone else is calling it, even if I didn't know much about it ;-) What a pleasant surprise I have to say, since the book title suits me perfectly. I tend to program best between the hours of midnight and 6am, so that is definitely after hours for most people. I also think each of the samples tends to reflect the mindset that you would develop these at home, after you've come home from work.
Work after work? Nah, this isn't work, all of the samples are great fun more than work. Games, blogging tools, messaging applications, and the sort. No work here my friend. The name also works well for people that have something other than programming as their day jobs. The book doesn't have to be read by a programmer, and I hope my largest audience is that of the non-programmer. I think just about anyone interested in computers will be able to get a great deal of information from the whiteboard diagrams that I've developed and much of the information provided throughout the chapters is informational and would apply irregardless of whether or not you were programming. For instance, a major application in the book is a download manager. Throughout the chapter I cover the use of the new FTP classes, show you how and why resumed downloads over HTTP 1.1 are cool, and then demonstrate a multi-chunk asynchronous download. Even if you don't program, you'll want to go out and get the application so you can use it at home, or find another download manager on the Internet that suits your needs.
You see, the book is for everyone, and after hours is when you'll want to read it. I suspect some users may find it a great reference material since there are ten different types of applications developed with a full project framework from which to start a much larger application project. Each of those projects fully stands on it's own though and is a fully usable application that you might pay $25 for on the web somewhere. That is why I like the book so much, I'm finally able to provide the level of quality in code, applications, information, and design that I'm actually happy with. There aren't any corners cut, and I'll continue to support the book long after it's release. It's just a great project for me, everyone involved, and hopefully there will be thousands of very pleased readers.
BlogShares is a project that I'd love to tackle in switching over to an ASP .NET site. They are racked constantly with visitors, they have some fairly detailed view screens, they are constantly aggregating and changing data, and constantly pulling from a large listing of RSS feeds. Recently they've added some graphs that look better and they've been adding some new game rules and such. The site is a behemoth of possible performance improvements and features.
Looking at their graphs, they probably haven't seen Dundas Charts or any of the really nice graph facilities available to .NET programmers. I hate to say it, but if our graphs went to the same school as their graphs, we'd definitely tease them in the lunch room. I'm thinking performance must be a really large goal for the charting, but I wouldn't foresee any problems making both high quality, high performance charts.
Anyway, if you haven't checked out BlogShares, you shold go check it out. A kind of fantasy stock market in blogs. I've been a member for a while, but all I do is insider trade with my own blog as time permits.
It'll still be another few days off, since I want to integrate some decent graphics into the application, but Solitaire .NET will be the first game launched on G4... It has been a long time in the coming, and I finally said the hell with it and we are going live with reference graphics rather than the actual planned graphics. Too many people are interested in the site to let it sit around and collect dust.
Some of the first features will include a bunch of Terrarium work with the exception of anything that relies on the net yet publicly released source code, all of the descriptions and some samples for my Whidbey book, probably an entire book on game programming in .NET that I never published out of shear distaste for my own content (something I”ll have to get over in the future), and quite a bit more. The Solitaire and cards samples will be the first to roll off and the site will focus on game playability and fun features rather than games that rely entirely on AV content alone. Don't get me wrong, a beautiful game is a beautiful thing, but I'm sure tire of paying $50 bucks for a coaster when I could spend $10 for an indie game that I'll get my money's worth from.
Anyway, stay tuned and drop any comments on the terrible reference graphics that are currently up on the site.
If you've followed my recent web-casts you'll see that the samples and demos are in C# Express. Now, for those that know me long term, I'm a notepad warrior and there is nothing stopping it. You can take the Developer out of the Notepad but you can't take the Notepad out of the Developer. Some notepad exploits for good measure include a very large percentage of the .NET V1 QuickStart Tutorials Samples, all of the internal testing infrastructure for those samples, all of those little helper controls like the source viewer, a good portion of the ASP .NET V1 Forums system, quite a few interesting sections on both asp.net and windowsforms.net. So why in the hell would I stop writing in notepad?
I'll start by saying why I write in notepad (or rather I'm generalizing I tend to use TextPad). I write best in lime and green irregardless of whether or not I have contextual syntax highlighting available. Just can't get around that. I will say working on the laptop with the soft LCD screen has improved my usage of other color schemes. Text editors come up fast, save fast, go away fast, search fast. Everything is fast! They easily launch from the command line and don't take half an hour. Batch files are project systems to you know, and I can write a batch file faster than I can navigate most of the build options menus. So I like the command line as well. I type about 120 words per minute on a good day. Now I will say that I can't sustain that rate for very long, but thankfully development is a series of burps and hickups of code between intense design thought. Text editors let me pump out the extremely large number of code lines that I've grown used to, and visual editors such as the previous VS tend to slow my process down.
Now, C# Express might just replace this entire thought pattern for me. The Intellisense is actually useful, the refactoring is actually useful, the designer is actually useful. I timed myself doing some common tasks and in some cases I kick my own text editor ass when using C# Express. Most of this comes down to the R&I's (refactoring and intellisense), and their ability to aid in typing well named classes, enumerations, and methods that would otherwise be a chore. They truly enable event programming with two tabs after the += automatically generating a hook-up and stubbed out method for you. The same goes for overriding base methods, they autogenerate the stuff for you.
The ability to regionalize code and use various expansions is alright. I will say that the 20 or so code snippets I've added to my expansions list is much more useful than the default ones, to the point that I've deleted all of the default expansions from my snips list and added my own so I can access them more quickly. I hope snippets becomes parts of a project, rather than the environment you are working in so you can ship them around easier (hint Dan ;-). Something like the Terrarium could ship a base project with 30 or so expansions for common tasks that would really enable users.
That means a big Yes! for me on this tool. I'm finally use something other than a text-editor for development of select applications. All of my testing is still going to be done at the command line for sure and I'd love to see some real developer tools added to the IDE in terms of showing me the IL for particular methods, etc.. These are the things I use the command line for and integrate into a text editor, that still don't work in C# Express. That is fine, you should never use just one tool. Dan said something in his web-cast about this product marketing in the tens of dollars. Now that sounds pretty nice. I've recently contacted a number of friends and the metric I seem to get is $25 bucks or less being a great price. Common developer outlets ship full versions of Visual C# 2003 for less than 50 bucks at times, so you really have to price a light version of the product below these metrics. Anyway, go check out Dan's web-cast, he did a really great job showing of VC# Express features. One thing to note is that he fades out at times so have your speakers kind of loud. The entire talk is in the designer, and he focuses on the data features quite a bit. I'd really love to do something collaborative with Dan on this, because I've actually used the data designer features for some pretty neat applications and I think seeing the power of generating a full application using the data features would make for a great web-cast.
Visual C# Express 2005 Series 1 of 3: Introduction - http://go.microsoft.com/fwlink/?LinkId=31151
I hate dropping source code directly into a blog posting, but what the hell, it isn't very long at all.
CardManager<StandardCard> cardMan = new CardManager<StandardCard>();
deck = cardMan.AddHand( "Deck", StandardCard.StandardDeck );
// Set up Discard Pile
btnView.Tag = discard = cardMan.AddHand( "Discard", null );
tierTags[0].hideHand = cardMan.AddHand( "Tier1Hide", null );
tierTags[1].hideHand = cardMan.AddHand( "Tier2Hide", null );
tierTags[2].hideHand = cardMan.AddHand( "Tier3Hide", null );
tierTags[3].hideHand = cardMan.AddHand( "Tier4Hide", null );
tierTags[4].hideHand = cardMan.AddHand( "Tier5Hide", null );
tierTags[5].hideHand = cardMan.AddHand( "Tier6Hide", null );
tierTags[6].hideHand = cardMan.AddHand( "Tier7Hide", null );
// Set up View Tiers
tierTags[0].viewHand = cardMan.AddHand( "Tier1View", null );
tierTags[1].viewHand = cardMan.AddHand( "Tier2View", null );
tierTags[2].viewHand = cardMan.AddHand( "Tier3View", null );
tierTags[3].viewHand = cardMan.AddHand( "Tier4View", null );
tierTags[4].viewHand = cardMan.AddHand( "Tier5View", null );
tierTags[5].viewHand = cardMan.AddHand( "Tier6View", null );
tierTags[6].viewHand = cardMan.AddHand( "Tier7View", null );
btnFinish1.Tag = finishHands[0] = cardMan.AddHand( "Finish1", null );
btnFinish2.Tag = finishHands[1] = cardMan.AddHand( "Finish2", null );
btnFinish3.Tag = finishHands[2] = cardMan.AddHand( "Finish3", null );
btnFinish4.Tag = finishHands[3] = cardMan.AddHand( "Finish4", null );
deck.Shuffle();
deck.DealTo( tierTags[0].hideHand, 1 );
deck.DealTo( tierTags[1].hideHand, 2 );
deck.DealTo( tierTags[2].hideHand, 3 );
deck.DealTo( tierTags[3].hideHand, 4 );
deck.DealTo( tierTags[4].hideHand, 5 );
deck.DealTo( tierTags[5].hideHand, 6 );
deck.DealTo( tierTags[6].hideHand, 7 );
deck.DealTo( discard, 1 );
You'll notice Solitaire is reduced to a bunch of hands quite easily. I added 7 extra hands to hold my *hidden* cards on the tiers, and this means less state that my game engine has to keep. Whenever I update the UI, I make sure the I either have at least one View card available, else I grab one off the Hide stack and if none are available I mark the spot empty. Super, super easy. So with all of the UI and everything, how many lines of code does Solitaire weight in at? About 250 in the partial class definition where all of my code went.
I'll try to release this as another sample this weekend if I get the time between pounding out a couple more chapters of my book.
I'm completely third party with respect to the Terrarium. Yes I still help with the evangelism and coding of the application itself, but on a very limited role as the product goes towards maturity and new product ideas develop for future versions. That said, there are many things I can't talk about in regards to the application because I know about future features that I'm under NDA for, but there are equally many things on a conceptual level that I can talk about. That brings me to the Terrarium as a learning game. When I first started working on the Terrarium the concepts for the game were simple.
- Thoroughly test the .NET Framework from top to bottom in what I would call the ONLY enterprise sample. We tested the server, client, client/server interoperation, platform invocation, every level of security, and so many features it would make your head spin. Now it seems like not that much, but when we released, the .NET Terrarium was the most stressful application anyone had ever developed. In saying that, we still found issues as late as V1.1 that were only being exercised by the Terrarium and no other application in existence (unless they were quiet about it).
- Get a shitload of people running the application. That meant making a pretty screen saver that people could run and would want to run. Unfortunately technical requirements were that it run on a laptop with 2.5 megs of video memory. Come on, we got pretty damn cool for such small memory requirements. We never did whack the aquarium that shipped with the XP Plus! Pack, but we sure did get a lot of people running anyway.
- Educate users on the process of programming .NET applications and get them writing small samples in a friendly environment. The basic creature was only 15 or so lines of easily explained code, while the upper limits of coding the AI are still being established today. That is a pretty nicely designed learning infrastructure.
As far as I'm concerned those were the main goals and we accomplished all of them. We had a huge university outreach program that kind of fizzled out, but at least one group of students got a very interesting experience with the application. The technical outreach at various conferences was unparalleled with hundreds and hundreds of users playing and submitting creatures at each conference the Terrarium was used as a lab exercise program.
Now, that said, the Terrarium focuses on great features of the .NET Framework, but is is a partial game. It doesn't meet the requirements I have for a game engine, and for good reason, we simply didn't have the time or resources to make something of that magnitude when our primary goals were something entirely different (see goals 1 through 3 none of which cover making a demonstrable game engine). Moving forward some very big decisions have to be made. Based on some recent postings by Mitch, it appears he has ideas of going a mech warrior route. In my mind, I'm more focused on enabling the learning experience of getting up to speed on AI and .NET programming in general. You can start to see where the two sides of the equation diverge with different end goals being established. This isn't a bad thing and I'll describe why.
First and foremost the Terrarium is going to be a community project very soon. That means releasing some very nice community enhancements. From my standpoint this means releasing source code that I've had under my belt for almost two years now waiting for the source release to happen so I could push some changes that were never approved in the official release. It also means that the community goals can be easily resolved with some simple code-fixes. Users tend to say quite a few things but they boil down to the following items:
- The rules are inconsistent, don't work very well, or what boils down to not enough rules.
- Users have a hard time getting the Terrarium up and running for the first time.
- There is no publicly available mechanism for real competition.
For the first, there is some nice code available that allows a server module to change the basic engine settings dynamically. This can be used to simulate weather and a number of other unique conditions. The next step is increasing the variety of creatures without increasing the complexity, again, the code is ready to go for this feature as well. The second feature relies on things like TerrariumProxy or TerrariumIM in order to work properly. Both of these features will allow users to play without worrying about the NAT problems that are traditionally encountered by so many of the users.
For the third feature the TerrariumClusterServer will be made available. This last one I haven't talked about at all, but it basically allows a single machine to simulate any number of Terrariums and allows competitions to be run using a pluggable ranking system. Now, rather than using multiple trusted machines for a competition, we can have a single server located on the Internet capable of running competitions and determining the best users. After all, with the source release the public EcoSystem will be able to be taken advantage of quite easily and the threshold for overcoming an established population is very huge. The new feature set will rely on simulating trials between creatures and collecting statistics about the winner over a period of time. All creatures are inserted on an equal basis and pitted against one another. To avoid any cross-idea issues I will say that this feature set is based around spawning 10 or more concurrent Terrarium engines on the same box, hijacking the network, reporting and peer registration layers, and finally running all engines concurrently. There are no rule changes or other concepts that might create an intellectual property issue.
That means, what do I think of Boris as mentioned on Mitch's blog? Well, I think it is a very niche market. I think the community needs to reach out to those players that haven't joined up yet. I know the nerds, geeks, dweebs, dorks, and other misfits have already tried the game and love it, and these same people would dig the mechs, but I think the direction the game needs to head is a more general adoption. For me that means concentrating on things that interest children, teenagers, college students, and technical individuals. I think bringing the female gaming markets and child gaming markets into the fray is important. What kinds of features am I looking for?
- Everyone can play and be somewhat successful. That means even without a large amount of programming experience you should be able to make an effective creature. This feature works based on a creature designer that creates a creature with fairly decent survival statistics. I guess as the developer of this type of feature I'll have to keep up with all the rest of the programmers so that automatically generated creatures are only slightly worse than the best creatures in the environment.
- Everyone is interested in watching the game play out. Mechs aren't the coolest thing ever. They are pretty cool, I'll admit, but the classics of bugs and animals are much cooler. Children are especially interested in bugs and animals, as is the female gaming crowd (moreso animals than bugs at this stage). Guys that watch mechs, also watch vicious animal attacks, so I don't think any of the action will be missing here ;-)
- Code protection is a must and individuals that want to be competitive at the code level are able to safely release their creatures and battle them without worrying about having their code ripped off. I want to foster some of the best programmers to play the game and if intellectual property is at stake these best of the best simply won't play.
- Provide a challenge for good programmers. The base designed creatures will be good enough to provide a challenge, but so will the variety of coding a creature. Every niche of the scale will provide areas where people can play. The imbalance of the current game towards small, quickly reproducing creatures is nothing short of atrocious.
- Keep it on the P2P layer, get rid of the server, and call it a day. I think the ability to play the game cheaply is a must and running a Terrarium server can be a large expense. Focusing on this particular layer will be a must for any real adoption level. After all, the Terrarium server breaks down at 2500 users or so, we can theoretically hold 10000, and that is only if an admin is tweaking things every few days. Going beyond 10000 or even supporting 10000 currently requires a large operating budget.
This is by no means a complaint about how the current Terrarium is being run. I get insights into the direction of the game and I love where it is going as an application, but I can certainly disagree on design issues and other such nonsense. At this stage that is all I'm doing is disagreeing at some design level, and it may turn out that the insights I'm basing my opinion on are changed at a later date. Most of the above comes from my long term attachment to a project that I've been extremely close to, and I'm still extremely protective of.
|
Jason Olson has some comments about the Poker Deck I developed and I am starting to agree with some of them. Not that the integrated Hand is bad, but more that the integrated Hand is not tightly integrated enough to be sufficiently useful. So what am I going to do about it? Well, I'm going to fix it darnit. Or better, yet not fix it quite yet, but explain the names a bit better. I'll start by taking a few sample definitions with respect to where cards are located in several games.
- Poker
- Initial Deck - 52 Cards - Cards are dealt with one hand per player
- Hands - 5 Cards at a time in general - Cards can be discarded and new cards retrieved.
- Discard Pile - A pile where all dealt cards that get discarded go, and after the Initial Deck is finished, Cards can be reshuffled into the Initial Deck
- Solitaire
- Initial Deck - 52 - ((7*8)/2) - or basically 52 - 28 where 28 is the initial set of cards in the 7 tiers
- 7 Tiers - This is where the game is played
- Top of Deck - 1 Card that you can see, maybe three, depending on how the settings are laid out
- Discard Pile - Cards that have been moved from the playable hand back to the pile.
- 4 Suit Stacks - Where you place all of the cards that will win you the game.
- Magic the Gathering
- Two Initial Decks - Ouch, does our deck fail at this point? Kind of, but I'll fix that.
- 1 Hand per player
- 1 Discard pile per player
- Many Board Locations for placing cards
Now, all we need to do is define the appropriate definitions and everything works. What is a Deck? Well a deck is the initial set of cards. It is the source of cards. A deck in Poker is 52 cards, Solitaire, the same deck. What about Magic the Gathering? Well, the deck is the same, but it is comprised of cards from two players, so you logically have two decks, but from an abstract standpoint the deck is the set of all other decks. Using some set theory here isn't but so bad eh ;-)
What is a Hand? Well, a hand is a pile of cards. A hand holds onto cards, but it doesn't own them. That is the job of the deck. The deck controls the entire process of making sure all cards are properly initialized and then placed in their initial spots. The current Deck does this well, but there is some work left. Just as the Card definition is meant to be overriden and slightly changed, so is the Deck. With that in mind I'll be releasing a new Deck that offers a number of extra features and is consistent with this new model I've defined. The new process would be defined as follows:
Deck<StandardCard> deck = Deck<StandardCard>.CreateDeck( new HandInfo[] { new HandInfo(“Initial Deck“, 0, StandardCard.StandardDeck), new HandInfo(“Hands“, 0, null), new HandInfo(“Hands“, 1, null), new HandInfo(“Hands“, 2, null), new HandInfo(“Hands“, 3, null), new HandInfo(“Discard“, 0, null) } );
What does the above do? Well, it creates a deck of cards with several named hands. One of the hands is the InitialDeck and it contains a set of StandardDeck cards. You can pass in more decks if you need to. The Hands are a single collection of hands, each indexed by a different number 0 through 3. Finally there is a Discard pile. All of the commands on Deck now manage the passage of items between hands. Remember, a Deck should be contained within an Engine, so that the user never has direct access to the Deck. The Deck still has the basics of internal protection, but it is truly protected by the Engine itself.
deck.Shuffle(“Initial Deck“, 0); // That'll handle your shuffling deck.Deal(“InitialDeck“, 0, “Hands“, 0, 5); // Deal 5 cards to the first hand deck.Deal(“InitialDeck“, 0, “Hands“, 1, 5); // Deal 5 cards to the second hand deck.Transfer(”Hands”, 0, “Discard”, 0, 3); // Transfer card 3 from Hands 0 to Discard pile
I think just about everything is possible with this feature set and the deck is a bit cleaner. It can still protect it's children and hold their hands (terrible association). The diagram shows the process in action and is described as follows:
-
Deck is the init class. Everything happens through Deck.
-
Hands is an indexed property that is indexed by Name or by Name, Offset combo. By Name defaults to the 0th hand of that name or the default hand.
-
Named Hand is a collection of the various hands. Sometimes this will be a list of length 1, other times it will be a larger list.
-
Offset 0 is the default hand
-
Offset 1-N are the N additional offset hands in the named hand.
I am hoping this makes logical sense to everyone. I can easily show some games, including Solitaire and Poker being played using this new deck and rules.
|
|
More Posts
Next page »