Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > 2bb54e74e6dbbbfe00f09923014f5fe2 > files > 12

libpoker-eval-devel-135.0-1mdv2009.1.i586.rpm

/*
 * Copyright (C) 2004-2006
 *           Michael Maurer <mjmaurer@yahoo.com>
 *           Loic Dachary <loic@dachary.org>
 *
 *  This package is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 dated June, 1991.
 *
 *  This package is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this package; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
 *  MA 02110-1301, USA.
 */
/* $Id: enumord.h 1773 2006-10-12 11:34:41Z loic $ */
/*
  Definitions for computing a histogram of final hand orderings.

  A final hand ordering is defined by the relative rank of each player's hand
  after all cards are dealt.  For example, in a high-only game with 3 players,
  the possible final hand orderings for players A, B, and C are (where
  comma denotes tie):
        A B C
        A C B
        B A C
        B C A
        C A B
        C B A
        A B,C
        B A,C
        C A,B
        A,B C
        A,C B
        B,C A
        A,B,C
  Another way to reprsent this is to assign a player to a column and write
  the relative hand rank (1=best) in that column.  Then the possibilities
  above are written (in the same order as above) as
        A B C
        -----
        1 2 3
        1 3 2
        2 1 3
        2 3 1
        3 1 2
        3 2 1
        1 2 2
        2 1 2
        2 2 1
        1 1 2
        1 2 1
        2 1 1
        1 1 1
  Our encoding here is based on the second form.

  For high/low games, we track the full combination of outcomes.  In a
  2-person game with a qualifier for low, the possible outcomes are:
         HI         LO
        A  B       A  B
        1  1       1  1		tie for high; tie for low
        1  1       1  2		tie for high; A wins low
        1  1       1 NQ		tie for high; A wins low, B doesn't qualify low
        1  1       2  1		tie for high; B wins low
        1  1      NQ  1		etc.
        1  1      NQ NQ
        1  2       1  1
        1  2       1  2
        1  2       1 NQ
        1  2       2  1
        1  2      NQ  1
        1  2      NQ NQ
        2  1       1  1
        2  1       1  2
        2  1       1 NQ
        2  1       2  1
        2  1      NQ  1
        2  1      NQ NQ

  For ease of programming, we are somewhat wasteful of memory when storing the
  histogram of outcomes.  We allocate an array such that hist[i] is the number
  of times that outcome i occurs.  The integer i encodes the ordering of N
  players' hand ranks by using N bit fields, each bit field just large enough
  to represent the numbers [0..N].  The value 0 in bit field K indicates that
  player K has the strongest hand (possibly tying another player); the value
  N-1 indicates player K has the weakest hand; the value N indicates a
  non-qualifying hand (such as a 9-low in 8-or-better).  Note that not all
  integers i correspond to valid rank orderings, both due the fact that for
  some values of N the bit field can encode values greater than N, and due to
  the fact that some rank orderings, like a 3-way tie for 3rd place, are
  impossible.  That is the wasteful part; a hash table would solve it.

  For high-low games, we use two such sets of bit fields, packed adjacent to
  one another in a single integer.  The high-order bit fields correspond to
  the high hand; the low-order bit fields correspond to the low hand.

  Michael Maurer, Jun 2002
*/

#ifndef ENUMORD_H
#define ENUMORD_H

#include "pokereval_export.h"
#include "poker_defs.h"

/* largest integer N such that N * ENUM_ORDERING_NBITS(N) < 32 */
#define ENUM_ORDERING_MAXPLAYERS 7

/* largest integer N such that 2 * N * ENUM_ORDERING_NBITS(N) < 32 */
#define ENUM_ORDERING_MAXPLAYERS_HILO 5

typedef enum {
  enum_ordering_mode_none = 0,
  enum_ordering_mode_hi,
  enum_ordering_mode_lo,
  enum_ordering_mode_hilo
} enum_ordering_mode_t;

