Thursday, 24 November 2011

Java: Texas Hold Em (9)

Happy Thanksgiving to all the Yanks in the audience. Today we're moving onto the evaluation part of the program. This one's a little big, so it'll be more than 1 post dedicated to it! To keep things concise (or at the very least, available in small chunks), I'll keep posts to 2 screenshots worth of code per day, as I've been more or less doing for a while, anyway.

Fixing things in previous posts won't count, unless its a ridiculous amount! Speaking of which...
I knew there was something off about Mr. Stigter's ranks for hand values, but couldn't quite put my finger on it. Looking back on old code, I realized! There's no need for a rank variable! Maybe there is for his particular program, but I don't see the need, at least not at this time. Remember our cards? We used the ordinal() method to get the ordered values of ranks and suits?

I figure we should do the same here. To get the ordinal dealy to work right, though, we need to reverse the order in which the hand values are placed in the enumeration, as it is currently, a Royal Flush being first gives it an ordinal value of 0, when it should be the highest. Behold: My "fix" (wasn't technically broken, after all):

Bam, even managed to get it squeezed into 1 shot. It's not very pretty code, I know. The comments are icky, and, as with everything I do (Because I am a bad coder, do as I say not as I do!), I don't document the methods themselves. Bad practice. Bad.

But anyway, you can see that all I did was reverse the order the hand value types appear, so High Card now has an ordinal value of 0, and Royal Flush has a 9. I've removed the value variable, and changed the getValue() method on line 25 to reflect that I'm using the ordinal position!

Phew, now we can get started on the actual HandEvaluator class. There's a hell of a lot going on in the pre-constructor part, where all the class variables are. A few of them I see in Stigter's code, I don't actually know why they're there, but I'll trust him for now, and change it later! Mostly because they look less like programming dealies that I don't get, and more like poker dealies I don't get:

Hoo-boy. This'll be the first class that will HAVE to be completely different to Stigter's, mostly because our Card classes also are, and such, but for now, I'll keep what he has, let's go through it.

Line 6: Uh...the number of hand rankings. This is one of the things I don't get. There's 4 suits, so it isn't that, it's got nothing to do with players, and there's 10 hand value types. Brief looking into the code reveals nothing to me! We'll see later, it's always easier to understand as you do than as you read.
Line 7: This just holds the max number of pairs a hand can have, so we can make an array later. 5 cards means 3 pairs can't be done, you see. We could just use the integer later when making the array, but this looks prettier.
Line 9: WHAT IS THIS? THIS ISN'T CODE, THIS IS SOME WHACKED OUT SCORING SYSTEM I DON'T EVEN KNOW WHY YOU WOULD NEED THIS. It actually looks like Stigter is calculating the hand's value in a farm more complex way later on. I will probably remove this, don't grow attached to it. But maybe this way is better?
Lines 11-12: Aah, simpler territory, I can handle this. A variable to hold whether the hand is a royal flush or just a pair, and a value variable to hold the actual final score of the hand.
Lines 13-17: The cards from the hand, to evaluate, then, an array to hold the rank distribution. It occurs to me I screenshot this before I was actually done with the code. The array should only be 13 long, not 52. I don't fully get why we need this, but its got a name like Rank Distribution, so I assume its all about the poker scoring, so it stays. Same with the next one, an array to represent the distribution of suits.
Lines 19-21: Back to readily understandable stuff. We have an int declaring how many pairs are actually in the hand as well as an array to hold as many pairs as possible (2). This'll make it easy to check which pairs win out in the event of 2 players getting pairs of some variant.
Lines 22-24: More in-case-of-draw variables. Something to hold what rank and suit flushes are, and something to hold the high card of a straight. Suit doesn't matter for forming a straight, so there's no way to properly use it as a tie-breaker.
Line 26: Ooh, I actually know this one! You can use an Ace in place of a 1 for a low straight (5-Ace only), so naturally we'll need a boolean to make sure that this straight doesn't outperform a higher one due to having an Ace in it.

Okay, so I cheated a little with the second screenshot, but that's 'cause what comes after is the constructor, and that's too big to fit in here! Also, holy fuck this is long already, nobody's going to read this shit as is. Bet you didn't even make it this far.
Lines 28-32: Self explanatory! As in the comments. 2 variables to hold the ranks of different hand value types, and then an array to hold each component of the hand values.

That is....more than enough. For a while. But I'll still be back tomorrow, see if I can make these shorter while still being able to learn some amount.

Questions/comments welcome etc, see you tomorrow!


  1. Woah, I like how nice and concise everything is, it makes it a lot easier to follow along.

  2. Very interesting post.

  3. Looking good. Impressive that you were able to pick out things like that to improve efficiency and make the code more clean. I wouldn't have caught on. :P

  4. thanks for the detailed explanations, I will appreciate it when I follow it step by step.