protected void RecursivelyFindAllGroupsInTiles(IList <Tile> tiles, int currentIndex, int maxDepth,
                                                       IList <TileGrouping> allGroups, params Tile[] currentTiles)
        {
            try {
                if (!currentTiles[0].CanBelongToSameGroup(tiles[currentIndex]))
                {
                    return;
                }
            }
            catch (ArgumentOutOfRangeException)
            {
                return;
            }

            Tile[] potentialGroup = new List <Tile>(currentTiles)
            {
                tiles[currentIndex]
            }.ToArray();
            var groupingOfTiles = new TileGrouping(potentialGroup);

            if (Tile.IsGroup(potentialGroup) && !allGroups.Contains(groupingOfTiles)) // || Tile.IsPair(potentialGroup))
            {
                allGroups.Add(groupingOfTiles);
            }

            if (maxDepth > 0)
            {
                for (int nextTileIndex = currentIndex; nextTileIndex < tiles.Count - minimumGroupSize + 2; nextTileIndex++)
                {
                    RecursivelyFindAllGroupsInTiles(tiles, nextTileIndex + 1, maxDepth - 1, allGroups, potentialGroup);
                }
            }
        }
예제 #2
0
        public TileGrouping ChooseGroupToMakeWithDiscardedTile(Tile discardedTile, bool canBeSequence)
        {
            UpdateSeenTiles();
            var potentialHandTiles = new List <Tile>(Hand.UncalledTiles)
            {
                discardedTile
            };
            var groupsInvolvingDiscardedTile = GetAllGroupsThatCanBeMadeWithDiscardedTile(discardedTile, canBeSequence);

            var minimumWaitingDistance = WaitingDistanceFinder.GetWaitingDistance(Hand.UncalledTiles);
            var maximumTileEfficiency  = EfficientDrawsFinder.GetEfficientDrawCountWithSeenTiles(Hand.UncalledTiles,
                                                                                                 SeenTiles);
            TileGrouping idealGroup = null;

            foreach (var group in groupsInvolvingDiscardedTile)
            {
                var remainingTiles = new List <Tile>(potentialHandTiles);
                foreach (var tile in group)
                {
                    remainingTiles.Remove(tile);
                }

                var newWaitingDistance = WaitingDistanceFinder.GetWaitingDistance(remainingTiles);
                var newTileEfficiency  = EfficientDrawsFinder.GetEfficientDrawCountWithSeenTiles(remainingTiles,
                                                                                                 SeenTiles);
                if (newWaitingDistance < minimumWaitingDistance ||
                    (newWaitingDistance == minimumWaitingDistance && newTileEfficiency > maximumTileEfficiency))
                {
                    minimumWaitingDistance = newWaitingDistance;
                    maximumTileEfficiency  = newTileEfficiency;
                    idealGroup             = group;
                }
            }
            return(idealGroup);
        }
예제 #3
0
 public void MakeGroupWithDiscardedTile(Tile discardedTile, TileGrouping group)
 {
     group.IsOpenGroup = true;
     Hand.CalledSets.Add(group);
     Hand.UncalledTiles.Add(discardedTile);
     Hand.IsOpen = true;
     foreach (var tile in group)
     {
         Hand.UncalledTiles.Remove(tile);
     }
 }
예제 #4
0
 private void WriteOpenGroupMessage(Player player, TileGrouping groupFormed)
 {
     if (groupFormed.IsQuad())
     {
         Console.WriteLine($"{player.Name} says \"GONG.\"");
     }
     else if (groupFormed.IsTriplet())
     {
         Console.WriteLine($"{player.Name} says \"PUNG.\"");
     }
     else if (groupFormed.IsSequence())
     {
         Console.WriteLine($"{player.Name} says \"CHOW.\"");
     }
     Console.ReadKey();
     Console.WriteLine();
 }
        public IList <IList <TileGrouping> > FindAllWaysToGroupTilesAfterRemovingAPair(IList <Tile> tiles)
        {
            var allWaysToGroupTiles = new List <IList <TileGrouping> >();

            tiles = tileSorter.SortTiles(tiles);
            for (int i = 0; i < tiles.Count - 1; i++)
            {
                var pair = new TileGrouping(tiles[i], tiles[i + 1]);
                if (!tiles[i].Equals(tiles[i + 1]))
                {
                    continue;
                }

                // If we've already seen all ways of splitting these tiles starting with an identical pair to this one,
                // we won't find any new ways to split the tiles by starting with this pair
                if (IsValueAlreadyContainedInNestedEnumerable(pair, allWaysToGroupTiles))
                {
                    i++;
                    continue;
                }

                var remainingTiles          = GetTilesWithConsecutiveNTilesRemoved(tiles, i, 2);
                var currentWaysToSplitTiles = FindAllWaysToGroupTiles(remainingTiles);
                foreach (var listOfGroups in currentWaysToSplitTiles)
                {
                    listOfGroups.Add(pair);
                    allWaysToGroupTiles.Add(listOfGroups);
                }
                if (currentWaysToSplitTiles.Count == 0)
                {
                    allWaysToGroupTiles.Add(new List <TileGrouping> {
                        pair
                    });
                }
            }
            return(allWaysToGroupTiles);
        }
예제 #6
0
        private void HandleClaimedDiscard(int indexOfStealingPlayer, Tile discardedTile, TileGrouping group)
        {
            var stealingPlayer = Round.GetPlayers()[indexOfStealingPlayer];

            WriteOpenGroupMessage(stealingPlayer, group);
            stealingPlayer.MakeGroupWithDiscardedTile(discardedTile, group);
            stealingPlayer.Hand.SortHand();
            mostRecentActionText = $"{stealingPlayer.Name} takes the discarded {discardedTile}.\n";
            if (group.IsQuad())
            {
                HandleClaimedDiscardForQuad(stealingPlayer);
            }
            else
            {
                WriteGameState();

                bool hasDiscardedTile = false;
                while (!hasDiscardedTile)
                {
                    hasDiscardedTile = HandleTurnAction(stealingPlayer);
                }
            }
        }