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