예제 #1
0
        public static IPlayCardStrategy Create(IGameProvider gameProvider, IPlayerContext playerContext)
        {
            if (gameProvider == null)
            {
                throw new ArgumentNullException(nameof(gameProvider));
            }
            if (playerContext == null)
            {
                throw new ArgumentNullException(nameof(playerContext));
            }

            List <Guess> guesses = new List <Guess>();

            foreach (var cardInHand in playerContext.Hand)
            {
                var guess = new Guess(gameProvider, cardInHand);
                foreach (var clue in playerContext.GetCluesAboutCard(cardInHand))
                {
                    clue.Accept(guess);
                }

                guesses.Add(guess);
            }

            return(new PlayCardStrategy(guesses));
        }
예제 #2
0
        private ClueType FindClueToDiscard(IPlayerContext playerContext, IEnumerable <Card> uniqueCards)
        {
            // сразу уберём карты, о которых игрок знает.
            var cardsToSearch = uniqueCards.Except(playerContext.Player.GetKnownCards()).ToList();

            if (!cardsToSearch.Any())
            {
                return(null);
            }

            var uniqueUnknownCards =
                playerContext
                .Hand
                .Where(cardInHand => cardsToSearch.Contains(cardInHand.Card))
                .ToList();

            if (!uniqueUnknownCards.Any())
            {
                return(null);
            }

            uniqueUnknownCards =
                uniqueUnknownCards
                .OrderBy(cardInHand => (int)cardInHand.Card.Rank)
                .ToList();

            // если игрок знает о пятёрке, то указывать на неё не будем
            var cardToClue =
                uniqueUnknownCards.FirstOrDefault(cardInHand => !KnownFiveRankedCards(cardInHand));

            if (cardToClue == null)
            {
                return(null);
            }

            return(ClueDetailInfo.CreateClues(cardToClue, playerContext).First());

            bool KnownFiveRankedCards(CardInHand cardInHand)
            {
                if (cardInHand.Card.Rank != Rank.Five)
                {
                    return(false);
                }

                var clueAboutFiveRank = new ClueAboutRank(Rank.Five);

                return
                    (playerContext
                     .GetCluesAboutCard(cardInHand)
                     .Any(clue => clueAboutFiveRank.Equals(clue)));
            }
        }
예제 #3
0
        /// <summary>
        /// Возвращает
        /// {карты, по которым есть тонкая подсказка} U
        /// {карты, \forall P(play) >= play_threshold} U
        /// {единицы, о которых игрок знает при условии, что единицу можно сыграть}
        /// </summary>
        /// <param name="boardContext"></param>
        /// <param name="playerContext"></param>
        /// <returns></returns>
        public IList <Card> GetPossibleCards(IBoardContext boardContext, IPlayerContext playerContext)
        {
            var estimates = _strategy.EstimateCardToPlayProbability(boardContext);

            var result =
                playerContext
                .Hand
                .Where(cardInHand => playerContext.IsSubtleClue(cardInHand, boardContext.GetExpectedCards()))
                .Select(cardInHand => cardInHand.Card)
                .ToList();

            // Если нет тонких подсказок, то посмотрим на вероятности
            if (!result.Any())
            {
                Probability maxProbability = estimates.Values.Max();

                if (maxProbability >= playerContext.Player.PlayProbabilityThreshold)
                {
                    result =
                        (from e in estimates
                         where e.Value == maxProbability
                         orderby e.Value descending
                         select e.Key.Card).ToList();
                }
            }

            // Ни тонких подсказок, не явных карт, которыми можно сходить, нет
            // посмотрим, знает ли игрок об единицах
            if (!result.Any() && boardContext.BlowCounter > 1)
            {
                if (boardContext.GetExpectedCards().Any(c => c.Rank == Rank.One))
                {
                    var cards = playerContext.Hand
                                .Where(c => c.Card.Rank == Rank.One)
                                .Where(c => !playerContext.Player.KnowAboutNominalAndColor(c));

                    foreach (CardInHand card in cards)
                    {
                        var knowsAboutRank
                            = playerContext.GetCluesAboutCard(card)
                              .Any(c => new ClueAboutRank(Rank.One).Equals(c));

                        if (knowsAboutRank)
                        {
                            result.Add(card.Card);
                        }
                    }
                }
            }

            return(result);
        }
예제 #4
0
        /// <summary>
        /// Возвращает подсказки, которые можно дать игроку на карту.
        /// Убирает подсказки, которые давали игроку ранее
        /// </summary>
        public static IList <ClueType> CreateClues(CardInHand card, IPlayerContext playerContext)
        {
            if (card == null)
            {
                throw new ArgumentNullException(nameof(card));
            }
            if (playerContext == null)
            {
                throw new ArgumentNullException(nameof(playerContext));
            }
            // TODO create more concise error description
            if (card.Player != playerContext.Player)
            {
                throw new ArgumentException("Different players");
            }

            return(new List <ClueType> {
                new ClueAboutRank(card.Card.Rank), new ClueAboutColor(card.Card.Color)
            }
                   .Except(playerContext.GetCluesAboutCard(card))
                   .ToList());
        }
예제 #5
0
        private ClueType FindClueToPlay(IPlayerContext playerContext, IEnumerable <Card> expectedCards)
        {
            // сразу уберём карты, о которых игрок знает.
            var cardsToSearch = expectedCards.Except(playerContext.Player.GetKnownCards()).ToList();

            if (!cardsToSearch.Any())
            {
                return(null);
            }

            var cardsToPlay =
                playerContext
                .Hand
                .Where(cardInHand => cardsToSearch.Contains(cardInHand.Card))
                .Where(cardInHand => !IsKnownOneRankedCard(cardInHand))
                .ToList();

            if (!cardsToPlay.Any())
            {
                return(null);
            }

            cardsToPlay =
                cardsToPlay.OrderBy(cardInHand => (int)cardInHand.Card.Rank).ToList();

            var cardToClue =
                cardsToPlay.Last().Card.Rank == Rank.Five ? cardsToPlay.Last() : cardsToPlay.First();

            return(ClueDetailInfo.CreateClues(cardToClue, playerContext).FirstOrDefault());

            bool IsKnownOneRankedCard(CardInHand cardInHand)
            {
                return
                    (playerContext
                     .GetCluesAboutCard(cardInHand)
                     .Any(clue => Equals(new ClueAboutRank(Rank.One), clue)));
            }
        }