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