//*********************************************************************** //*************************** Public Methods **************************** //*********************************************************************** //Rebuilds the potential meld list from zero public void RebuildMeldList() { Melds.Clear(); //All closed tiles are loose until proven otherwise LooseTiles = new SortedTileCollection(hand.Tiles.Closed.GetTileList(), accessKey); //Add all the open melds int i = 0; for (i = 0; i < hand.OpenMelds.Count; i++) { AddMeld(hand.OpenMelds[i].ConvertToPotentialMeld()); } //Handle all closed tiles List <TileID> closed = hand.Tiles.Closed.GetTileIDList(accessKey); CheckForwardResponse info; i = 0; while (i < closed.Count) { info = CheckForward(i); if (info.count > 0) { LooseTiles.Remove(hand.Tiles.Closed[i], accessKey); } i++; } }
//Checks up to the next 3 tiles in the list and adds any potential melds to the collection //Returns the number of potential melds added. private CheckForwardResponse CheckForward(int index) { CheckForwardResponse info = new CheckForwardResponse { count = 0, }; List <TileID> list = hand.Tiles.Closed.GetTileIDList(accessKey); PotentialMeld meld; TileID t1 = TileID.Invalid, t2 = TileID.Invalid, t3 = TileID.Invalid, t4 = TileID.Invalid; t1 = list[index]; //First rule out any obvious disqualifiers if (index + 1 < list.Count) { t2 = list[index + 1]; } else { return(info); //index is last tile in list } if (t2.Suit != t1.Suit) { return(info); //next suit different } if (t1.Jihai && t1.Number != t2.Number) { return(info); //different honor } //Set the next tileIDs if (index + 2 < list.Count) { t3 = list[index + 2]; } if (index + 3 < list.Count) { t4 = list[index + 3]; } //Check for koutsu/kantsu if (t2 == t1) { if (t3 == t1) { if (t4 == t1) { //4 of the same tile //Completed kantsu meld = new PotentialMeld() { Type = Meld.MeldType.Kantsu, Completed = true }; meld.Add(t1); meld.Add(t1); meld.Add(t1); meld.Add(t1); AddMeld(meld); info.count++; //Completed koutsu meld = new PotentialMeld() { Type = Meld.MeldType.Koutsu, Completed = true }; meld.Add(t1); meld.Add(t1); meld.Add(t1); AddMeld(meld); info.count++; //Completed jantou meld = new PotentialMeld() { Type = Meld.MeldType.Jantou, Completed = true, }; meld.Add(t1); meld.Add(t1); AddMeld(meld); info.count++; LooseTiles.Remove(hand.Tiles.Closed[index], accessKey); LooseTiles.Remove(hand.Tiles.Closed[index + 1], accessKey); LooseTiles.Remove(hand.Tiles.Closed[index + 2], accessKey); LooseTiles.Remove(hand.Tiles.Closed[index + 3], accessKey); } else { //3 of the same tile. //Potential kantsu meld = new PotentialMeld() { Type = Meld.MeldType.Kantsu, }; meld.Add(t1); meld.Add(t1); meld.Add(t1); meld.Waits.Add(new Wait(WaitType.Kantsu, t1)); AddMeld(meld); info.count++; //Completed koutsu meld = new PotentialMeld() { Type = Meld.MeldType.Koutsu, Completed = true }; meld.Add(t1); meld.Add(t1); meld.Add(t1); AddMeld(meld); info.count++; //Add potential koutsu info.count += AddPotentialVersions(meld); //Completed jantou meld = new PotentialMeld() { Type = Meld.MeldType.Jantou, Completed = true, }; meld.Add(t1); meld.Add(t1); AddMeld(meld); info.count++; LooseTiles.Remove(hand.Tiles.Closed[index], accessKey); LooseTiles.Remove(hand.Tiles.Closed[index + 1], accessKey); LooseTiles.Remove(hand.Tiles.Closed[index + 2], accessKey); } } else { //2 of the same tile //Potential koutsu meld = new PotentialMeld() { Type = Meld.MeldType.Koutsu, }; meld.Add(t1); meld.Add(t1); meld.Waits.Add(new Wait(WaitType.Koutsu, t1)); AddMeld(meld); info.count++; //Completed jantou meld = new PotentialMeld() { Type = Meld.MeldType.Jantou, Completed = true, }; meld.Add(t1); meld.Add(t1); AddMeld(meld); info.count++; LooseTiles.Remove(hand.Tiles.Closed[index], accessKey); LooseTiles.Remove(hand.Tiles.Closed[index + 1], accessKey); } } //Check for shuntsu else { if (t2.Number - t1.Number == 1) { if (t3.Suit == t1.Suit && t3.Number - t2.Number == 1) { //Completed shuntsu meld = new PotentialMeld() { Type = Meld.MeldType.Shuntsu, Completed = true }; meld.Add(t1); meld.Add(t2); meld.Add(t3); AddMeld(meld); info.count++; //Add all the potential shuntsu info.count += AddPotentialVersions(meld); LooseTiles.Remove(hand.Tiles.Closed[index], accessKey); LooseTiles.Remove(hand.Tiles.Closed[index + 1], accessKey); LooseTiles.Remove(hand.Tiles.Closed[index + 2], accessKey); } else { //Potential shuntsu with an outer wait meld = new PotentialMeld() { Type = Meld.MeldType.Shuntsu, }; meld.Add(t1); meld.Add(t2); if (t1.Number == 1) { meld.Waits.Add(new Wait(WaitType.Penchan, new TileID(t1.Suit, 3))); } else if (t2.Number == 9) { meld.Waits.Add(new Wait(WaitType.Penchan, new TileID(t1.Suit, 7))); } else { meld.Waits.Add(new Wait(WaitType.Ryanmen, new TileID(t1.Suit, (byte)(t1.Number - 1)))); meld.Waits.Add(new Wait(WaitType.Ryanmen, new TileID(t1.Suit, (byte)(t2.Number + 1)))); } AddMeld(meld); info.count++; LooseTiles.Remove(hand.Tiles.Closed[index], accessKey); LooseTiles.Remove(hand.Tiles.Closed[index + 1], accessKey); } } else if (t2.Number - t1.Number == 2) { //Potential shuntsu with a kanchan (inner) wait meld = new PotentialMeld() { Type = Meld.MeldType.Shuntsu, }; meld.Add(t1); meld.Add(t2); meld.Waits.Add(new Wait(WaitType.Kanchan, new TileID(t1.Suit, (byte)(t1.Number + 1)))); AddMeld(meld); info.count++; LooseTiles.Remove(hand.Tiles.Closed[index], accessKey); LooseTiles.Remove(hand.Tiles.Closed[index + 1], accessKey); } } return(info); }