views:

196

answers:

1

Is there a regex to calculate straight poker hand?

I'm using strings to represent the sorted cards, like:

AAAAK#sssss = 4 aces and a king, all of spades.
A2345#ddddd = straight flush, all of diamonds.

In Java, I'm using these regexes:

regexPair = Pattern.compile(".*(\\w)\\1.*#.*");
regexTwoPair = Pattern.compile(".*(\\w)\\1.*(\\w)\\2.*#.*");
regexThree = Pattern.compile(".*(\\w)\\1\\1.*#.*");
regexFour = Pattern.compile(".*(\\w)\\1{3}.*#.*");
regexFullHouse = Pattern.compile("((\\w)\\2\\2(\\w)\\3|(\\w)\\4(\\w)\\5\\5)#.*");
regexFlush = Pattern.compile(".*#(\\w)\\1{4}");

How to calculate straight (sequences) values with regex?

EDIT

I open another question to solve the same problem, but using ascii value of char, to regex be short. Details here.

Thanks!

+4  A: 

I have to admit that regular expressions are not the first tool I would have thought of for doing this. I can pretty much guarantee that any RE capable of doing that to an unsorted hand is going to be far more hideous and far less readable than the equivalent procedural code.

Assuming the cards are sorted by face value (and they seem to be otherwise your listed regexes wouldn't work either), and you must use a regex, you could use a construct like

2345A|23456|34567|...|9TJQK|TJQKA

to detect the face value part of the hand.

In fact, from what I gather here of the "standard" hands, the following should be checked in order of decreasing priority:

Royal/straight flush: "(2345A|23456|34567|...|9TJQK|TJQKA)#(\\w)\\1{4}"
Four of a kind:       ".*(\\w)\\1{3}.*#.*"
Full house:           "((\\w)\\2\\2(\\w)\\3|(\\w)\\4(\\w)\\5\\5)#.*"
Flush:                ".*#(\\w)\\1{4}"
Straight:             "(2345A|23456|34567|...|9TJQK|TJQKA)#.*"
Three of a kind:      ".*(\\w)\\1\\1.*#.*"
Two pair:             ".*(\\w)\\1.*(\\w)\\2.*#.*"
One pair:             ".*(\\w)\\1.*#.*"
High card:            (none)

Basically, those are the same as yours except I've added the royal/straight flush and the straight. Provided you check them in order, you should get the best score from the hand. There's no regex for the high card since, at that point, it's the only score you can have.

I also changes the steel wheel (wrap-around) straights from A2345 to 2345A since they'll be sorted that way.

paxdiablo
Agreed. Run the regexes above, and then run procedural code to check for straights. That should be pretty straightforward - step through the string and make sure they're sequential.
cincodenada
@cincodenada: yes, that's how I'd do it. But sometimes, OPs have a good reason for doing it a specific way (e.g., they may be using a tool/framework that can only use regexes). So, while I'll suggest there may be a better way, I'll still try to help them out. I didn't gel to the idea at first but I can see it would make their source code small and elegant :-)
paxdiablo
@paxdiablo True, which is why I commented on your answer and didn't make my own. But a good reminder to give the OP the benefit of the doubt regardless. Thanks :)
cincodenada
@paxdiablo Thanks a lot! Great ideas!
Topera