typedef struct {
  enum_ordering_mode_t mode;
  unsigned int nplayers;
  unsigned int nentries; /* equal to ENUM_ORDERING_NENTRIES(nplayers)
                            or ENUM_ORDERING_NENTRIES_HILO(nplayers),
                            depending on mode */
  /* hist[i] is the number of outcomes in which the ordering of players'
     relative hand values corresponds to ordering i.  We encode each ordering
     as an integer i such that ENUM_ORDERING_DECODE_PLAYER_K(i, n, k) gives
     the relative hand rank of player k out of n players.  Rank is encoded as
     an integer in [0,n] where 0=strongest, n-1=weakest, n=non-qualifying. */
  unsigned int *hist;	/* has nenetries elements */
} enum_ordering_t;

extern POKEREVAL_EXPORT int enum_nbits[ENUM_ORDERING_MAXPLAYERS+1];
extern POKEREVAL_EXPORT void enum_ordering_rank(HandVal *hands, int noqual,
                               int nplayers, int *ranks, int reverse);

/* the bit field size for one player's relative hand rank */
#define ENUM_ORDERING_NBITS(nplayers) \
  ((nplayers < 0 || nplayers >= sizeof(enum_nbits)/sizeof(enum_nbits[0])) \
   ? -1 : enum_nbits[nplayers])

/* the number of elements in the hist[] array */
#define ENUM_ORDERING_NENTRIES(nplayers) \
  (((nplayers > ENUM_ORDERING_MAXPLAYERS) || \
    ENUM_ORDERING_NBITS(nplayers) < 0) \
   ? -1 : (1 << (nplayers * ENUM_ORDERING_NBITS(nplayers))))

/* the number of elements in the hist[] array in high/low games */
#define ENUM_ORDERING_NENTRIES_HILO(nplayers) \
  (((nplayers > ENUM_ORDERING_MAXPLAYERS_HILO) || \
    ENUM_ORDERING_NBITS(nplayers) < 0) \
   ? -1 : (1 << (2 * nplayers * ENUM_ORDERING_NBITS(nplayers))))

/* Compute the integer encoding of a given array of relative hand rankings.
   ranks[k] is relative hand rank of player k's hand; rank=0 is best,
   rank=nplayers-1 is worst, rank=nplayers is non-qualifying.  Caller must
   ensure that 0 <= ranks[k] <= nplayers.  */
#define ENUM_ORDERING_ENCODE(encoding, nplayers, ranks) \
do { \
  int _k; \
  int _nbits = ENUM_ORDERING_NBITS(nplayers); \
  (encoding) = 0; \
  for (_k=0; _k<(nplayers); _k++) \
    (encoding) = ((encoding) << _nbits) | ((ranks)[_k]); \
} while (0)
  
/* Compute the integer encoding of a given array of relative hand rankings
   for high/low games. */
#define ENUM_ORDERING_ENCODE_HILO(encoding, nplayers, hiranks, loranks) \
do { \
  int _k; \
  int _nbits = ENUM_ORDERING_NBITS(nplayers); \
  (encoding) = 0; \
  for (_k=0; _k<(nplayers); _k++) \
    (encoding) = ((encoding) << _nbits) | ((hiranks)[_k]); \
  for (_k=0; _k<(nplayers); _k++) \
    (encoding) = ((encoding) << _nbits) | ((loranks)[_k]); \
} while (0)
  
/* the number of bits to the start of the bit field for player k */
#define ENUM_ORDERING_SHIFT_K(nplayers, k) \
   (((nplayers) - (k) - 1) * ENUM_ORDERING_NBITS(nplayers))

/* the number of bits to the start of the bit field for player k's high
 hand, in a high/low game */
#define ENUM_ORDERING_SHIFT_HILO_K_HI(nplayers, k) \
   ((2*(nplayers) - (k) - 1) * ENUM_ORDERING_NBITS(nplayers))

/* the number of bits to the start of the bit field for player k's low
 hand, in a high/low game */
