public override TurnAction GetTurnActionAgainstDiscardedTile(Tile discardedTile, Player discardingPlayer)
        {
            RecentlySelectedTileGrouping = null;
            var isNextInTurnOrder  = IsPlayerNextInTurnOrder(discardingPlayer);
            var canMakeWinningHand = CanClaimDiscardedTileToCompleteWinningHand(discardedTile);

            var potentialHandTiles = new List <Tile>(Hand.UncalledTiles)
            {
                discardedTile
            };
            var groupsInvolvingDiscardedTile = TileGrouper.FindAllGroupsInTiles(potentialHandTiles)
                                               .Where(group => group.Contains(discardedTile)).ToList();
            var allowedGroups = FilterUnallowedGroups(groupsInvolvingDiscardedTile,
                                                      x => x.IsSequence() && !isNextInTurnOrder);

            while (true)
            {
                WriteOptionChoiceIntroductoryText();

                for (int i = 0; i < allowedGroups.Count; i++)
                {
                    Console.WriteLine($"\t{i + 1}. Claim the discarded {discardedTile} to make: " +
                                      $"[{allowedGroups[i]}].");
                }
                if (canMakeWinningHand)
                {
                    Console.WriteLine($"\tW: Claim the discarded {discardedTile} to form a [w]inning hand.");
                }
                Console.WriteLine($"\tP: [P]ass.");
                var choice = TakeInputAsLowercase();

                if (choice == "w" && canMakeWinningHand)
                {
                    return(TurnAction.DeclareWin);
                }
                if (choice == "p")
                {
                    return(TurnAction.Pass);
                }

                int.TryParse(choice, out int numericChoice);
                if (numericChoice > 0 && numericChoice < allowedGroups.Count + 1)
                {
                    RecentlySelectedTileGrouping = allowedGroups[numericChoice - 1];
                    var action = RecentlySelectedTileGrouping.IsTriplet() ? TurnAction.FormTriplet :
                                 (RecentlySelectedTileGrouping.IsQuad() ? TurnAction.FormQuad :
                                  (RecentlySelectedTileGrouping.IsSequence() ? TurnAction.FormSequence : TurnAction.Pass));
                    return(action);
                }
                WriteUnrecognizedInputText();
            }
        }
        public override TurnAction GetTurnActionAgainstDiscardedTile(Tile discardedTile, Player discardingPlayer)
        {
            RecentlySelectedTileGrouping = null;
            var indexInPlayerList         = Array.IndexOf(Game.Players, this);
            var arrayLength               = Game.Players.Count();
            var moduloPreviousPlayerIndex = (indexInPlayerList - 1 + arrayLength) % arrayLength;
            var isNextInTurnOrder         = Game.Players[moduloPreviousPlayerIndex] == discardingPlayer;

            if (IsClaimingDiscardedTileToCompleteWinningHand(discardedTile))
            {
                return(TurnAction.DeclareWin);
            }
            if (IsClaimingDiscardedTileToCompleteGroup(discardedTile, isNextInTurnOrder))
            {
                RecentlySelectedTileGrouping = ChooseGroupToMakeWithDiscardedTile(discardedTile, isNextInTurnOrder);
                var action = RecentlySelectedTileGrouping.IsTriplet() ? TurnAction.FormTriplet :
                             (RecentlySelectedTileGrouping.IsQuad() ? TurnAction.FormQuad :
                              (RecentlySelectedTileGrouping.IsSequence() ? TurnAction.FormSequence : TurnAction.Pass));
                return(action);
            }
            return(TurnAction.Pass);
        }