//Returns the number of matching tiles in the collection public int CountOf(TileID id, int accessKey = 0) { if ((accessKey != _accessKey) && _accessKey != 0) { return(-1); } int count = 0; for (int i = 0; i < Count; i++) { if (tileIDs[i] == id) { count++; } } return(count); }
//Checks the given tile ID to see if the hand may contain a loose tile of it after a discard //If loose, adds the tile to the loose tile list. private void CheckIfNewLoose(TileID tile) { int index = hand.Tiles.Closed.IndexOf(tile, accessKey); if (index == -1) { return; } if (hand.Tiles.Closed.CountOf(tile, accessKey) >= 2) { return; } if (IsLoose(hand.Tiles.Closed[index])) { LooseTiles.Add(hand.Tiles.Closed[index], accessKey); } }
//Returns true if the tile qualifies as loose. Does not add it to the loose tiles collection. private bool IsLoose(Tile tile) { int index = hand.Tiles.Closed.IndexOf(tile, accessKey); if (index == -1) { return(false); } if (index > 0 && TileID.InSameSuji(hand.Tiles.Closed[index - 1].Query(accessKey), tile.Query(accessKey))) { return(false); } if (index + 1 < hand.Tiles.Closed.Count && TileID.InSameSuji(hand.Tiles.Closed[index + 1].Query(accessKey), tile.Query(accessKey))) { return(false); } return(true); }
//Returns all potential melds that are waiting on the given tile ID public List <PotentialMeld> GetWaitingMelds(TileID tile) { List <PotentialMeld> list = new List <PotentialMeld>(); for (int i = 0; i < Melds.Count; i++) { if (!(Melds[i].Completed) && (tile.Suit == Melds[i].Suit)) { for (int j = 0; j < Melds[i].Waits.Count; j++) { if (Melds[i].Waits[j].tile == tile) { list.Add(Melds[i]); break; } } } } return(list); }
//*********************************************************************** //**************************** Basic Methods **************************** //*********************************************************************** //Adds the tile to the collection //Note: if the tile is locked with a different access key, will not add public void Add(Tile tile, int accessKey = 0) { if ((accessKey != _accessKey) && _accessKey != 0) { return; } if (Contains(tile, _accessKey)) { return; } TileID id = tile.Query(_accessKey); if (id == TileID.Hidden) { return; } tiles.Add(tile); tileIDs.Add(id); }
//Returns the number of matching tiles in the collection new public int CountOf(TileID id, int accessKey = 0) { if ((accessKey != _accessKey) && _accessKey != 0) { return(-1); } int index = IndexOf(id, _accessKey); if (index == -1) { return(0); } int count = 1; while (index + count < this.Count && tileIDs[index + count] == id) { count++; } return(count); }
//Returns the index of the first matching tile or -1 if not found new public int IndexOf(TileID id, int accessKey = 0) { if ((accessKey != _accessKey) && _accessKey != 0) { return(-1); } int i = 0; while (i < tileIDs.Count && tileIDs[i] != id) { i++; } if (i < tileIDs.Count) { return(i); } else { return(-1); } }
//Gets the first naki of the type in the meld list //...[that involves the given TileID, if that arg is passed] private Naki GetNaki(NakiType type, TileID involving = null) { int i = 0; while (i < calls.Count && calls[i].type != type) { i++; } if (i == calls.Count) { return new Naki() { type = NakiType.Nashi /*, requestor = player*/ } } ; else { return(calls[i]); } }
//Adds all the waiting versions of a completed meld. Returns the number added. private int AddPotentialVersions(PotentialMeld completed) { int count = 0; PotentialMeld meld; if (completed.Type == Meld.MeldType.Koutsu) { //Potential koutsu meld = new PotentialMeld() { Type = Meld.MeldType.Koutsu, }; meld.Add(completed.IDs[0]); meld.Add(completed.IDs[0]); meld.Waits.Add(new Wait(WaitType.Kantsu, completed.IDs[0])); AddMeld(meld); count++; } else if (completed.Type == Meld.MeldType.Shuntsu) { //Potential shuntsu lower meld = new PotentialMeld() { Type = Meld.MeldType.Shuntsu, }; TileID t1 = completed.IDs[0]; TileID t2 = completed.IDs[1]; TileID t3 = completed.IDs[2]; meld.Add(t1); meld.Add(t2); if (t1.Number == 1) { meld.Waits.Add(new Wait(WaitType.Penchan, new TileID(t1.Suit, 3))); } else { meld.Waits.Add(new Wait(WaitType.Ryanmen, new TileID(t1.Suit, (byte)(t1.Number - 1)))); meld.Waits.Add(new Wait(WaitType.Ryanmen, t3)); } AddMeld(meld); count++; //Potential shuntsu upper meld = new PotentialMeld() { Type = Meld.MeldType.Shuntsu, }; meld.Add(t2); meld.Add(t3); if (t3.Number == 9) { meld.Waits.Add(new Wait(WaitType.Penchan, new TileID(t1.Suit, 7))); } else { meld.Waits.Add(new Wait(WaitType.Ryanmen, t1)); meld.Waits.Add(new Wait(WaitType.Ryanmen, new TileID(t1.Suit, (byte)(t3.Number + 1)))); } AddMeld(meld); count++; //Potential shuntsu center (kanchan) meld = new PotentialMeld() { Type = Meld.MeldType.Shuntsu, }; meld.Add(t1); meld.Add(t3); meld.Waits.Add(new Wait(WaitType.Kanchan, t2)); AddMeld(meld); count++; } return(count); }
//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); }
public bool GreaterOrEqual(TileID t1, TileID t2) { return(LessThan(t2, t1) || (t1 == t2)); }
public bool LessOrEqual(TileID t1, TileID t2) { return(LessThan(t1, t2) || (t1 == t2)); }
public bool GreaterThan(TileID t1, TileID t2) { return(LessThan(t2, t1)); }
public Wait(WaitType t, TileID id) { tile = id; type = t; }
//Creates a copy of the tile. Used for access safety public TileID Copy() { TileID tile = new TileID(this.Suit, this.Number, this.Aka); return(tile); }
//Removes the first occurrence of the tile public void Remove(TileID tile) { _ids.Remove(tile); }