µObjects: Temporally Coupled Decisions into Chain of Responsibility

µ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.

Requirements:
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."
  • Flush
    • 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.
  • Straight
    • 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.

Video Edited

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.

Code

THe code is available in my MicroPlayingCards repo with the final commit of this video being here.

Show Comments