parsecards.txt version 1.1 arfer operation of parsecards.tcl parsecards.tcl is not a script in its own right, rather it is called/utilised by other scripts in order to derive/recognise the best 5 card poker hand from a string representation of between 5 and 9 cards parsecards.tcl should be loaded before any other script that uses it any procedure in the namespace nParseCards can be called from within your script. to pass the string representation of cards to the parsing engine you could typically use statements akin to the following :- set x "Ah Td 4c 3s Js 7h" set y [nParseCards::pParseCards $x] the above statements pass the string representation of cards held in the variable x to pParseCards procedure within nParseCards namespace. the return value is stored in the variable y the return value has 3 components :- 1. a string representaion of the best 5 card poker hand 2. the plain english poker name for this 5 card poker hand 3. an enumerated ranking system for this 5 card poker hand (more on this later) the 3 components are returned in a single string seperated by the character '|', so the above code would yield a return value (stored in variable y) as follows :- "Ah Js Td 7h 4c|Ace High, Jack Kicker|10 1 4 5 8 11" the components can be split from the return value typically using statements such as the following to place each component in a separate string variable :- set z1 [join [lindex [split $y "\|"] 0]]; # z1 stores the hand itself set z2 [join [lindex [split $y "\|"] 1]]; # z2 stores the name of the hand set z3 [join [lindex [split $y "\|"] 2]]; # z3 stores the enumerated ranking of the hand the demonstration script pokerdemo.tcl will allow you to confirm the above. a string of cards such as that in x above can be input or the script will, in fact, generate a random string of cards automatically. the 3 components, split into seperate variables, will be output to the irc channel. full instructions for using pokerdemo.tcl are contained within the script itself parsecards.tcl simply parses the card string through a series of procedures in order of major poker hand ranking (see http://www.pagat.com/vying/pokerrank.html) until a hand is recognised. the card string is first passed through one of two procedures that puts the cards in suit or value order, whichever is appropriate to recognition of a specific hand type. once a non zero return value occurs, the parsing stops. for example, there is little point searching for a flush once a straight flush has been detected. it is the highest ranking hand that matters. the procedures/major ranks are as follows :- 1 Royal Flush 2 Straight Flush 2 Straight Flush Ace Low 3 Four Of A Kind 4 Full House 5 Flush 6 Straight 6 Straight Ace Low 7 Three Of A Kind 8 Two Pair 9 One Pair 10 High Card note that straight flush and straight flush ace low have the same major ranking. likewise a straight and a straight ace low. they are separated above simply because they are dealt with separately in parsecards.tcl the number to the left of the major poker hand ranking above is the first number in the enumerated hand ranking. for example, the enumerated hand ranking for a pair of threes (or any other single pair for that matter) would always start with 9 the remaining five numbers in the enumerated hand ranking represent the five cards in value order as follows :- Ace = 1 King = 2 Queen = 3 Jack = 4 Ten = 5 Nine = 6 Eight = 7 Seven = 8 Six = 9 Five = 10 Four = 11 Three = 12 Two = 13 using the above example stored in variable z3, namely 10 1 4 5 8 11 :- 10 = High Card 1 = Ace 4 = Jack 5 = Ten 8 = Seven 11 = Four so we can sort of reverse deduce from this that the hand was Ace High, Jack Kicker followed by a ten, seven and four note that where similar hands in poker exist, they are not usually separated by suit. for example, it doesn't matter whether a flush is in hearts, clubs, diamonds or spades. it is the successive card values that are used to determine the best flush from two or more with the same high card there is one oddity that perhaps deviates slightly from the norm in respect of enumerated hand ranking, that is in the case of a straight with ace low or a straight flush with ace low. for example 5h 4h 3h 2h Ah. in the enumerated ranking, ace would still be represented by 1 but it would be last in the sequence of numbers rather than immediatelly following the major hand rank (2 for a straight flush) 5h 4h 3h 2h Ah equates to 2 10 11 12 13 1 the enumerated ranking could be used to simplify the process of finding a winner from two or more similar hands in a multiuser game simply by examining each number in turn to find which player's hand has the lowest. for example :- Player 1 has Ah Qc Td 5d 3s (Ace High, Queen Kicker) which equates to 10 1 3 5 10 12 Player 2 has Ad Qs Tc 6h 2c (Ace High, Queen Kicker) which equates to 10 1 3 5 9 13 examining the numbers one by one we see that the 5th number in the sequences is lower (representing a higher card) for player 2, hence he is the winner. we need not take any interest in subsequent number(s). if all the numbers were equal, then the hands would be tied although the intent was to provide a mechanism for simplifying hand comparison in a multiuser game environment, it turns out that basic tcl does not have a min or max function within the scope of expr, which would clearly have been of use. these functions exist in the extended tclx but this is not included in the version used in eggdrop/windrop bots (at least not at present as far as I know) there remains one minor problem area with parsecards.tcl that restricts it's use to the parsing of not more than 9 cards. I count it as minor because it's difficult to envision a poker game where more than 9 cards are needed, yet I guess it remains a bit of an annoyance. the problem concerns recognition of the best flush. consider the following ten cards :- 5c 6h Qc Jc Qh Th 8h 2c 3c 7h there are two queen flushes Qh Th 8h 7h 6h and Qc Jc 5c 3c 2c. the winning flush is discerned by looking at the minor cards in value order. since Jc beats Th then the queen flush in clubs is the highest (winning) hand. however, parsecards.tcl would return the queen flush in hearts the flush procedure in parsecards.tcl functions by looking for an ace flush in hearts then an ace flush in clubs then an ace flush in diamonds then an ace flush in spades, stopping once an ace flush is found. if an ace flush is not found, then it continues in the same way looking for a king flush then a queen flush etc etc. it would therefore find the queen flush in hearts and stop, without ever looking for a queen flush in clubs this procedure would need to be changed such that it firstly collected ALL the ace flushes should one or more exist. if one exists it is returned, if more than one exists then the best one is found and that returned, whilst if none exist then it moves on to kings, then queens etc in the same manner. this difficulty does not effect any other hand type. if the procedure was changed in the manner described then parsecards.tcl could be used for any number of input cards, all the pack if you wish (though I can't think why, since this would always return a royal flush in hearts - because again it looks for hearts first and the suit makes no difference to the hand value). it goes without saying that there can't be more than one flush (in different suits) in 9 cards or less. this is the point where i discovered the lack of support in the scope of expr for min and max functions, so i thought i'd publish it 'as is' and leave the tricky flush issue to somebody rather more expert than me. if the reader feels up to the task, run a few card strings similar to the ten cards above through pokerdemo.tcl, just to confirm it works most irc users neither know nor care about the workings of tcl. they just want functioning scripts. for this reason i have included in pokerstuff1.0.zip a full game script that emulates a poker slot machine using parsecards.tcl. full instructions can be found within the script itself. have fun!