コード例 #1
0
	/*
		pocket1 and pocket2 are 2 cards represented as strings e.g "AcKc"
		board is made up of 5 cards represented as strings e.g "AcKcQcJcTc"
	*/
	int CompareTexasHand(const char* hand1, const char* hand2, const char* board)
	{
		// Say we start with something like this...
		StdDeck_CardMask player1 = TextToPokerEval(hand1);
		StdDeck_CardMask player2 = TextToPokerEval(hand2);
		StdDeck_CardMask theBoard = TextToPokerEval(board);

		// Get each player's full 7-card hand into his mask
		StdDeck_CardMask_OR(player1, player1, theBoard);
		StdDeck_CardMask_OR(player2, player2, theBoard);

		// Evaluate each player's hand
		int player1Val = StdDeck_StdRules_EVAL_N(player1, 7);
		int player2Val = StdDeck_StdRules_EVAL_N(player2, 7);
		
		int winner;

		if (player1Val > player2Val)
		   winner = 1;
		else if (player1Val < player2Val)
		   winner = 2;
		else
		   winner = 0;

		return winner;
	}
コード例 #2
0
ファイル: calc.c プロジェクト: psmit/PeteOmaha
static inline void calc(int argc, char** argv) {   
    StdDeck_CardMask hole, board;
    StdDeck_CardMask card;
    StdDeck_CardMask_RESET(hole);
    StdDeck_CardMask_RESET(board);
    int i, cardi;
    
    for(i = 1; i < 5; ++i) {
       StdDeck_stringToCard(argv[i], &cardi); 
       card = StdDeck_MASK(cardi);
       StdDeck_CardMask_OR(hole, hole, card);
    }
    po_probs probs;
    probs = get_probs(hole, board);
    printf("%.4f", probs.win + probs.draw);
            
    if ( argc > 7) {
    for(i = 5; i < 8; ++i) {
       StdDeck_stringToCard(argv[i], &cardi); 
       card = StdDeck_MASK(cardi);
       StdDeck_CardMask_OR(board, board, card);
    }
    probs = get_probs(hole, board);
    printf(" %.4f", probs.win + probs.draw);
    }
    
    if ( argc > 8) {
        i = 8;
       StdDeck_stringToCard(argv[i], &cardi); 
       card = StdDeck_MASK(cardi);
       StdDeck_CardMask_OR(board, board, card);
    
    probs = get_probs(hole, board);
    printf(" %.4f", probs.win + probs.draw);
    }
    
    if ( argc > 9) {
        i = 9;
       StdDeck_stringToCard(argv[i], &cardi); 
       card = StdDeck_MASK(cardi);
       StdDeck_CardMask_OR(board, board, card);
    
    probs = get_probs(hole, board);
    printf(" %.4f", probs.win + probs.draw);
    }
    
    
    
    
    printf("\n");
}
コード例 #3
0
	// Helper:
	// Given a string such as "AcKcQcJcTc" representing a poker hand,
	// return an StdDeck_CardMask representing that hand.	
	extern "C" StdDeck_CardMask TextToPokerEval(const char* strHand)
	{
	   StdDeck_CardMask theHand, theCard;
	   StdDeck_CardMask_RESET(theHand);

	   if (strHand && strlen(strHand))
	   {
		  int cardIndex = -1;
		  char* curCard = const_cast<char*>(strHand);

		  while (*curCard)
		  {
			 // Take the card text and convert it to an index (0..51)
			 StdDeck_stringToCard(curCard, &cardIndex); 
			 // Convert the card index to a mask
			 theCard = StdDeck_MASK(cardIndex);
			 // Add the card (mask) to the hand
			 StdDeck_CardMask_OR(theHand, theHand, theCard);
			 // Advance to the next card (if any)
			 curCard += 2;
		  }
	   }

	   return theHand;
	}
