Example #1
0
        private void UpdateStatistic(StatisticInternal stat, IHand player_hand, PlayerHandResult player_hand_final_result,
            IHand enemy_stat_hand, PlayerHandResult player_stat_hand_result)
        {
            lock (UpdateStat_SyncRoot)
            {
                Statistic.HandStatistic hs;

                hs = stat.PlayerHandsStat[player_hand.Value];
                switch (player_hand_final_result)
                {
                    case PlayerHandResult.PlayerWin:
                        hs.Win++;
                        break;
                    case PlayerHandResult.Draw:
                        hs.Draw++;
                        break;
                    case PlayerHandResult.PlayerLose:
                        hs.Lose++;
                        break;
                    default:
                        throw Utility.GetUnknownEnumValueException(player_hand_final_result);
                }
                stat.PlayerHandsStat[player_hand.Value] = hs;

                hs = stat.EnemyHandsStat[enemy_stat_hand.Value];
                switch (player_stat_hand_result)
                {
                    case PlayerHandResult.PlayerWin:
                        hs.Lose++;
                        break;
                    case PlayerHandResult.Draw:
                        hs.Draw++;
                        break;
                    case PlayerHandResult.PlayerLose:
                        hs.Win++;
                        break;
                    default:
                        throw Utility.GetUnknownEnumValueException(player_stat_hand_result);
                }
                stat.EnemyHandsStat[enemy_stat_hand.Value] = hs;
            }
        }
Example #2
0
        private Statistic PreparePublicStatistic(StatisticInternal stat)
        {
            var public_stat = new Statistic();
            public_stat.GameNumber = SimulatedGamesCount;

            var player_hands_stat = new List<Statistic.HandStatistic>();

            for (int hand_value = 0; hand_value < stat.PlayerHandsStat.Length; hand_value++)
            {
                HandType player_hand_type;
                if (!HandTypeConverter.TryGetHandType(hand_value, out player_hand_type))
                {
                    continue;
                }

                player_hands_stat.Add(stat.PlayerHandsStat[hand_value]);
            }
            public_stat.PlayerHandsStat = player_hands_stat.ToArray();

            public_stat.Win = public_stat.PlayerHandsStat.Sum(x => x.Win);
            public_stat.Draw = public_stat.PlayerHandsStat.Sum(x => x.Draw);
            public_stat.Lose = public_stat.PlayerHandsStat.Sum(x => x.Lose);

            var enemy_hands_stat = new List<Statistic.HandStatistic>();
            for (int hand_value = 0; hand_value < stat.EnemyHandsStat.Length; hand_value++)
            {
                HandType enemy_hand_type;
                if (!HandTypeConverter.TryGetHandType(hand_value, out enemy_hand_type))
                {
                    continue;
                }

                enemy_hands_stat.Add(stat.EnemyHandsStat[hand_value]);
            }
            public_stat.EnemyHandsStat = enemy_hands_stat.ToArray();

            return public_stat;
        }
Example #3
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 #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;
        }