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