コード例 #4
0
ファイル: omaha_calc.c プロジェクト: psmit/PeteOmaha
static inline void calc_counts(StdDeck_CardMask my_hole, StdDeck_CardMask board, counts_t * counts, int num_trials) {
    HandVal my_value = calc_handval(my_hole, board);
    HandVal other_value;

    StdDeck_CardMask used_cards;
    StdDeck_CardMask other_hole;
    StdDeck_CardMask_OR(used_cards, my_hole, board);


    DECK_MONTECARLO_N_CARDS_D(StdDeck, other_hole, used_cards, 4, num_trials, {
        other_value = calc_handval(other_hole, board);
        if (my_value > other_value) counts->win += 1;
        else if (my_value == other_value) counts->draw += 1;
        else counts->loss += 1;
    });
コード例 #5
0
ファイル: Util.cpp プロジェクト: strikles/poker
CRank169To1326Utility::CRank169To1326Utility()
{
	/*
	*  
	*/

	GeneratePreflopHandRanks1326();

	for(int hc1=0, index1326=0; hc1<51; hc1++)
	{
		for(int hc2=hc1+1; hc2<52; hc2++, index1326++)	
		{
			card_mask_for_hand1326[index1326] = StdDeck_MASK(hc1);
			StdDeck_CardMask_OR(card_mask_for_hand1326[index1326], card_mask_for_hand1326[index1326], StdDeck_MASK(hc2));

			FillRanges(hc1, hc2, index1326);
		}
	}
}
コード例 #6
0
ファイル: enumtest7.c プロジェクト: Buzdygan/poker
int main( void )
{
  CardMask cards, cards1, peggedCards;
  HandVal handval1, handval2;
  EvxHandVal evxHandVal;

  StdDeck_CardMask_RESET(peggedCards);
  StdDeck_CardMask_SET(peggedCards, 
                       StdDeck_MAKE_CARD(StdDeck_Rank_ACE, 
                                         StdDeck_Suit_DIAMONDS));
  StdDeck_CardMask_SET(peggedCards, 
                       StdDeck_MAKE_CARD(StdDeck_Rank_ACE, 
                                         StdDeck_Suit_HEARTS));
  ENUMERATE_5_CARDS_D(cards, peggedCards, 
                    {
                      StdDeck_CardMask_OR(cards1, cards, peggedCards);
                      handval1 = Hand_EVAL_N(cards1, 7);
                      evxHandVal = Hand_EVAL_X7(CardMask_CLUBS(cards1), 
                                                CardMask_DIAMONDS(cards1),
                                                CardMask_HEARTS(cards1),
                                                CardMask_SPADES(cards1));
                      handval2 = EvxHandVal_toHandVal(evxHandVal);
                      if (handval1 != handval2)
                        {
                          fprintf(stderr, "eval_n() and eval_x7() disagree\n");
                          printf("0\n");
                          Deck_printMask(cards);                        
                          printf(": ");                                 
                          HandVal_print(handval1);                  
                          printf(", ");
                          HandVal_print(handval2);                  
                          printf("\n");                                 
                          exit(0);
                        }
		      printf("%d %d %d %d %d %d\n", 
			     HandVal_HANDTYPE(handval1),
			     HandVal_TOP_CARD(handval1),
			     HandVal_SECOND_CARD(handval1),
			     HandVal_THIRD_CARD(handval1),
			     HandVal_FOURTH_CARD(handval1),
			     HandVal_FIFTH_CARD(handval1));
                    });
コード例 #7
0
StdDeck_CardMask wrap_StdDeck_CardMask_OR(StdDeck_CardMask op1, StdDeck_CardMask op2) { StdDeck_CardMask_OR(op1, op1, op2); return op1; } 
コード例 #8
0
ファイル: Logic_Knn.cpp プロジェクト: strikles/poker
void CKnnLogic::FillHandInfoStruct(int* hand)
{
	bool	new_hand, new_street, new_bet;

	hand[eDim_handId] = current_hand_id;

	/////////////////////////////
	// NEW HAND / STREET / BET //
	/////////////////////////////
	new_hand = new_street = new_bet = false;

	// New Hand
	if(gVars.get_dealerchair() != prev_dealer)	
	{
		new_hand = true;
		hand[eDim_isNew] = 1;
	}
	// New street
	else if(gVars.get_betround() != prev_br)
	{
		new_street = true;
		hand[eDim_isNew] = 2;
	}
	// New bet
	else if(prev_ntimesacted != gVars.ntimesacted)
	{
		new_bet	= true;
		hand[eDim_isNew] = 3;
	}
	// initialize hero_actions
	if(new_hand || new_street)
	{
		for(int i = 0; i < k_max_actions; i++)
			hero_actions[i] = eBet_Unknown;
	}

	hand[eDim_brNdx] = BR2NDX(gVars.get_betround());
	assert(ePreflopIndex <= hand[eDim_brNdx] && eRiverIndex >= hand[eDim_brNdx]);

	hand[eDim_timesActed] = min(gVars.ntimesacted,3);
	// save hero_actions to hand_info struct
	for(int i = 0; i < k_max_actions; i++)
		hand[eDim_Action1+i] = hero_actions[i];
	
	hand[eDim_HS] = 100 * (hand[eDim_InHand] > 0 && hand[eDim_InHand] < k_max_chairs ? hand[eDim_InHand] : 1) * gVars.get_prwin();  //0..1
	hand[eDim_Raises] = gVars.get_nopponentsraising();

	/////////////////////////////////////////////////
	//Save data normalized on the interval 0..1000://
	/////////////////////////////////////////////////
	
	// save hand169 to hand_info struct
	if(ePreflopIndex == hand[eDim_brNdx])
	{
		hand[eDim_PPot] = 0;
		hand[eDim_NPot] = 0;
	}
	else
	{
		// Calc hand potentials
		if(eRiverIndex != hand[eDim_brNdx])
		{
			// Generate card masks
			StdDeck_CardMask hero_cards = {0}, board_cards = {0};
			for(int i = 0; i < 2; i++)
			{
				int card = StdDeck_MAKE_CARD(gVars.Bot_Common_Cards[i][0]-2, ConvertSuitsForPokerEval[gVars.Bot_Common_Cards[i][1]]);
				StdDeck_CardMask_OR(hero_cards, hero_cards, StdDeck_MASK(card));
				//gLog.WriteLog(eSeverityDebug, eCatHandPotential, "Player Card: %d\n", card);
			}
			for(int i = 0; i < (1 + gVars.get_betround()); i++)
			{
				int card = StdDeck_MAKE_CARD(gVars.Bot_Common_Cards[2+i][0]-2, ConvertSuitsForPokerEval[gVars.Bot_Common_Cards[2+i][1]]);
				StdDeck_CardMask_OR(board_cards, board_cards, StdDeck_MASK(card));
				//gLog.WriteLog(eSeverityDebug, eCatHandPotential, "Board Card: %d\n", card);
			}

			// calculate potentials
			// Shouldn't this calc be moved to the server ?
			CHandPotential hp(hero_cards, board_cards);
			hp.CalcPotentials();

			// save potentials to hand_info struct
			hand[eDim_PPot]= (int)(100*hp.Ppot); //0..1
			hand[eDim_NPot] = (int)(100*hp.Npot); //0..1
		}
		else
		{
			// no such thing as ppot/npot in the river
			hand[eDim_PPot] = 0;
			hand[eDim_NPot] = 0;
		}
	}

	hand[eDim_InHand]	= gVars.nplayersplaying; //1..6 /4
	// replace me !!!
	hand[eDim_Dealt]	= gVars.get_nplayersdealt(); //1..6 /4
	// replace me !!!
	hand[eDim_ToAct]	= gVars.m_state.LeftToAct(gVars.userchair); //1..6 /4
	// replace me !!!
	hand[eDim_Balance]	= (int)(gVars.balance[gVars.userchair]); //0..+-400
	hand[eDim_InitialBalance]	= (int)(gVars.initial_balance[gVars.userchair]); //0..+-400

	hand[eDim_Call]		= (int)(gVars.call); //0..+-400
	hand[eDim_Pot]		= (int)(gVars.get_pot()); //0..+-800
}
コード例 #9
0
static PyObject*
eval_hand(PyObject* self, PyObject *args)
{
  PyObject* result = 0;
  char* hilow_string = 0;
  PyObject* pyhand = 0;
  PyObject* pyboard = 0;
  int low = 0;
  CardMask hand;
  CardMask board;
  int board_size = 0;
  CardMask best;
  HandVal best_handval;

  StdDeck_CardMask_RESET(best);

  if (!PyArg_ParseTuple(args, "sOO", &hilow_string, &pyhand, &pyboard))
    return NULL;

  if(!strcmp(hilow_string, "low"))
    low = 1;

  if(PyList2CardMask(pyhand, &hand) < 0)
    return NULL;

  board_size = PyList2CardMask(pyboard, &board);

  if(board_size > 0) {
    CardMask hicards;
    CardMask locards;
    HandVal  hival = 0;
    HandVal  loval = 0;
    StdDeck_CardMask_RESET(hicards);
    StdDeck_CardMask_RESET(locards);
    OmahaHiLow8_Best(hand, board, &hival, &loval, &hicards, &locards);
    if(low) {
      best_handval = loval;
      if(best_handval != LowHandVal_NOTHING)
	best = locards;
    } else {
      best = hicards;
      best_handval = hival;
    }
  } else {
    CardMask cards;
    CardMask dead;

    StdDeck_CardMask_RESET(best);

    StdDeck_CardMask_RESET(dead);
    StdDeck_CardMask_OR(dead, dead, hand);
    StdDeck_CardMask_NOT(dead, dead);

    if(low) {
      best_handval = LowHandVal_NOTHING;
    } else {
      best_handval = HandVal_NOTHING;
    }

    ENUMERATE_N_CARDS_D(cards, 5, dead,
    {
      HandVal handval;

      if(low) {
	handval = Hand_EVAL_LOW8(cards, 5);
      } else {
	handval = Hand_EVAL_N(cards, 5);
      }

      if(low ? (handval < best_handval) : (handval > best_handval)) {
	best = cards;
	best_handval = handval;
      }
    }
			);
コード例 #10
0
static int
OmahaHiLow8_Best(StdDeck_CardMask hole, StdDeck_CardMask board,
		 HandVal *hival, LowHandVal *loval,
		 StdDeck_CardMask *hicards, StdDeck_CardMask *locards) {
  StdDeck_CardMask allcards;
  LowHandVal allval;
  HandVal curhi, besthi;
  LowHandVal curlo, bestlo;
  StdDeck_CardMask hole1[OMAHA_MAXHOLE];
  StdDeck_CardMask board1[OMAHA_MAXBOARD];
  StdDeck_CardMask n1, n2, n3, n4, n5;
  int nhole, nboard;
  int eligible = 0;
  int i, h1, h2, b1, b2, b3;

  /* pluck out individual cards from hole and board masks, save in arrays */
  nhole = nboard = 0;
  for (i=0; i<StdDeck_N_CARDS; i++) {
    if (StdDeck_CardMask_CARD_IS_SET(hole, i)) {
      if (nhole >= OMAHA_MAXHOLE)
        return 1;                               /* too many hole cards */
      StdDeck_CardMask_RESET(hole1[nhole]);
      StdDeck_CardMask_SET(hole1[nhole], i);
      nhole++;
    }
    if (StdDeck_CardMask_CARD_IS_SET(board, i)) {
      if (StdDeck_CardMask_CARD_IS_SET(hole, i)) /* same card in hole and board */
        return 2;
      if (nboard >= OMAHA_MAXBOARD)
        return 3;                               /* too many board cards */
      StdDeck_CardMask_RESET(board1[nboard]);
      StdDeck_CardMask_SET(board1[nboard], i);
      nboard++;
    }
  }

  if (nhole < OMAHA_MINHOLE || nhole > OMAHA_MAXHOLE)
    return 4;                                   /* wrong # of hole cards */
  if (nboard < OMAHA_MINBOARD || nboard > OMAHA_MAXBOARD)
    return 5;                                   /* wrong # of board cards */

  /* quick test in case no low is possible with all 9 cards */
  if (loval != NULL) {
    StdDeck_CardMask_OR(allcards, hole, board);
    allval = StdDeck_Lowball8_EVAL(allcards, nhole + nboard);
    eligible = (allval != LowHandVal_NOTHING);
  }

  /* loop over all combinations of hole with board (60 for 4 hole cards
     and 5 board cards). */
  besthi = HandVal_NOTHING;
  bestlo = LowHandVal_NOTHING;
  /* {h1,h2} loop over all hole card combinations */
  for (h1=0; h1<nhole-1; h1++) {
    StdDeck_CardMask_RESET(n1);
    StdDeck_CardMask_OR(n1, n1, hole1[h1]);
    for (h2=h1+1; h2<nhole; h2++) {
      StdDeck_CardMask_OR(n2, n1, hole1[h2]);
      /* {b1,b2,b3} loop over all board card combinations */
      for (b1=0; b1<nboard-2; b1++) {
        StdDeck_CardMask_OR(n3, n2, board1[b1]);
        for (b2=b1+1; b2<nboard-1; b2++) {
          StdDeck_CardMask_OR(n4, n3, board1[b2]);
          for (b3=b2+1; b3<nboard; b3++) {
            if (hival != NULL) {
              StdDeck_CardMask_OR(n5, n4, board1[b3]);
              curhi = StdDeck_StdRules_EVAL_N(n5, 5);
              if (curhi > besthi || besthi == HandVal_NOTHING) {
                besthi = curhi;
		*hicards = n5;
	      }
            }
            if (loval != NULL && eligible) {
              curlo = StdDeck_Lowball8_EVAL(n5, 5);
              if (curlo < bestlo || bestlo == LowHandVal_NOTHING) {
                bestlo = curlo;
		*locards = n5;
	      }
            }
          }
        }
      }
    }
  }
  if (hival != NULL) *hival = besthi;
  if (loval != NULL) *loval = bestlo;
  return 0;
}
コード例 #11
0
static int
pyenumSample(enum_game_t game, StdDeck_CardMask pockets[],
		 int numToDeal[],
               StdDeck_CardMask board, StdDeck_CardMask dead,
               int sizeToDeal, int iterations, enum_result_t *result) {
  int i;
  enumResultClear(result);
  StdDeck_CardMask cardsDealt[ENUM_MAXPLAYERS + 1];
  memset(cardsDealt, 0, sizeof(StdDeck_CardMask) * (ENUM_MAXPLAYERS + 1));
  if (sizeToDeal - 1 > ENUM_MAXPLAYERS)
    return 1;

  /*
   * Cards in pockets or in the board must not be dealt
   */
  StdDeck_CardMask_OR(dead, dead, board);
  for(i = 0; i < sizeToDeal - 1; i++) {
    StdDeck_CardMask_OR(dead, dead, pockets[i]);
  }

  if (game == game_holdem) {
    DECK_MONTECARLO_PERMUTATIONS_D(StdDeck, cardsDealt,
				   sizeToDeal, numToDeal,
				   dead, iterations, INNER_LOOP_ANY_HIGH);
  } else if (game == game_holdem8) {
    DECK_MONTECARLO_PERMUTATIONS_D(StdDeck, cardsDealt,
				   sizeToDeal, numToDeal,
				   dead, iterations, INNER_LOOP_ANY_HILO);
  } else if (game == game_omaha) {
    DECK_MONTECARLO_PERMUTATIONS_D(StdDeck, cardsDealt,
				   sizeToDeal, numToDeal,
				   dead, iterations, INNER_LOOP_OMAHA);
  } else if (game == game_omaha8) {
    DECK_MONTECARLO_PERMUTATIONS_D(StdDeck, cardsDealt,
				   sizeToDeal, numToDeal,
				   dead, iterations, INNER_LOOP_OMAHA8);
  } else if (game == game_7stud) {
    DECK_MONTECARLO_PERMUTATIONS_D(StdDeck, cardsDealt,
				   sizeToDeal, numToDeal,
				   dead, iterations, INNER_LOOP_ANY_HIGH);
  } else if (game == game_7stud8) {
    DECK_MONTECARLO_PERMUTATIONS_D(StdDeck, cardsDealt,
				   sizeToDeal, numToDeal,
				   dead, iterations, INNER_LOOP_ANY_HILO);
  } else if (game == game_7studnsq) {
    DECK_MONTECARLO_PERMUTATIONS_D(StdDeck, cardsDealt,
				   sizeToDeal, numToDeal,
				   dead, iterations, INNER_LOOP_7STUDNSQ);
  } else if (game == game_razz) {
    DECK_MONTECARLO_PERMUTATIONS_D(StdDeck, cardsDealt,
				   sizeToDeal, numToDeal,
				   dead, iterations, INNER_LOOP_RAZZ);
  } else if (game == game_lowball27) {
    DECK_MONTECARLO_PERMUTATIONS_D(StdDeck, cardsDealt,
				   sizeToDeal, numToDeal,
				   dead, iterations, INNER_LOOP_LOWBALL27);
  } else {
    return 1;
  }

  result->game = game;
  result->nplayers = sizeToDeal - 1;
  result->sampleType = ENUM_SAMPLE;
  return 0;
}
コード例 #12
0
static int
pyenumExhaustive(enum_game_t game, StdDeck_CardMask pockets[],
		 int numToDeal[],
               StdDeck_CardMask board, StdDeck_CardMask dead,
               int sizeToDeal, enum_result_t *result) {
  int totalToDeal = 0;
  int i;
  enumResultClear(result);
  StdDeck_CardMask cardsDealt[ENUM_MAXPLAYERS + 1];
  memset(cardsDealt, 0, sizeof(StdDeck_CardMask) * (ENUM_MAXPLAYERS + 1));
  if (sizeToDeal - 1 > ENUM_MAXPLAYERS)
    return 1;
  for(i = 0; i < sizeToDeal; i++)
    totalToDeal += numToDeal[i];

  /*
   * Cards in pockets or in the board must not be dealt
   */
  StdDeck_CardMask_OR(dead, dead, board);
  for(i = 0; i < sizeToDeal - 1; i++) {
    StdDeck_CardMask_OR(dead, dead, pockets[i]);
  }

  if (game == game_holdem) {
    if(totalToDeal > 0) {
      DECK_ENUMERATE_COMBINATIONS_D(StdDeck, cardsDealt,
				    sizeToDeal, numToDeal,
				    dead, INNER_LOOP_ANY_HIGH);
    } else {
      INNER_LOOP_ANY_HIGH;
    }
  } else if (game == game_holdem8) {
    if(totalToDeal > 0) {
      DECK_ENUMERATE_COMBINATIONS_D(StdDeck, cardsDealt,
				    sizeToDeal, numToDeal,
				    dead, INNER_LOOP_ANY_HILO);
    } else {
      INNER_LOOP_ANY_HILO;
    }
  } else if (game == game_omaha) {
    if(totalToDeal > 0) {
      DECK_ENUMERATE_COMBINATIONS_D(StdDeck, cardsDealt,
				    sizeToDeal, numToDeal,
				    dead, INNER_LOOP_OMAHA);
    } else {
      INNER_LOOP_OMAHA;
    }
  } else if (game == game_omaha8) {
    if(totalToDeal > 0) {
      DECK_ENUMERATE_COMBINATIONS_D(StdDeck, cardsDealt,
				    sizeToDeal, numToDeal,
				    dead, INNER_LOOP_OMAHA8);
    } else {
      INNER_LOOP_OMAHA8;
    }
  } else if (game == game_7stud) {
    if(totalToDeal > 0) {
      DECK_ENUMERATE_COMBINATIONS_D(StdDeck, cardsDealt,
				    sizeToDeal, numToDeal,
				    dead, INNER_LOOP_ANY_HIGH);
    } else {
      INNER_LOOP_ANY_HIGH;
    }
  } else if (game == game_7stud8) {
    if(totalToDeal > 0) {
      DECK_ENUMERATE_COMBINATIONS_D(StdDeck, cardsDealt,
				    sizeToDeal, numToDeal,
				    dead, INNER_LOOP_ANY_HILO);
    } else {
      INNER_LOOP_ANY_HILO;
    }
  } else if (game == game_7studnsq) {
    DECK_ENUMERATE_COMBINATIONS_D(StdDeck, cardsDealt,
                                  sizeToDeal, numToDeal,
                                  dead, INNER_LOOP_7STUDNSQ);
  } else if (game == game_razz) {
    DECK_ENUMERATE_COMBINATIONS_D(StdDeck, cardsDealt,
                                  sizeToDeal, numToDeal,
                                  dead, INNER_LOOP_RAZZ);
  } else if (game == game_lowball27) {
    DECK_ENUMERATE_COMBINATIONS_D(StdDeck, cardsDealt,
                                  sizeToDeal, numToDeal,
                                  dead, INNER_LOOP_LOWBALL27);
  } else {
    return 1;
  }

  result->game = game;
  result->nplayers = sizeToDeal - 1;
  result->sampleType = ENUM_EXHAUSTIVE;
  return 0;
}
コード例 #13
0
ファイル: poker_eval.c プロジェクト: cubesystems/poker_eval
static VALUE
t_eval_hand(VALUE self, VALUE args)
{
  VALUE result = 0;
  VALUE rbboard = 0;
  VALUE rbhand = 0;
  char* hilow_string = 0;

  hilow_string = RSTRING_PTR(rb_hash_aref(args, rb_str_new2("side")));
  rbboard = rb_hash_aref(args, rb_str_new2("board"));
  rbhand = rb_hash_aref(args, rb_str_new2("hand"));

  int low = 0;
  CardMask hand;
  CardMask board;
  int board_size = 0;
  CardMask best;
  HandVal best_handval;

  StdDeck_CardMask_RESET(best);

  if(!strcmp(hilow_string, "low")) {
    low = 1;
  }

  if(rbList2CardMask(rbhand, &hand) < 0)
    rb_fatal("empty hand given");

  if( !NIL_P(rbboard))
  {
    board_size = rbList2CardMask(rbboard, &board);
  }

  if(board_size > 0) {
    CardMask hicards;
    CardMask locards;
    HandVal  hival = 0;
    HandVal  loval = 0;
    StdDeck_CardMask_RESET(hicards);
    StdDeck_CardMask_RESET(locards);
    OmahaHiLow8_Best(hand, board, &hival, &loval, &hicards, &locards);
    if(low) {
      best_handval = loval;
      if(best_handval != LowHandVal_NOTHING)
	best = locards;
    } else {
      best = hicards;
      best_handval = hival;
    }
  } else {
    CardMask cards;
    CardMask dead;

    StdDeck_CardMask_RESET(best);

    StdDeck_CardMask_RESET(dead);
    StdDeck_CardMask_OR(dead, dead, hand);
    StdDeck_CardMask_NOT(dead, dead);

    if(low) {
      best_handval = LowHandVal_NOTHING;
    } else {
      best_handval = HandVal_NOTHING;
    }

    ENUMERATE_N_CARDS_D(cards, 5, dead, 
    {
      HandVal handval;

      if(low) {
	handval = Hand_EVAL_LOW8(cards, 5);
      } else {
	handval = Hand_EVAL_N(cards, 5);
      }

      if(low ? (handval < best_handval) : (handval > best_handval)) {
	best = cards;
	best_handval = handval;
      }
    }
			);