Example #1
0
        public ApproximationResults Approximate(CardCollection deadCards, params Range[] ranges)
        {
            var allApprox = ranges.Select(r => r.SelectedHoleCardBinaries
                                          .Where(b => !_cards.ContainsSome(b) && (deadCards == null || !deadCards.ContainsSome(b))))
                            .CartesianProduct()
                            .Select(s => Approximate(s.ToArray(), deadCards, trials: 100))
                            .ToList();

            var   players   = new List <float>(new float[ranges.Length]);
            float splitProb = 0f;

            foreach (var approx in allApprox)
            {
                splitProb += approx.SplitProbability;
                for (int p = 0; p < ranges.Length; p++)
                {
                    players[p] += approx[p].Equity;
                }
            }
            players.ForEach(p => p /= allApprox.Count);
            splitProb /= allApprox.Count;

            return(new ApproximationResults(players.Select((eq, i) => new ApproximationResults.PlayerResults(i, eq, 3UL)), splitProb)); // Todo: add ranges to result
        }
 /// <summary>
 /// A collection of all possible hole cards which include one or more cards from a card collection with optional dead cards.
 /// </summary>
 /// <param name="card"></param>
 /// <param name="deadCards">Dead cards. If no dead cards needed leave it null</param>
 public static IEnumerable <HoleCards> Include(CardCollection includedCards, CardCollection deadCards = null) =>
 Include((ulong)includedCards, (ulong)deadCards);
Example #3
0
 public bool ContainsSome(CardCollection collection)
 {
     return((Binary & collection.Binary) != 0UL);
 }
Example #4
0
 public bool Contains(CardCollection collection)
 {
     return((Binary & collection.Binary) == collection.Binary);
 }
Example #5
0
 public void Exclude(CardCollection collection)
 {
     Binary &= ~collection.Binary;
 }
Example #6
0
 public void Include(CardCollection collection)
 {
     Binary |= collection.Binary;
 }
Example #7
0
 public static IEnumerable <CardCollection> Include(int cardAmount, CardCollection includedCards, CardCollection excludedCards = null)
 {
     return(Include(cardAmount, includedCards.Binary, excludedCards.Binary).Select(cc => new CardCollection(cc)));
     //return All(cardAmount, excludedCards).Where(cc => cc.Contains(includedCards));
 }
Example #8
0
 public static IEnumerable <CardCollection> All(int cardAmount, CardCollection excludedCards = null)
 {
     return(All(cardAmount, (ulong)excludedCards).Select(cc => new CardCollection(cc)));
 }
 /// <summary>
 /// Get the notation of a card collection
 /// </summary>
 /// <returns>String representation of the card collection, e.g. "Ac Th 6s "</returns>
 public static string GetNotation(CardCollection collection)
 {
     return(GetNotation(collection.Binary));
 }
Example #10
0
 /// <summary>
 /// Creates a random board.
 /// </summary>
 /// <param name="progress">The progression of the board. Specifies how many cards are on the board.</param>
 /// <param name="deadCards">Dead cards. Specifies all cards that can't be contained on the board such as hole cards or boxed cards.</param>
 /// <returns>A random board according to the parameters</returns>
 public static Board Random(Progression progress = Progression.River, CardCollection deadCards = null)
 {
     return(new Board(CardCollection.RandomAsUlong((int)progress, deadCards)));
 }
Example #11
0
 internal void DealRandomCards(Progression targetState, ulong deadCards = 0UL)
 {
     _cards.Include(CardCollection.RandomAsUlong(targetState - Progress, deadCards | _cards.Binary));
 }
Example #12
0
 /// <summary>
 /// Calculates equity for two or more hole cards on the board by checking all possible outcomes. No splits considered
 /// </summary>
 /// <param name="holeCards">The list of hole cards to evaluate the equity for</param>
 /// <returns>A list of player approximation results</returns>
 public ApproximationResults ApproximateExact(CardCollection deadCards, params HoleCards[] holeCards) =>
 ApproximateExact(deadCards, Array.ConvertAll(holeCards, hc => (ulong)hc));