#define ENUM_ORDERING_SHIFT_HILO_K_LO(nplayers, k) \
   (((nplayers) - (k) - 1) * ENUM_ORDERING_NBITS(nplayers))

/* a bit mask covering the bit field for player k */
#define ENUM_ORDERING_MASK_K(nplayers, k) \
  ((~(~0 << ENUM_ORDERING_NBITS(nplayers))) << \
   ENUM_ORDERING_SHIFT_K((nplayers), (k)))

/* a bit mask covering the bit field for player k's high hand, in a high/low
   game */
#define ENUM_ORDERING_MASK_HILO_K_HI(nplayers, k) \
  ((~(~0 << ENUM_ORDERING_NBITS(nplayers))) << \
   ENUM_ORDERING_SHIFT_HILO_K_HI((nplayers), (k)))

/* a bit mask covering the bit field for player k's low hand, in a high/low
   game */
#define ENUM_ORDERING_MASK_HILO_K_LO(nplayers, k) \
  ((~(~0 << ENUM_ORDERING_NBITS(nplayers))) << \
   ENUM_ORDERING_SHIFT_HILO_K_LO((nplayers), (k)))

/* decodes the integer encoding to yield the relative rank of
   player k's hand */
#define ENUM_ORDERING_DECODE_K(encoding, nplayers, k) \
  (((encoding) & ENUM_ORDERING_MASK_K((nplayers), (k))) >> \
   ENUM_ORDERING_SHIFT_K((nplayers), (k)))
   
/* decodes the integer encoding to yield the relative rank of
   player k's high hand in a high/low game */
#define ENUM_ORDERING_DECODE_HILO_K_HI(encoding, nplayers, k) \
  (((encoding) & ENUM_ORDERING_MASK_HILO_K_HI((nplayers), (k))) >> \
   ENUM_ORDERING_SHIFT_HILO_K_HI((nplayers), (k)))
   
/* decodes the integer encoding to yield the relative rank of
   player k's low hand in a high/low game */
#define ENUM_ORDERING_DECODE_HILO_K_LO(encoding, nplayers, k) \
  (((encoding) & ENUM_ORDERING_MASK_HILO_K_LO((nplayers), (k))) >> \
   ENUM_ORDERING_SHIFT_HILO_K_LO((nplayers), (k)))
   
/* given hands[], assigns ranks[k] such that a rank of 0 indicates that
   hands[k] is the highest hand value in hands[], a rank of 1 indicates
   that hands[k] is the next highest value, etc., and a rank of nplayers
   indicates that hands[k] is equal to noqual (the not-qualifying hand) */
#define ENUM_ORDERING_RANK_HI(hands, noqual, nplayers, ranks) \
  enum_ordering_rank((hands), (noqual), (nplayers), (ranks), 0)

/* given hands[], assigns ranks[k] such that a rank of 0 indicates that
   hands[k] is the lowest hand value in hands[], a rank of 1 indicates
   that hands[k] is the next lowest value, etc., and a rank of nplayers
   indicates that hands[k] is equal to noqual (the not-qualifying hand) */
#define ENUM_ORDERING_RANK_LO(hands, noqual, nplayers, ranks) \
  enum_ordering_rank((hands), (noqual), (nplayers), (ranks), 1)

/* increments the histogram bin value corresponding to the ranks[] array */
#define ENUM_ORDERING_INCREMENT(ordering, nplayers, ranks) \
do { \
  int _encoding; \
  ENUM_ORDERING_ENCODE(_encoding, (nplayers), (ranks)); \
  (ordering)->hist[_encoding]++; \
} while (0)

/* increments the histogram bin value corresponding to the ranks[] array,
 for high/low games*/
#define ENUM_ORDERING_INCREMENT_HILO(ordering, nplayers, hiranks, loranks) \
do { \
  int _encoding; \
  ENUM_ORDERING_ENCODE_HILO(_encoding, (nplayers), (hiranks), (loranks)); \
  (ordering)->hist[_encoding]++; \
} while (0)

#endif