// Выбросить нужно ту карту, которая не нужна => 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)); }