Пример #1
0
        // Выбросить нужно ту карту, которая не нужна => P(карта сыграна U уже не может быть сыграна) -> max
        // Нужно как-то учесть критичность карты, чтобы ненароком не выбросить нужное.
        // P(карта сыграна U уже не может быть сыграна) -> max И
        // P(карта не критичная) -> min
        private CardInHand GetCardToDiscard()
        {
            var uniqueCards = _pilesAnalyzer.GetUniqueCards(FireworkPile, DiscardPile);

            var thrownCards      = _pilesAnalyzer.GetThrownCards(FireworkPile, DiscardPile);
            var otherPlayerCards = GetOtherPlayersCards().Select(cih => cih.Card).ToList();

            var excludedCards = thrownCards.Concat(otherPlayerCards);

            //var boardContext = BoardContext.Create(_game.Board, _pilesAnalyzer, otherPlayerCards);
            //var playerContext = new PlayerContext(this, );

            //var discardStrategy = new DiscardStrategy();
            //discardStrategy.EstimateDiscardProbability(boardContext, playerContext);

            var cardsWhateverToPlay =
                _pilesAnalyzer.GetCardsWhateverToPlay(FireworkPile, DiscardPile);

            // разделим карты на две категории:
            // (*) о которых что-то известно (номинал или цвет),
            // (*) о которых ничего конкретного неизвестно.

            // если из тех карт, о которых что-то известно, есть те, которые можно выкинуть,
            // то выкидываем.
            var guessesAboutKnownCards =
                _memory
                .GetGuesses()
                .Where(guess => guess.KnowAboutRankOrColor());

            bool ShouldDiscard(Guess guess) =>
            guess.GetProbability(cardsWhateverToPlay, excludedCards) < DiscardProbabilityThreshold;

            Guess guessToDiscard =
                guessesAboutKnownCards.FirstOrDefault(ShouldDiscard);

            if (guessToDiscard != null)
            {
                return(_memory.GetCardByGuess(guessToDiscard));
            }

            // что ж, тогда копаемся со второй группой.
            // для каждой карты оценим вероятность того, что она - карта - критичная
            // выбросим карту с наименьшей вероятностью
            guessToDiscard =
                Guesses
                .Except(guessesAboutKnownCards)
                .OrderBy(guess => guess.GetProbability(uniqueCards, excludedCards))
                .FirstOrDefault();

            if (guessToDiscard == null)
            {
                guessToDiscard = guessesAboutKnownCards
                                 .OrderBy(guess => guess.GetProbability(uniqueCards, excludedCards))
                                 .First();
            }

            return(_memory.GetCardByGuess(guessToDiscard));
        }