NAME
   Games::Cards::Poker - Pure Perl Poker functions

VERSION
   This documentation refers to version 1.2.565CHh5 of Games::Cards::Poker,
   which was released on Sun Jun 5 12:17:43:05 2005.

SYNOPSIS
     use Games::Cards::Poker;

     # Deal Four (4) players hands and score them...
     my $players   = 4; # number of players to get hands dealt
     my $hand_size = 5; # number of cards to deal to each player
     my @hands     = ();# player hand data
     my @deck      = Shuffle(Deck());

     while($players--) {
       push(@{$hands[$players]}, pop(@deck)) foreach(1..$hand_size);
       printf("Player$players score:%4d hand:@{$hands[$players]}\n",
                                   ScoreHand(@{$hands[$players]}));
     }

DESCRIPTION
   Poker provides a few functions for creating decks of cards and
   manipulating them for simple Poker games or simulations.

2DO
   - mk CalcOdds() work more accurately and for more opponents and factor
   in stages beyond hole
   - maybe remove all %pdat ways data (since all can be determined easily)
   - better error checking
   - What else does Poker need?

USAGE
 Deck()
   Returns a new array of scalars with the abbreviated Poker names of cards
   (e.g., 'As' for 'Ace of Spades', 'Td' for 'Ten of Diamonds', '2c' for
   'Two of Clubs', etc.).

   Use CardName() to expand abbreviated cards into their full names.

 Shuffle(@cards)
   Shuffles the passed in @cards array in one quick pass. Shuffle() returns
   a shuffled copy of the @cards array.

   Shuffle() can also take an arrayref parameter instead of an explicit
   @cards array in which case, the passed in arrayref will be shuffled in
   place so the return value does not need to be reassigned.

 SortCards(@cards)
   Sorts the passed in @cards array. SortCards() returns a sorted copy of
   the @cards array.

   SortCards() can also take an arrayref parameter instead of an explicit
   @cards array in which case, the passed in arrayref will be sorted in
   place so the return value does not need to be reassigned.

   SortCards() works consistently on the return values of ShortHand() as
   well as abbreviated cards (e.g., 'AAA', 'AAK'..'AKQs', 'AKQ'..'222').

 ShortHand(@hand)
   Returns a scalar string containing the abbreviated Poker description of
   @hand (e.g., 'AKQJTs' for 'Royal Flush', 'QQ993' for 'Two Pair', etc.).

   ShortHand() calls SortCards() on its parameter before doing the
   abbreviation to make sure that the return value is consistent.

   ShortHand() can be called on fewer cards than a full @hand of 5 to
   obtain other useful abbreviations (e.g., ShortHand(@hole) will return
   the abbreviated form of a player's two hole [pocket] cards or
   ShortHand(@flop) will abbreviate the three community cards which flop
   onto the board in Hold'Em).

 ScoreHand(@hand)
   This is a new version of SlowScoreHand(). Both do the opposite of
   HandScore() by accepting a ShortHand() string and returning the proper
   associated Poker score.

   This version simply indexes the string as a key into a hash of
   corresponding score values so it is much faster and should be used for
   any normal hand scoring needs.

   If you would prefer to use the slower computational version of scoring
   hands, you can call the UseSlow() function to make ScoreHand() actually
   call SlowScoreHand() instead of just indexing the answer score in a
   hash.

 HandScore($score)
   This function is the opposite of ScoreHand(). It takes an integer $score
   parameter and returns the corresponding ShortHand string.

   HandScore() uses a fully enumerated table to just index the associated
   ShortHand so it should be quite fast. The table was generated by running
   SlowScoreHand() on every possible hand and sorting the resultant
   ShortHands by score.

ADVANCED USAGE
 SlowScoreHand(@hand)
   Returns an integer score (where lower is better) for the passed in Poker
   @hand. This means 0 (zero) is returned for a Royal Flush and the worst
   possible score is 7461 awarded to 7, 5, 4, 3, 2 unsuited.

   If you want higher scores to mean higher hands, just subtract the return
   value from 7461.

   All suits are considered to have equal value in this scoring function.
   It should be easy to use SlowScoreHand() as a first pass where ties can
   be resolved by another suit-comparison function if you want such
   behavior.

 UseSlow([$slow])
   UseSlow() is a function provided in case you'd prefer to actually employ
   the SlowScoreHand() function whenever you call ScoreHand().

   UseSlow() takes an optional $slow value. If you don't provide $slow,
   UseSlow() will toggle the slow state.

   UseSlow() always returns the current state of whether SlowScoreHand() is
   being used whenever ScoreHand() is called.

 BestIndices(@cards)
   BestIndices() takes 5 or more cards (normally 7) which can be split
   among separate arrays (like BestIndices(@hole, @board) for Hold'Em) and
   returns an array of the indices of the 5 cards (hand) which yield the
   best score.

 BestHand(@best, @cards)
   BestHand() takes the return value of BestIndices() as the first
   parameter (which is an array of the best indices) and then the same
   other parameters (@cards) or (@hole, @board) to give you a copy of just
   the best cards. The return value of this function can be passed to
   ScoreHand() to get the score of the best hand.

   BestHand() can optionally take just the @cards like BestIndices() and it
   will automagically call BestIndices() first to obtain @best. It will
   then return copies of those indexed cards from the @cards.

 HandName($score)
   HandName() takes a HandScore() parameter (e.g., 0, 2000, 7000) and
   returns the name of the corresponding hand scoring category it falls
   under (e.g., 'Royal Flush', 'Three-of-a-Kind', 'High Card').

   HandName() can optionally accept an arrayref to a hand, the @hand
   itself, or a ShortHand instead of the $score parameter.

 VerboseHandName($score)
   VerboseHandName() takes a HandScore() parameter (e.g., 0, 2000, 7000)
   and returns the name of the corresponding verbose (i.e., commonly
   spoken) description of the hand (e.g., 'Aces over Kings', 'Tens, Jack
   kicker', 'Queen high, Ten kicker'). VerboseHandName() should normally be
   used in conjunction with HandName() as a further clarification of a
   specific hand's description.

   VerboseHandName() can optionally accept an arrayref to a hand, the @hand
   itself, or a ShortHand instead of the $score parameter.

 NameCard($name)
   NameCard() does the opposite of CardName() by taking an expanded full
   $name (e.g., 'Queen of Diamonds', 'Jack of Hearts', 'Ten of Clubs') and
   returning the abbreviated card (e.g., 'Qd', 'Jh', 'Tc').

 CardName($card)
   CardName() takes an abbreviated $card (e.g., 'As', 'Kh', '2c') and
   returns the expanded full name of the card ('Ace of Spades', 'King of
   Hearts', 'Two of Clubs').

 B64Card($b64c)
   B64Card() does the opposite of CardB64() by taking a base-64 card
   ($b64c) representation (e.g., 'K', 'N', 'T') and returning the
   abbreviated card (e.g., 'Qd', 'Jh', 'Tc').

 CardB64($card)
   CardB64() takes an abbreviated $card (e.g., 'As', 'Kh', '2c') and
   returns the single character (only letters) base-64 representation of
   the card ('A', 'F', 'z');

   Please see the "NOTES" section below for the complete B64 <-> Card
   conversion table.

 B64Hand($b64h)
   B64Hand() does the opposite of HandB64() by taking a string containing
   several concatenated base-64 card abbreviations and converting it into a
   list of the cards.

 HandB64(@hand)
   HandB64() takes a list of cards which make up a @hand (or a reference to
   such an array) and returns a base-64 abbreviation string.

 DecCard($decc)
   DecCard() does the opposite of CardDec() by taking a decimal card
   ($decc) representation (e.g., '0', '3', '51') and returning the
   abbreviated card (e.g., 'As', 'Ac', '2c').

 CardDec($card)
   CardDec() takes an abbreviated $card (e.g., 'As', 'Kh', '2c') and
   returns the corresponding decimal card representation ('0', '15', '51').

 DecHand($dech)
   DecHand() does the opposite of HandDec() by taking a string containing
   several concatenated decimal card abbreviations and converting it into a
   list of the cards.

 HandDec(@hand)
   HandDec() takes a list of cards which make up a @hand (or a reference to
   such an array) and returns an array of decimal abbreviations.

 RemoveCard($card, @cards)
   Returns a copy of @cards with abbreviated $card (e.g., 'Td') removed.

   RemoveCard() can also take an arrayref parameter instead of an explicit
   @cards array in which case, the passed in arrayref will be updated in
   place so the return value does not need to be reassigned.

 WorstHand(@cards)
   Returns the ShortHand description of the worst hand possible using
   @cards. This means that if there are fewer than 5 @cards, it returns
   simply the worst hand containing all of them however if there are 5 or
   more cards, it returns the same result as the abbreviated best hand
   (i.e., ShortHand(BestHand(BestIndices(@cards), @cards)) )since that is
   also the worst hand you are guaranteed to at least have out of your
   @cards.

   WorstHand() can also accept an arrayref or ShortHand parameter in place
   of a list of cards.

   WorstHand() is useful for calculating odds when you have a chance to
   improve your hand by future cards but you want to know the minimum hand
   or score you are guaranteed of.

 CountWays($bad_score_limit [,$good_score_limit])
   CountWays() helps calculate odds by summing the ways to get a range of
   abbreviated card sets (normally just ShortHands) between the
   $bad_score_limit (which starts from 7461, the bad 'High Card' end of
   hands) to the optional $good_score_limit (which starts from 0, the good
   'Royal Flush' end of hands).

 CalcOdds($hole_index)
   CalcOdds() takes the index of a hole abbreviation (e.g., %zloh = Zloh;
   CalcOdds($zloh{'AA'})) from a Hold'Em game and returns the percent that
   will win against all possibilities.

   CalcOdds() is only an approximation for heads up situations for now but
   it will hopefully be improved later as I study the statistics further.

 PDat() and Other Poker Data Accessors
   PDat() is my global Poker Data structure which contains all of the data
   used to populate each of the smaller structures below. These can all be
   accessed with the :data export tag with:

     use Games::Cards::Poker qw(:data);

   RPrV() - Simple accessor to my Rank Progression Value hash where ranks
   are keys and their indices in RPrg() are values.

   RPrg() - Simple accessor to my Rank Progression array: 'A'..'2'

   SPrg() - Simple accessor to my Suit Progression array: 's'..'c'

   RNam() - Simple accessor to my Rank Name array: 'Ace'..'Two'

   SNam() - Simple accessor to my Suit Name array: 'Spades'..'Clubs'

   Namz() - Simple accessor to my Hand Name hash where keys are score
   thresholds and values are full names of hand categories.

   Zman() - The reverse of Namz() where values and keys switch.

   Hndz() - Simple accessor to my ShortHands array in score order.

   Zdnh() - The reverse of Hndz() as a hash where ShortHands key their
   score value.

   Holz() - Simple accessor to my ShortHands array of possible holes.

   Zloh() - The reverse of Holz() as a hash where ShortHands key their
   index value.

   Flpz() - Simple accessor to my ShortHands array of possible flops.

   Zplf() - The reverse of Flpz() as a hash where ShortHands key their
   index value.

EXPORT TAGS
   Games::Cards::Poker normally only exports a few key Poker functions
   (Deck Shuffle SortCards ShortHand ScoreHand HandScore) into your local
   namespace when you:

     use Games::Cards::Poker;

   You can specify additional export tags such as:

     use Games::Cards::Poker qw(:all);

   for when you want to utilize more than just the above default functions.

 :all
   Exports everything!

     Shuffle Deck SortCards ShortHand HandName VerboseHandName
     BestIndices CardB64 B64Hand CardDec DecHand ScoreHand CardName
     BestHand    B64Card HandB64 DecCard HandDec HandScore NameCard
     WorstHand RemoveCard CountWays CalcOdds SlowScoreHand UseSlow
     RPrg RNam Namz Hndz Holz Flpz RPrV SPrg SNam Zman Zdnh Zloh Zplf PDat

 :best
   This tag just exports functions for finding the best hand out of some
   list of more than 5 cards.

     BestIndices BestHand

 :slow
   This tag just exports my old slower hand scoring function (which uses
   combinatorics and sequence summation to score any Poker hand) and
   another function to specify if you prefer to use the slower scoring all
   the time.

     SlowScoreHand UseSlow

 :name
   This tag exports functions which convert between verbose names for cards
   and hands.

     CardName NameCard HandName VerboseHandName

 :b64
   This tag exports functions which convert between base-64 representations
   of cards and hands.

     CardB64 B64Card HandB64 B64Hand

 :dec
   This tag exports functions which convert between decimal representations
   of cards and hands.

     CardDec DecCard HandDec DecHand

 :odds
   This tag exports functions which should be useful in calculating odds.

     WorstHand RemoveCard CountWays CalcOdds

 :data
   This tag exports all internal data sets in case direct access to them is
   beneficial.

     RPrg RNam Namz Hndz Holz Flpz RPrV SPrg SNam Zman Zdnh Zloh Zplf PDat

WHY?
   Games::Poker::* wouldn't compile correctly for me since it had some
   weird broken .xs dependencies I couldn't figure out so I thought it
   shouldn't take too long to write my own Poker module purely in Perl. =)
   It was certainly a fun problem... much trickier than I first imagined
   but I think I have solved the problem elegantly once and for all.

NOTES
   Suits are: s,h,d,c (Spade,Heart,Diamond,Club) like bridge
   (anti-alphabetical). Although they are sorted and appear in this order,
   suits are ignored for scoring by default (but can be optionally
   reordered and scored later)

   B64 notes: Cards map perfectly into A..Z,a..z (indx += 10) for one
   letter rep

                                                                           Suits:
     B64 Cards: A.As E.Ks I.Qs M.Js Q.Ts U.9s Y.8s c.7s g.6s k.5s o.4s s.3s w.2s 0
                B.Ah F.Kh J.Qh N.Jh R.Th V.9h Z.8h d.7h h.6h l.5h p.4h t.3h x.2h 1
                C.Ad G.Kd K.Qd O.Jd S.Td W.9d a.8d e.7d i.6d m.5d q.4d u.3d y.2d 2
                D.Ac H.Kc L.Qc P.Jc T.Tc X.9c b.8c f.7c j.6c n.5c r.4c v.3c z.2c 3
         Ranks:   0    1    2    3    4    5    6    7    8    9    A    B    C

     B64 Cards: A.As B.Ah C.Ad D.Ac Ranks: 0
                E.Ks F.Kh G.Kd H.Kc        1
                I.Qs J.Qh K.Qd L.Qc        2
                M.Js N.Jh O.Jd P.Jc        3
                Q.Ts R.Th S.Td T.Tc        4
                U.9s V.9h W.9d X.9c        5
                Y.8s Z.8h a.8d b.8c        6
                c.7s d.7h e.7d f.7c        7
                g.6s h.6h i.6d j.6c        8
                k.5s l.5h m.5d n.5c        9
                o.4s p.4h q.4d r.4c        A
                s.3s t.3h u.3d v.3c        B
                w.2s x.2h y.2d z.2c        C
                0.Jokr                    -1
         Suits:    0    1    2    3

   Error checking is minimal.

   I hope you find Games::Cards::Poker useful. Please feel free to e-mail
   me any suggestions or coding tips or notes of appreciation
   ("app-ree-see-ay-shun"). Thank you. TTFN.

CHANGES
   Revision history for Perl extension Games::Cards::Poker:

   - 1.2.565CHh5 Sun Jun 5 12:17:43:05 2005
       * added VerboseHandName() from code contributed by Roy Lyons

       * fixed Shuffle() off-by-one results skewing error reported by Lee

   - 1.2.4CCJ12M Sun Dec 12 19:01:02:22 2004
       * added MySQL and XML and .c and Tk scripts to bin/

       * fixed pod typo and updated License

   - 1.2.46QD4ax Sat Jun 26 13:04:36:59 2004
       * added Dec functions

   - 1.2.4610lBw Tue Jun 1 00:47:11:58 2004
       * removed benchmrk.pl since it's not worth including in pkg

       * fixed some out-of-date POD and rearranged USAGE

   - 1.2.45UGmiC Sun May 30 16:48:44:12 2004
       * upped minor version number since CPAN doesn't recognize my PTVR

       * split test.pl into t/*.t and added those + bin/pokr to MANIFEST

       * added separate EXPORT_TAGS and added ADVANCED USAGE POD

       * added RemoveCard(), WorstHand(), CountWays(), and CalcOdds()

       * added %pdat as common structure for all my Poker Data and Counts

       * added B64Hand and HandB64 functions

       * added simple accessors to internal data

       * added possible hole and flop data

       * made CardName take either of just rank or suit

       * made new b64 card conversion functions: CardB64() and B64Card()

       * changed b64 maps to use letters

   - 1.0.44P0KER Sun Apr 25 00:20:14:27 2004
       * made CardName() to return 'Ace of Spades' or 'Two of Clubs' for
       'As'or'A' or '2c'or'z' and NameCard() to do inverse

       * made HandName() to return 'Royal Flush' or 'High Card' for
       ScoreHand() or ShortHand() or @hand or \@hand and NameHand()

       * rewrote SortCards() to accept any length ShortHand() params

       * s/valu/rank/g s/scor/score/g s/bord/board/g

   - 1.0.44LCEw8 Wed Apr 21 12:14:58:08 2004
       * s/HoldEm//g; on advice from Joe since Best*() are useful for more
       than just Hold'Em (like 7-card stud)

       * fixed minor typos in POD

   - 1.0.44KFNKP Tue Apr 20 15:23:20:25 2004
       * wrote UseSlow() so that benchmrk.pl would still work without
       Best() and in case anyone would rather have ScoreHand() call
       SlowScoreHand() every time instead.

       * since my old Best() was actually slower than BestHoldEmIndices()
       =O I removed Best().

       * since old Scor() was so much faster than old ScoreHand(), I
       renamed them to ScoreHand() and SlowScoreHand() respectively since
       computational version is unnecessary now.

       * wrote benchmrk.pl to test BestHoldEmIndices() + ScoreHand()
       against Best() + Scor(). Best()+Scor() only took 60% as long to run.

       * added SortCards() call on ShortHand() param just in case

   - 1.0.44ILBKV Sun Apr 18 21:11:20:31 2004
       * wrote Scor() with gen'd enumerated hash of ShortHand => Score

       * wrote HandScore() to just lookup index of a ShortHand from a score

       * squashed 4 scoring bugs in one pair section

       * used Algorithm::ChooseSubsets for new BestHoldEmIndices (on Jan's
       recommendation)

       * renamed enumerated BestHoldEmIndices() as Best()

       * gave ScoreHand() optional arrayref param like others

       * gave ScoreHand() optional ShortHand() string param

       * updated 2do and tidied up documentation a bit

   - 1.0.44H2DUS Sat Apr 17 02:13:30:28 2004
       * added BestHoldEmIndices() and BestHoldEmHand() for Tim and Jan

       * commented unnecessary Games::Cards inheritance since I haven't
       written any compatability / object interface yet

   - 1.0.44F2Q8F Thu Apr 15 02:26:08:15 2004
       * original version

INSTALL
   Please run:

       `perl -MCPAN -e "install Games::Cards::Poker"`

   or uncompress the package and run the standard:

       `perl Makefile.PL; make; make test; make install`

LICENSE
   Most source code should be Free! Code I have lawful authority over is
   and shall be! Copyright: (c) 2004, Pip Stuart. Copyleft : This software
   is licensed under the GNU General Public License (version 2), and as
   such comes with NO WARRANTY. Please consult the Free Software Foundation
   (http://FSF.Org) for important information about your freedom.

AUTHOR
   Pip Stuart <[email protected]>