title: Poker odds application gives inaccurate values for odds percentage
body: <p>The application is supposed to provide what %  a given pair of cards will win a round of 1v1 Texas Hold'em Poker. Basically generating all random hole cards for the opponent (given my own hole cards, and the (potential) cards on the table), and then generating from that all possible 5-card combinations on the table at showdown. Then it checks whether me or the opponent will win, given the 5-card hand. I have already checked hand evaluation, and that seems to work. So the problem seems to be the bot &quot;algorithm&quot;. The odds percentages are wrong usually by 2-10% and I know this because I checked against an application with similiar purpose.</p>
  <pre><code>public static (int mainScore, long tieBreaker) HandToPlay(ulong holes, ulong cardsOnTable) //what hand someone gets at the end of the round, when all 5 cards are exposed
          {
              if (_handTable.TryGetValue((holes, cardsOnTable), out (int, long) value)) //lookup table
              {
                  return value;
              }
  
              (int mainScore, long tieBreaker) max = (-100000, -100000);
  
              foreach(var combo in CardCombos(cardsOnTable.ToIEnum(), 3)) //pick 3 cards of all the cards on the table
              {
                  (int mainScore, long tieBreaker) currentScore = GetFullScore(combo | holes); //add the 2 hole cards for a 5 card hand
                  if ((currentScore.mainScore.CompareTo(max.mainScore) != 0 ? currentScore.mainScore.CompareTo(max.mainScore) : currentScore.tieBreaker.CompareTo(max.tieBreaker)) &gt; 0) //if current hand has higher score than the last
                  {
  
  
                      max = currentScore;
  
                  }
  
              }
              foreach (var combo in CardCombos(cardsOnTable.ToIEnum(), 4)) //pick 4 cards of all the cards on the table
              {
                  foreach (ulong holeCard in holes.ToIEnum()) //add one of the hole cards for a 5 card hand
                  {
                      (int mainScore, long tieBreaker) currentScore = GetFullScore(combo | holeCard);
                      if ((currentScore.mainScore.CompareTo(max.mainScore) != 0 ? currentScore.mainScore.CompareTo(max.mainScore) : currentScore.tieBreaker.CompareTo(max.tieBreaker)) &gt; 0)
                      {
  
                          {
                              max = currentScore;
  
                          }
  
                      }
                  }
              }
             
                  _handTable[(holes, cardsOnTable)] = max; //add to lookup table
              
              return max;
          }
  </code></pre>
  <pre><code>private static (double heroPoints, double villainPoints) updateScore(ulong holes, ulong villainHoles, ulong currentHand)
          {
              (int mainScore, long tieBreaker) heroHand = HandEvaluation.HandToPlay(holes, currentHand); //what hand the player plays given the 5 cards on the board at showdown
              (int mainScore, long tieBreaker) villainHand = HandEvaluation.HandToPlay(villainHoles, currentHand);//what hand the opponent plays given the 5 cards on the board at showdown
              switch (heroHand.mainScore.CompareTo(villainHand.mainScore) != 0 ? heroHand.mainScore.CompareTo(villainHand.mainScore) : heroHand.tieBreaker.CompareTo(villainHand.tieBreaker)) //which hand has highest score
              {
                  case 1:
                      return (1, 0); //player gets one point if their card best
                  case -1:
                      return (0, 1); //villain gets one point if their card best
                  default:
                      return (0.5, 0.5); //both get half points if tie
              }
  
          }
  </code></pre>
  <pre><code>  public static double GetOdds(List&lt;KeyValuePair&lt;int, int&gt;&gt; holeCardsKvpList, List&lt;KeyValuePair&lt;int, int&gt;&gt; tableKvpList)
          {
             
              double heroWins = 0;
              double villainWins = 0;
              ulong holes = HandEvaluation.ParseAsBitField(holeCardsKvpList); //hand eval stuff, turn list of cards into binary (performance reasons)
              ulong communityCards = HandEvaluation.ParseAsBitField(tableKvpList); //hand eval stuff, turn list of cards into binary (performance reasons)
              ulong availableCards = HandEvaluation.Deck ^ (holes | communityCards); //all cards in deck (removing own hole cards and the given cards at the table (own input value) from the 52-card deck)
              foreach (var villainHoles in HandEvaluation.CardCombos(availableCards.ToIEnum(), 2))//every combination of cards our opponent may have
              {
  
                  ulong currentAvailableCards = availableCards ^ villainHoles; //hypothetical deck with opponent's cards removed
                  if (tableKvpList.Count &lt; 5) //if all 5 cards arent on table yet
                  {
                      foreach (var cardAdditions in HandEvaluation.CardCombos(currentAvailableCards.ToIEnum(), 5 - tableKvpList.Count))//all combinations of cards that may be added to the existing table
                      {
  
                          ulong currentHand = communityCards | cardAdditions; //the hypothetical 5 cards on the table given the combination
                          (double heroPoints, double villainPoints) scoreUpdate = updateScore(holes, villainHoles, currentHand);
  
                          heroWins += scoreUpdate.heroPoints;
                          villainWins += scoreUpdate.villainPoints;
    
                      }
                  }
                  else //if all 5 cards are on table (showdown)
                  {
  
                      (double heroPoints, double villainPoints) scoreUpdate = updateScore(holes, villainHoles, communityCards);
  
                      heroWins += scoreUpdate.heroPoints;
                      villainWins += scoreUpdate.villainPoints;
  
                  }
  
  
              }
  
              return heroWins / (heroWins + villainWins);
  
          }
  </code></pre>