Example #13
0
        public void ApproximateLive(Action <IEnumerable <float>, float> updateLiveResults, CardCollection deadCards, CancellationToken?cancellationToken, params Range[] ranges)
        {
            var rnd          = new Random();
            var nativeRanges = ranges.Select(r => r.SelectedHoleCardBinaries.Where(b => !_cards.ContainsSome(b) && (!deadCards?.ContainsSome(b) ?? true)).ToList()).ToList();

            cancellationToken?.ThrowIfCancellationRequested();


            ulong[]? localHoleCards = new ulong[nativeRanges.Count];
            ulong allLocalHoleCards;

            float[]? totalEquity = new float[nativeRanges.Count];
            float splitEquity = 0f;

            int  firstSelectedPlayer = 0;
            int  skippedSituations   = 0;
            bool skipSituation       = false;

            for (int i = 0; i < Int32.MaxValue; i++)
            {
                // Stop if requested
                cancellationToken?.ThrowIfCancellationRequested();

                allLocalHoleCards = 0;
                // Select random hole cards from each player to test
                // Do not select from the same player first every time,
                // the equities can be affected by this (e.g. AA-KK vs AA-KK vs AA-KK)
                int j = firstSelectedPlayer;
                do
                {
                    var validHoleCards = nativeRanges[j].Where(hc => (hc & allLocalHoleCards) == 0).ToList();

                    if (!validHoleCards.Any())
                    {
                        if (skippedSituations > (i < 1000 ? 950 : i * 0.95f))
                        {
                            throw new NashException("Ranges are too narrow. Please adjust.");
                        }
                        skipSituation = true;
                        break;
                    }

                    localHoleCards[j]  = validHoleCards[rnd.Next(validHoleCards.Count)];
                    allLocalHoleCards |= localHoleCards[j];

                    // if the last player is reached wrap around to the first one
                    if (++j >= nativeRanges.Count)
                    {
                        j = 0;
                    }
                } while (j != firstSelectedPlayer);

                // skip this situation if not all hole cards were chosen
                // try with same first player to not influence the results
                if (skipSituation)
                {
                    skippedSituations++;
                    skipSituation = false;
                    continue;
                }

                // update first player for next run
                if (++firstSelectedPlayer >= nativeRanges.Count)
                {
                    firstSelectedPlayer = 0;
                }

                // Add to total equity
                var results = Approximate(localHoleCards, deadCards, trials: 1000);
                for (int k = 0; k < nativeRanges.Count; k++)
                {
                    totalEquity[k] += results[k].Equity;
                }
                splitEquity += results.SplitProbability;

                // Update live results
                if (i % 10 == 0)
                {
                    int simulationCount = (i - skippedSituations + 1);
                    updateLiveResults?.Invoke(totalEquity.Select(eq => Math.Min(eq / simulationCount, 1f)), Math.Min(splitEquity / simulationCount, 1f));
                }
            }
        }
Example #14
0
 public Board()
 {
     _cards = new CardCollection();
 }
Example #15
0
            /// <summary>
            /// Get all possible boards on a specific street and specific included cards
            /// </summary>
            /// <param name="progress">The street of the board</param>
            /// <param name="includedCards">Every board must contain all of these cards</param>
            /// <param name="deadCards">All boards containing one or more cards from this parameter will be excluded</param>
            /// <returns>A list of boards according to the parameters</returns>
            public static IEnumerable <Board> Include(Progression progress, CardCollection includedCards, CardCollection deadCards = null)
            {
#if DEBUG
                if (includedCards.Count > (int)progress)
                {
                    throw new ArgumentException("There can't be more cards included than are dealt on the current progression of the board.", nameof(includedCards));
                }
#endif

                return(Include((int)progress, includedCards, deadCards).Select(cc => new Board(cc)));
            }
Example #16
0
 public static IEnumerable <Board> All(Progression progress, CardCollection deadCards = null) =>
 All((int)progress, deadCards).Select(cc => new Board(cc));