protected override List <WinningTile> Process() { var output = new List <WinningTile>(); foreach (var possibleSet in PossibleSets) { var ordered = possibleSet.TilesLeft.OrderBy(q => q.Suit).ThenBy(q => q.Rank).ToList(); var meldCollection = new MeldCollection(null, ordered, possibleSet.Draw); var tilesWithEyeOccurance = meldCollection.TilesLeft.Distinct().Count( q => meldCollection.TilesLeft.Count(p => p.Equals(q)) == 2); var tilesWithKongOccurance = meldCollection.TilesLeft.Distinct().Count( q => meldCollection.TilesLeft.Count(p => p.Equals(q)) == 4); if (tilesWithEyeOccurance + tilesWithKongOccurance * 2 == 7) { for (int i = 0; i < 7; i++) { var tile = meldCollection.TilesLeft[0]; meldCollection.CreateMeld(new Meld(new List <Tile> { tile, tile }, MeldType.Eye)); } output.Add(new WinningTile(meldCollection, tilesWithKongOccurance == 0 ? Type : WinType.LongQiDui, tilesWithKongOccurance)); } } return(output); }
protected List <MeldCollection> Join(List <MeldCollection> list1, List <MeldCollection> list2, Tile draw) { var output = new List <MeldCollection>(); if (list1.Any() || list2.Any()) { if (!list1.Any()) { return(list2.ToList()); } if (!list2.Any()) { return(list1.ToList()); } foreach (var meldCollection in list1) { foreach (var collection in list2) { var mc = new MeldCollection(null, null, draw); mc.Melds.AddRange(meldCollection.Melds); mc.Melds.AddRange(collection.Melds); output.Add(mc); } } } return(output); }
protected IEnumerable <MeldCollection> GetMeldCollections(MeldCollection meldCollectionWithSameSuit) { var output = new List <MeldCollection>(); var count = meldCollectionWithSameSuit.TilesLeft.Count; if (count % 3 == 0) { var possibleMeldCollections = GetTripletMeldCollections(meldCollectionWithSameSuit); foreach (var possibleMeldCollection in possibleMeldCollections) { if (possibleMeldCollection.Successful) { output.Add(possibleMeldCollection); } else { var meldCollections = GetSequanceMeldCollections(possibleMeldCollection); foreach (var meldCollection in meldCollections) { if (meldCollection.Successful) { output.Add(meldCollection); } } } } } else if (count % 3 == 2) { var possibleMeldCollections = GetEyeMeldCollections(meldCollectionWithSameSuit); foreach (var possibleMeldCollection in possibleMeldCollections) { if (possibleMeldCollection.Successful) { output.Add(possibleMeldCollection); } else { var meldCollections = GetMeldCollections(possibleMeldCollection); foreach (var meldCollection in meldCollections) { if (meldCollection.Successful) { output.Add(meldCollection); } } } } } return(output); }
protected IEnumerable <MeldCollection> GetEyeMeldCollections(MeldCollection meldCollection) { var output = new List <MeldCollection>(); var tilesWithDoubleOccurance = meldCollection.TilesLeft.Where(q => meldCollection.TilesLeft.Count(p => p.Rank == q.Rank && p.Suit == q.Suit) >= 2).Distinct(); foreach (var tile in tilesWithDoubleOccurance) { var newMeldCollection = new MeldCollection(meldCollection.Melds.ToList(), meldCollection.TilesLeft.ToList(), meldCollection.Draw); newMeldCollection.CreateMeld(new Meld(new List <Tile> { tile, tile }, MeldType.Eye)); output.Add(newMeldCollection); } return(output); }
protected IEnumerable <MeldCollection> GetTripletMeldCollections(MeldCollection meldCollection, IList <Tile> selectedTiles = null) { var output = new List <MeldCollection>(); if (selectedTiles == null) { var tilesWithTripletOccurance = meldCollection.TilesLeft.Distinct().Where( q => meldCollection.TilesLeft.Count(p => p.Equals(q)) >= 3) .ToList(); var exceptionChildList = tilesWithTripletOccurance.GetChildSets(); foreach (var list in exceptionChildList) { output.AddRange(GetTripletMeldCollections(new MeldCollection(meldCollection.Melds.ToList(), meldCollection.TilesLeft.ToList(), meldCollection.Draw), list)); } } else { var newMeldCollection = new MeldCollection(meldCollection.Melds.ToList(), meldCollection.TilesLeft.ToList(), meldCollection.Draw); foreach (var tile in selectedTiles) { newMeldCollection.CreateMeld(new Meld(new List <Tile> { tile, tile, tile }, MeldType.Triplet)); } output.Add(newMeldCollection); } return(output); }
protected IEnumerable <MeldCollection> GetSequanceMeldCollections(MeldCollection meldCollection) { var output = new List <MeldCollection>(); if (meldCollection.TilesLeft.Count == 0) { return(output); } if (meldCollection.TilesLeft.Count % 3 != 0) { throw new Exception("Cannot process sequance search"); } var suit = meldCollection.TilesLeft.First().Suit; if (meldCollection.TilesLeft.Count(q => q.Suit == suit) != meldCollection.TilesLeft.Count) { throw new Exception("Unmatched suit found"); } if (meldCollection.TilesLeft.Count == 3) { var totalRank = meldCollection.TilesLeft.Sum(q => (int)q.Rank); if (totalRank % 3 != 0) { return(output); } else { var midTileRank = totalRank / 3; var midTile = meldCollection.TilesLeft.FirstOrDefault(q => q.Rank == (Rank)midTileRank); var leftTile = meldCollection.TilesLeft.FirstOrDefault(q => q.Rank == (Rank)midTileRank - 1); var rightTile = meldCollection.TilesLeft.FirstOrDefault(q => q.Rank == (Rank)midTileRank + 1); if (midTile != null && leftTile != null && rightTile != null) { var newMeldCollection = new MeldCollection(meldCollection.Melds.ToList(), meldCollection.TilesLeft.ToList(), meldCollection.Draw); newMeldCollection.CreateMeld(new Meld(new List <Tile> { leftTile, midTile, rightTile }, MeldType.Sequence)); output.Add(newMeldCollection); } } } else { var tilesLeft = meldCollection.TilesLeft.ToList(); var melds = meldCollection.Melds.ToList(); melds.AddRange(GetSequance(tilesLeft)); if (tilesLeft.Count == 0) { output.Add(new MeldCollection(melds, null, meldCollection.Draw)); } } return(output); }