Example #1
0
        public void BuildStatistic()
        {
            CardValue[] card_values = Enum.GetValues(typeof(CardValue)).OfType<CardValue>().ToArray();

            Func<Card, Card, int, int, int, double> func =
                (Card card1, Card card2, int gameNumber, int parallelLevel, int enemyCount) =>
                {
                    var parameters = new CalculationParameters();

                    parameters.PlayerCard1 = card1;
                    parameters.PlayerCard2 = card2;

                    parameters.GameNumber = gameNumber;
                    parameters.ParallelLevel = parallelLevel;
                    parameters.EnemyPlayersCount = enemyCount;

                    var psc = new PokerStatisticCalc();
                    Statistic stat = psc.RunExperiment(parameters);
                    return Math.Round(stat.Win * 100d / stat.GameNumber, 2);
                };

            for (int enemy = 1; enemy <= MaxEnemyCount; enemy++)
            {
                double min = int.MaxValue;
                double max = int.MinValue;

                var table = new List<KeyValuePair<CardValue, List<Tuple<CardValue, double, double>>>>();

                for (int i = 0; i < card_values.Length; i++)
                {
                    var line = new List<Tuple<CardValue, double, double>>();

                    for (int j = 0; j < card_values.Length; j++)
                    {
                        double d1 = func(
                            new Card(CardSuit.Clubs, card_values[i]),
                            new Card(CardSuit.Hearts, card_values[j]),
                            GameCount,
                            ParallellLevel,
                            enemy);

                        min = Math.Min(min, d1);
                        max = Math.Max(max, d1);

                        double d2 = -1;
                        if (i != j)
                        {
                            d2 = func(
                                new Card(CardSuit.Clubs, card_values[i]),
                                new Card(CardSuit.Clubs, card_values[j]),
                                GameCount,
                                ParallellLevel,
                                enemy);

                            min = Math.Min(min, d2);
                            max = Math.Max(max, d2);
                        }

                        line.Add(Tuple.Create(card_values[j], d1, d2));
                    }

                    table.Add(new KeyValuePair<CardValue, List<Tuple<CardValue, double, double>>>(card_values[i], line));
                }

                var make_rel = new Func<double, double, double, double>(
                    (double mmin, double mmax, double val) =>
                    {
                        double range = mmax - mmin;
                        double d1 = (val - mmin) / range; // [0;1]
                        return d1;
                        //double rel = mmax / mmin;
                        //return 1 + d1 * rel;
                    });

                var lines = new List<List<string>>();
                var lines2 = new List<List<string>>();
                foreach (var item in table)
                {
                    var nodes = new List<string>();
                    var nodes2 = new List<string>();
                    foreach (var item2 in item.Value)
                    {
                        nodes.Add("{0}{1} - {2} ({3})".FormatStr(
                            CardUtils.ConvertToString(item.Key),
                            CardUtils.ConvertToString(item2.Item1),
                            item2.Item2,
                            (item2.Item3 == -1 ? "-" : item2.Item3.ToString())));

                        nodes2.Add("{0}{1} - {2:0.####} ({3})".FormatStr(
                            CardUtils.ConvertToString(item.Key),
                            CardUtils.ConvertToString(item2.Item1),
                            make_rel(min, max, item2.Item2),
                            (item2.Item3 == -1 ? "-" : make_rel(min, max, item2.Item3).ToString("0.####"))));
                    }

                    lines.Add(nodes);
                    lines2.Add(nodes2);
                }

                int maxLength = lines.Select(x => x.Max(y => y.Length)).Max();
                int maxLength2 = lines2.Select(x => x.Max(y => y.Length)).Max();

                for (int i = 0; i < lines.Count; i++)
                {
                    for (int j = 0; j < lines[i].Count; j++)
                    {
                        lines[i][j] = lines[i][j].PadRight(maxLength);
                        lines2[i][j] = lines2[i][j].PadRight(maxLength2);
                    }
                }

                string s = string.Join(Environment.NewLine, lines.Select(l => string.Join(" | ", l)));
                File.WriteAllText(FileNamePattern.FormatStr(enemy), s);

                string s2 = string.Join(Environment.NewLine, lines2.Select(l => string.Join(" | ", l)));
                File.WriteAllText(FileNamePattern2.FormatStr(enemy), s2);
            }
        }
