µObjects: By Example - Playing Cards
I've been a bit remiss on good code examples for µObjects. I've been planning a few things; never got them done. Almost entirely because I'm lazy. So...
I'm going to try a simple example of the application of µObjects.
Playing cards. I was gonna do Magic: The Gathering (M:TG) cards; but they're a bit complex for an initial go. And not sure everyone will be as familiar witih M:TG. A co-worker is trying to get a better understanding of the µObject idea using M:TG cards as a base. It's one I'd like ot tackle. It presents a lot of places to implement things multiple ways; showing one of the strengths of µObjects; You can cleanly do things a number of ways. Though... please pick just one for your code base. :)
I'm going to code this up and write it up at the same time as I have a lot of other coding posts. This will make it a bit more "real time" and I can demonstrate the process much better.
My goal is scoring a single hand of poker. I've done a black jack scoring engine before; but I want to throw a little more umph into the final product of this.
Scoring a 5 card Poker Hands Ranked from Highest to Lowest:
- Royal Flush
- A straight from a ten to an ace with all five cards of the same suit. In poker all suits are ranked equally.
- Straight Flush
- Any straight with all five cards of the same suit.
- Four of a Kind
- Any four cards of the same rank. If two players share the same Four of a Kind (on the board), the bigger fifth card (the "kicker") decides who wins the pot.
- Full House
- Any three cards of the same rank together with any two cards of the same rank. Our example shows "Aces full of Kings" and it is a bigger full house than "Kings full of Aces."
- Any five cards of the same suit (not consecutive). The highest card of the five determines the rank of the flush. Our example shows an Ace-high flush, which is the highest possible.
- Any five consecutive cards of different suits. Aces can count as either a high or a low card. Our example shows a five-high straight, which is the lowest possible straight.
- Three of a Kind
- Any three cards of the same rank. Our example shows three-of-a-kind Aces, with a King and a Queen as side cards - the best possible three of a kind.
- Two Pair
- Any two cards of the same rank together with another two cards of the same rank. Our example shows the best possible two-pair, Aces and Kings. The highest pair of the two determines the rank of the two-pair.
- One Pair
- Any two cards of the same rank. Our example shows the best possible one-pair hand.
- High Card
- Any hand not in the above-mentioned hands. Our example shows the best possible high-card hand.
While traditional Poker doesn't rank suits, I think it adds a bit of complexity to the problem; so the suits will be ranked: Spades > Heart > Diamonds > Clubs.
That's my main feature. Compare hands. The simplest of these hands is High Card. Which is a card comparrison. I'll start with implementing just a card comparrison.
That's a pretty good initial objective.
I don't expect to get all the way to scoring hands; but being able to compare two cards is some solid value add to what I'm working towards.
Initial Recording Finished
I didn't get around to typing while recording. I talked a lot though; aren't you lucky.
What I've done in this first recording is using TDD to create the Card Comparison pieces. It's not a huge amount. I spent about 4 hours going through and getting it to this point. Probably could have gone faster if I shifted a few things. I had a few wrong paths that took some time.
Mistakes are there to learn from. I actually found a problem when applying a pattern in certain situations. The Decorator patter isn't the simple solution when you'll need to compare values that can be decorating. Slight spolier - The Suit is not a good decorator.
I don't want to get this up until I have the video edited. I'd really like to wait until I have it all the way through scoring; then just list the video's as resources.
I'll see where this gets to.
I've gotten the video edited and uploaded to YouTube.
I haven't gotten a transcript. I did all the coding and talking while coding on the fly.
I've sped up the beginning and end of the video quite a bit. It's not terribly interesting parts.
The core of the video is breaking down a temporally coupled procedural method into µObjects.
My original dialog is largely left in, minus some editing; like the phonecall I forgot to hit "stop" for... oops.
This video; while I didn't really have plans for what it would be; is an example of Temporally Coupled Decision Making into Chain of Responsibility.
A lot like Woody Zuill says, "You'll find the work that needs doing by doing the work." In this case, I found the purpose of the video by making the video. :)
Video Editing ... for phun
I've found video editing isn't really my thing. I used Adobe Premiere; I tried a few... and it's the one that seemed to work the best for me. A couple others I tried used about 4x the memory. The video was 4 hours total; and a few of the tools didn't do so well with that.
Premiere only hiccuped a couple times. I suspect I'll do month-to-month subscription to complete this video project. By which I mean I'll pay for a month to do a few days of editing. Cancel... and repeat each time I do a video. :)
I don't hate it as much as I did just starting the editing. I think this will be some good practice for me on how to present information; especially in a video format.
THe code is available in my MicroPlayingCards repo with the final commit of this video being here.