Range parsing¶
The poker.hand.Range
class parses human readable (text) ranges like "22+ 54s 76s 98s AQo+"
to a set of Hands and
hand Combos.
"22+ AQo+ 33 AKo"
–> "22+ AQo+"
Defining ranges¶
Atomic signs
X means “any card” A K Q J T 9 8 7 6 5 4 3 2 Ace, King, Queen, Jack, Ten, 9, …, deuce “s” or “o” after hands like AKo or 76s suited and offsuit. Pairs have no suit ( ''
)- hands worse, down to deuces + hands better, up to pairs
Available formats for defining ranges:
Format Parsed range 22 one pair 44+ all pairs better than 33 66- all pairs worse than 77 55-33 55, 44, 33
None of these below select pairs (for unambiguity):
AKo, J9o offsuit hands AKs, 72s suited hands AJo+ Q8o+ offsuit hands above this: AJo, AQo, AKo Q8o, Q9o, QTo, QJo AJs+ same as offsuit 76s+ this is valid, although “+” is not neccessary, because there are no suited cards above 76s A5o- offsuit hands; A5o-A2o A5s- suited hands; A5s-A2s K7 suited and offsuited version of hand; K7o, K7s J8o-J4o J8o, J7o, J6o, J5o, J4o 76s-74s 76s, 75s, 74s J8-J4 both ranges in suited an offsuited form; J8o, J7o, J6o, J5o, J4o, J8s, J7s, J6s, J5s, J4s A5+ either suited or offsuited hands that contains an Ace and the other is bigger than 5. Same as “A5o+ A5s+”. A5- downward, same as above XX every hand (100% range) In this special case, pairs are also included (but only this) AX Any hand that contains an ace either suited or offsuit (no pairs) AXo Any offsuit hand that contains an Ace (equivalent to A2o+) AXs Any suited hand that contains an Ace (equivalent to A2s+) QX+ Any hand that contains a card bigger than a Jack; Q2+, K2+, A2+ 5X- any hand that contains a card lower than 6 KXs+ Any suited hand that contains a card bigger than a Queen KXo+ same as above with offsuit hands 7Xs- same as above 8Xo- same as above 2s2h, AsKc exact hand Combos Note
“Q+” and “Q-” are invalid ranges, because in Hold’em, there are two hands to start with not one.
Ranges are case insensitive, so "AKs"
and "aks"
and "aKS"
means the same.
Also the order of the cards doesn’t matter. "AK"
is the same as "KA"
.
Hands can be separated by space (even multiple), comma, colon or semicolon, and Combo of them (multiple spaces, etc.).
Normalization¶
Ranges should be rearranged and parsed according to these rules:
- hands separated with one space only in repr, with “, ” in str representation
- in any given hand the first card is bigger than second (except pairs of course)
- pairs first, if hyphened, bigger first
- suited hands after pairs, descending by rank
- offsuited hands at the end
Printing the range as an HTML table¶
Range has a method to_html()
. When you print the result of that, you get a simple HTML table representation of it.
Range('XX').to_html()
looks like this:
AA | AKs | AQs | AJs | ATs | A9s | A8s | A7s | A6s | A5s | A4s | A3s | A2s |
AKo | KK | KQs | KJs | KTs | K9s | K8s | K7s | K6s | K5s | K4s | K3s | K2s |
AQo | KQo | QJs | QTs | Q9s | Q8s | Q7s | Q6s | Q5s | Q4s | Q3s | Q2s | |
AJo | KJo | QJo | JJ | JTs | J9s | J8s | J7s | J6s | J5s | J4s | J3s | J2s |
ATo | KTo | QTo | JTo | TT | T9s | T8s | T7s | T6s | T5s | T4s | T3s | T2s |
A9o | K9o | Q9o | J9o | T9o | 99 | 98s | 97s | 96s | 95s | 94s | 93s | 92s |
A8o | K8o | Q8o | J8o | T8o | 98o | 88 | 87s | 86s | 85s | 84s | 83s | 82s |
A7o | K7o | Q7o | J7o | T7o | 97o | 87o | 77 | 76s | 75s | 74s | 73s | 72s |
A6o | K6o | Q6o | J6o | T6o | 96o | 86o | 76o | 66 | 65s | 64s | 63s | 62s |
A5o | K5o | Q5o | J5o | T5o | 95o | 85o | 75o | 65o | 55 | 54s | 53s | 52s |
A4o | K4o | Q4o | J4o | T4o | 94o | 84o | 74o | 64o | 54o | 44 | 43s | 42s |
A3o | K3o | Q3o | J3o | T3o | 93o | 83o | 73o | 63o | 53o | 43o | 33 | 32s |
A2o | K2o | Q2o | J2o | T2o | 92o | 82o | 72o | 62o | 52o | 42o | 32o | 22 |
You can format it with CSS, you only need to define td.pair
, td.offsuit
and td.suited
selectors.
It’s easy to recreate PokerStove style colors:
<style>
td {
/* Make cells same width and height and centered */
width: 30px;
height: 30px;
text-align: center;
vertical-align: middle;
}
td.pair {
background: #aaff9f;
}
td.offsuit {
background: #bbced3;
}
td.suited {
background: #e37f7d;
}
</style>
AA | AKs | AQs | AJs | ATs | A9s | A8s | A7s | A6s | A5s | A4s | A3s | A2s |
AKo | KK | KQs | KJs | KTs | K9s | K8s | K7s | K6s | K5s | K4s | K3s | K2s |
AQo | KQo | QJs | QTs | Q9s | Q8s | Q7s | Q6s | Q5s | Q4s | Q3s | Q2s | |
AJo | KJo | QJo | JJ | JTs | J9s | J8s | J7s | J6s | J5s | J4s | J3s | J2s |
ATo | KTo | QTo | JTo | TT | T9s | T8s | T7s | T6s | T5s | T4s | T3s | T2s |
A9o | K9o | Q9o | J9o | T9o | 99 | 98s | 97s | 96s | 95s | 94s | 93s | 92s |
A8o | K8o | Q8o | J8o | T8o | 98o | 88 | 87s | 86s | 85s | 84s | 83s | 82s |
A7o | K7o | Q7o | J7o | T7o | 97o | 87o | 77 | 76s | 75s | 74s | 73s | 72s |
A6o | K6o | Q6o | J6o | T6o | 96o | 86o | 76o | 66 | 65s | 64s | 63s | 62s |
A5o | K5o | Q5o | J5o | T5o | 95o | 85o | 75o | 65o | 55 | 54s | 53s | 52s |
A4o | K4o | Q4o | J4o | T4o | 94o | 84o | 74o | 64o | 54o | 44 | 43s | 42s |
A3o | K3o | Q3o | J3o | T3o | 93o | 83o | 73o | 63o | 53o | 43o | 33 | 32s |
A2o | K2o | Q2o | J2o | T2o | 92o | 82o | 72o | 62o | 52o | 42o | 32o | 22 |
Printing the range as an ASCII table¶
to_ascii()
can print a nicely formatted ASCII table to the
terminal:
>>> print(Range('22+ A2+ KT+ QJ+ 32 42 52 62 72').to_ascii())
AA AKs AQs AJs ATs A9s A8s A7s A6s A5s A4s A3s A2s
AKo KK KQs KJs KTs
AQo KQo QQ QJs
AJo KJo QJo JJ
ATo KTo TT
A9o 99
A8o 88
A7o 77 72s
A6o 66 62s
A5o 55 52s
A4o 44 42s
A3o 33 32s
A2o 72o 62o 52o 42o 32o 22