Beispiel #1
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)));
            }
        }
Beispiel #2
0
        public ClueAndAction CreateClueToAvoid(IBoardContext boardContext, IPlayerContext playerContext)
        {
            // 1. Поищем подсказки, после которых игрок точно сходит
            var clueToPlayFinder = new ClueToPlayFinder(boardContext, playerContext);
            var actionToPlay     = clueToPlayFinder.Find();

            if (actionToPlay != null)
            {
                return(actionToPlay);
            }

            var variants = new List <ClueAndAction>();

            var clues =
                playerContext.Hand
                .Where(cih => Cards.Contains(cih.Card))
                .Select(cih => ClueDetailInfo.CreateClues(cih, playerContext))
                .Aggregate((acc, c) => acc.Concat(c).ToList())
                .Distinct();

            foreach (var clue in clues)
            {
                // применим подсказку и посмотрим, будет ли всё хорошо
                playerContext.PossibleClue = clue;

                // контекст должен чуток измениться...
                var playCardStrategy = PlayStrategyFabric.Create(playerContext.Player.GameProvider, playerContext);
                var discardStrategy  =
                    DiscardStrategyFabric.Create(playerContext.Player.GameProvider, playerContext);

                var playerPredictor = new PlayerActionPredictor(boardContext, playerContext);
                var newAction       = playerPredictor.Predict(playCardStrategy, discardStrategy);


                if (IsNewActionCorrect(newAction))
                {
                    variants.Add(new ClueAndAction {
                        Clue = clue, Action = newAction
                    });
                }
            }

            return(ChooseClue(playerContext, variants));
        }
Beispiel #3
0
        protected ClueType CreateClue(IPlayerContext playerContext, IEnumerable <Card> cards)
        {
            if (playerContext == null)
            {
                throw new ArgumentNullException(nameof(playerContext));
            }
            if (cards == null)
            {
                throw new ArgumentNullException(nameof(cards));
            }

            foreach (var cardInHand in playerContext.Hand.Where(c => cards.Contains(c.Card)))
            {
                var clues = ClueDetailInfo.CreateClues(cardInHand, playerContext);
                if (clues.Any())
                {
                    return(clues.First());
                }
            }
            return(null);
        }
Beispiel #4
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)));
            }
        }
Beispiel #5
0
        private ClueType FindClueToWhateverPlay(IPlayerContext playerContext, IEnumerable <Card> whateverToPlayCards)
        {
            // сразу уберём карты, о которых игрок знает.
            var cardsToSearch = whateverToPlayCards.Except(playerContext.Player.GetKnownCards()).ToList();

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

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

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

            // TODO изучить...
            unknownCards =
                unknownCards
                .OrderBy(cardInHand => (int)cardInHand.Card.Rank)
                .ToList();

            var cardToClue = unknownCards.FirstOrDefault();

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

            return(ClueDetailInfo.CreateClues(playerContext, cardToClue).First());
        }
Beispiel #6
0
        public ClueAndAction Find()
        {
            var expectedCards = _boardContext.GetExpectedCards();

            var expectedThatCanPlay =
                _playerContext.Hand
                .Where(cih => expectedCards.Contains(cih.Card))
                .ToList();

            var cardsToPlay =
                expectedThatCanPlay.Where(cih => cih.Card.Rank == Rank.Five)
                .Concat(
                    expectedThatCanPlay
                    .Where(cih => cih.Card.Rank != Rank.Five)
                    .OrderBy(cih => cih.Card.Rank)
                    )
                .ToList();


            List <ClueAndAction> possibleClues = new List <ClueAndAction>();

            if (cardsToPlay.Any())
            {
                var clues =
                    cardsToPlay
                    .Select(card => ClueDetailInfo.CreateClues(card, _playerContext))
                    .Aggregate((acc, list) => acc.Concat(list).ToList())
                    .Distinct();

                foreach (var clue in clues)
                {
                    var playerContext = _playerContext.Clone();
                    playerContext.PossibleClue = clue;

                    PlayerActionPredictor predictor    = new PlayerActionPredictor(_boardContext, playerContext);
                    IPlayCardStrategy     playStrategy =
                        PlayStrategyFabric.Create(playerContext.Player.GameProvider, playerContext);

                    IDiscardStrategy discardStrategy =
                        DiscardStrategyFabric.Create(playerContext.Player.GameProvider, playerContext);

                    var action = predictor.Predict(playStrategy, discardStrategy);

                    if ((action.Outcome & OutcomeFlags.Play) > 0)
                    {
                        possibleClues.Add(new ClueAndAction {
                            Action = action, Clue = clue
                        });
                    }
                }
            }

            if (possibleClues.Count <= 1)
            {
                return(possibleClues.FirstOrDefault());
            }

            // раз возможных подсказок больше одной, то выберем ту, которая затрагивает большее число карт
            // из тех, которыми можно сыграть
            int           max           = 0;
            ClueAndAction clueAndAction = null;

            foreach (var clue in possibleClues)
            {
                int cardsAffected = CardsToClue(clue.Clue);
                if (cardsAffected > max)
                {
                    max           = cardsAffected;
                    clueAndAction = clue;
                }
            }

            return(clueAndAction);
        }