internal static PlayerMove PlayBestScoredMoveUpToLimitConsideringCommunication( IReadOnlyCollection <int> cardsInHand, PlayerInformation info) { var spm = new ScorePlayerPlays(); var plays = spm.GetScoredPlays(cardsInHand, info.RowsOfCards); if (plays.Count == 0) { return(new PlayerMove(PlayerMoveDecision.Undecided)); } ConsiderCommunication(info, plays); var bestMove = PlayerRulesUtils.GetBestMoveFromPlays(plays); if (bestMove.score <= MaxDistanceForSingleScoredMoveWithCommunicationAndTwoCardsToPlay && info.CardsToPlayThisTurn == 2 || bestMove.score <= MaxDistanceForSingleScoredMoveWithCommunicationAndOneCardToPlay && info.CardsToPlayThisTurn == 1) { return(new PlayerMove(PlayerMoveDecision.WantToPlay, bestMove.placements[0])); } return(new PlayerMove(PlayerMoveDecision.Undecided)); }
internal static PlayerStartDecision MakeStartDecision(IReadOnlyCollection <int> cardsInHand, int startingRound) { var spm = new ScorePlayerPlays(); var rowsAtStart = new Dictionary <RowOfCardsIdentifier, RowOfCards> { { RowOfCardsIdentifier.FirstRowUp, new RowOfCards(RowOfCardsType.Up) }, { RowOfCardsIdentifier.SecondRowUp, new RowOfCards(RowOfCardsType.Up) }, { RowOfCardsIdentifier.FirstRowDown, new RowOfCards(RowOfCardsType.Down) }, { RowOfCardsIdentifier.SecondRowDown, new RowOfCards(RowOfCardsType.Down) } }; var possibleStartingPlays = spm.GetScoredPlays(cardsInHand, rowsAtStart).Where(x => x.placements.Count > 1); var bestScore = !possibleStartingPlays.Any() ? 999 : PlayerRulesUtils.GetBestMoveFromPlays(spm.GetScoredPlays(cardsInHand, rowsAtStart) .Where(x => x.placements.Count > 1)).score; return((bestScore, startingRound) switch { (< 13, _) => PlayerStartDecision.WantToStart, (< 20, 2) => PlayerStartDecision.WantToStart, (< 20, _) => PlayerStartDecision.CouldStart, (_, < 3) => PlayerStartDecision.DoNotWantToStart, (_, _) => PlayerStartDecision.WantToStart });
internal static PlayerMove PlayBackwardsTrick(IReadOnlyCollection <int> cardsInHand, PlayerInformation info) { var backwardsPlays = PlayerRulesUtils.FindPlaysForBackwardTrick(cardsInHand, info.RowsOfCards); if (backwardsPlays.Count > 0) { return(new PlayerMove(PlayerMoveDecision.WantToPlay, new CardPlacement(backwardsPlays.First().Key, backwardsPlays.First().Value))); } return(new PlayerMove(PlayerMoveDecision.Undecided)); }
internal static List <PlayerCommunication> CommunicateBackwardsTrick( IReadOnlyCollection <int> cardsInHand, PlayerInformation info) { if (cardsInHand.Count == 0) { return(new List <PlayerCommunication>()); } return(PlayerRulesUtils.FindPlaysForBackwardTrick(cardsInHand, info.RowsOfCards).Keys.Distinct() .Select(row => new PlayerCommunication(row, PlayerCommunicationType.DoNotPlayHere)) .ToList()); }
internal static PlayerMove PlayLowestGapMove(IReadOnlyCollection <int> cardsInHand, PlayerInformation info) { var plays = PlayerRulesUtils.FindPossiblePlays(cardsInHand, info.RowsOfCards); if (plays.Count > 0) { var bestPlay = plays.OrderBy(x => x.distance).First(); return(new PlayerMove(PlayerMoveDecision.WantToPlay, new CardPlacement(bestPlay.rowIdentifier, bestPlay.card))); } return(new PlayerMove(PlayerMoveDecision.Undecided)); }
internal static PlayerMove PlayBestScoredMove(IReadOnlyCollection <int> cardsInHand, PlayerInformation info) { var spm = new ScorePlayerPlays(); var plays = spm.GetScoredPlays(cardsInHand, info.RowsOfCards); if (plays.Count == 0) { return(new PlayerMove(PlayerMoveDecision.Undecided)); } var bestMove = PlayerRulesUtils.GetBestMoveFromPlays(plays); return(new PlayerMove(PlayerMoveDecision.WantToPlay, bestMove.placements[0])); }
internal static List <PlayerCommunication> CommunicateCanNotPlay(IReadOnlyCollection <int> cardsInHand, PlayerInformation info) { if (cardsInHand.Count == 0) { return(new List <PlayerCommunication>()); } if (PlayerRulesUtils.FindPossiblePlaysUpToDistance(cardsInHand, info.RowsOfCards, int.MaxValue).Count < info.CardsToPlayThisTurn) { return(new List <PlayerCommunication> { new(RowOfCardsIdentifier.FirstRowUp, PlayerCommunicationType.CanNotPlay) });
internal static PlayerMove PlayMovesUpToLimitedDistance(IReadOnlyCollection <int> cardsInHand, PlayerInformation info) { var goodPlays = PlayerRulesUtils.FindPossiblePlaysUpToDistance(cardsInHand, info.RowsOfCards, MaxDistanceForSingleMove); if (goodPlays.Count > 0) { foreach (var play in goodPlays.OrderBy(x => x.distance)) { return(new PlayerMove(PlayerMoveDecision.WantToPlay, new CardPlacement(play.rowIdentifier, play.card))); } } return(new PlayerMove(PlayerMoveDecision.Undecided)); }
internal static PlayerMove PlayMovesUpToLimitUnlessBlockedByCommunication( IReadOnlyCollection <int> cardsInHand, PlayerInformation info) { var goodPlays = PlayerRulesUtils.FindPossiblePlaysUpToDistance(cardsInHand, info.RowsOfCards, MaxDistanceForSingleMoveWithCommunication); if (goodPlays.Count > 0) { foreach (var play in goodPlays.OrderBy(x => x.distance)) { if (!info.Communication.Exists(x => x.PlayerCommunication.Row == play.rowIdentifier && x.PlayerCommunication.CommunicationType is PlayerCommunicationType.DoNotPlayHere)) { return(new PlayerMove(PlayerMoveDecision.WantToPlay, new CardPlacement(play.rowIdentifier, play.card))); } } } return(new PlayerMove(PlayerMoveDecision.Undecided)); }