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)); }
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))); } }
/// <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); }
/// <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()); }
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))); } }