Example #2
0
        private void SimulateGame(Card player_card1, Card player_card2, Card[] open_cards, Card[] free_cards, int enemyPlayersCount, StatisticInternal stat, CalculationParameters param)
        {
            var common_cards = new Card[5];
            Array.Copy(open_cards, common_cards, open_cards.Length);

            var cards_shuffled = new Card[free_cards.Length];
            Array.Copy(free_cards, cards_shuffled, free_cards.Length);
            Shuffle(cards_shuffled);

            int cards_shuffled_used_count = 0;

            if (open_cards.Length < 5)
            {
                int destinationIndex = open_cards.Length;
                int number_of_elements_to_copy = common_cards.Length - open_cards.Length;

                Array.Copy(cards_shuffled, 0, common_cards, destinationIndex, number_of_elements_to_copy);

                cards_shuffled_used_count = number_of_elements_to_copy;
            }

            OrderCards(common_cards);

            Card[] player_cards = AppendPreserveOrder(common_cards, player_card1, player_card2);
            bool[] player_cards_equality_by_value_helper = GetEqualityCardsByValueHelper(player_cards);
            IHand player_hand = GetStrongestHand(player_cards, player_cards_equality_by_value_helper, null);

            IHand enemy_stat_hand = null;
            PlayerHandResult player_stat_hand_result = PlayerHandResult.PlayerWin;
            PlayerHandResult player_hand_final_result = PlayerHandResult.PlayerWin;

            for (int enemyIndx = 0; enemyIndx < enemyPlayersCount; enemyIndx++)
            {
                Card enemy_card1 = cards_shuffled[cards_shuffled_used_count];
                cards_shuffled_used_count++;
                Card enemy_card2 = cards_shuffled[cards_shuffled_used_count];
                cards_shuffled_used_count++;

                Card[] enemy_cards = AppendPreserveOrder(common_cards, enemy_card1, enemy_card2);
                bool[] enemy_cards_equality_by_value_helper = GetEqualityCardsByValueHelper(enemy_cards);
                IHand enemy_hand = GetStrongestHand(enemy_cards, enemy_cards_equality_by_value_helper, (enemyIndx > 0 ? player_hand : null));

                if (enemyIndx == 0)
                {
                    enemy_stat_hand = enemy_hand;
                }

                PlayerHandResult player_hand_result = (enemy_hand != null) ?
                    HandHelper.ComparePlayerHand(player_hand, enemy_hand) : PlayerHandResult.PlayerWin;

                switch (player_hand_result)
                {
                    case PlayerHandResult.PlayerWin:
                        // nop
                        break;

                    case PlayerHandResult.Draw:
                        player_hand_final_result = PlayerHandResult.Draw;
                        if (enemyIndx == 0)
                        {
                            player_stat_hand_result = PlayerHandResult.Draw;
                        }
                        break;

                    case PlayerHandResult.PlayerLose:
                        player_hand_final_result = PlayerHandResult.PlayerLose;
                        if (enemyIndx == 0)
                        {
                            player_stat_hand_result = PlayerHandResult.PlayerLose;
                        }
                        break;

                    default:
                        throw Utility.GetUnknownEnumValueException(player_hand_result);
                }

                if (player_hand_final_result == PlayerHandResult.PlayerLose)
                {
                    break;
                }
            }

            UpdateStatistic(stat, player_hand, player_hand_final_result, enemy_stat_hand, player_stat_hand_result);
            Interlocked.Increment(ref param.SimulatedGamesCount);
        }
Example #3
0
        private Card[] GetOpenCards(CalculationParameters ex_params)
        {
            var boardCards = new Card[]
            {
                ex_params.Flop1,
                ex_params.Flop2,
                ex_params.Flop3,
                ex_params.Turn,
                ex_params.River,
            };

            return boardCards.Where(x => x != null).ToArray();
        }
Example #4
0
        public Statistic RunExperiment(CalculationParameters param)
        {
            CheckParameters(param);

            var sw = Stopwatch.StartNew();

            SimulatedGamesCount = 0;

            Card player_card1 = param.PlayerCard1;
            Card player_card2 = param.PlayerCard2;

            Card[] open_cards = GetOpenCards(param);
            ValidateInputCards(player_card1, player_card2, open_cards);

            Card[] cards = GetAllCards();

            Card[] free_cards = GetFreeCards(cards, player_card1, player_card2, open_cards);

            var stat = new StatisticInternal();
            stat.Init();

            int parallelLevel = param.ParallelLevel;

            #if OneThreadForDBG
            parallelLevel = 1;
            #endif

            int enemyPlayersCount = param.EnemyPlayersCount;
            int gameNumber = param.GameNumber;

            var semaphore = new SemaphoreSlim(parallelLevel);
            var countdown = new CountdownEvent(gameNumber);

            for (int i = 0; i < gameNumber; i++)
            {
                param.CancelToken.ThrowIfCancellationRequested();

                if (param.TimeLimit.HasValue
                    && sw.Elapsed > param.TimeLimit.Value)
                {
                    countdown.Signal(gameNumber - i);
                    break;
                }

                semaphore.Wait();
                SimulatedGamesCount++;

                Action action =
                    () =>
                    {
                        try
                        {
                            SimulateGame(player_card1, player_card2, open_cards, free_cards, enemyPlayersCount, stat, param);
                        }
                        finally
                        {
                            semaphore.Release();
                            countdown.Signal();
                        }
                    };

                if (parallelLevel == 1)
                {
                    action();
                }
                else
                {
                    Task.Factory.StartNew(action);
                }
            }

            countdown.Wait();
            countdown.Dispose();
            semaphore.Dispose();

            Statistic public_stat = PreparePublicStatistic(stat);

            return public_stat;
        }
Example #5
0
        private static void CheckParameters(CalculationParameters param)
        {
            Code.RequireNotNull(param);
            Code.RequireNotNull(param.PlayerCard1);
            Code.RequireNotNull(param.PlayerCard2);

            Code.Require(param.GameNumber > 0);
            Code.Require(param.ParallelLevel > 0);
            Code.Require(param.EnemyPlayersCount > 0 && param.EnemyPlayersCount <= 22);
            Code.Require(param.TimeLimit == null || param.TimeLimit.Value > TimeSpan.Zero);
        }