private void TehaiCreate(Hand Hand) { int i; WaitingCount = 0; for (i = 0; i < 38; i++) { Waitings[i] = 0; Tehai[i] = 0; TehaiUsage[i] = 0; } for (i = 0; i < 14; i++) { if (Hand.Tiles[i] != -1) { Tile T = new Tile(Hand.Tiles[i]); Tehai[T.TileId]++; TehaiUsage[T.TileId]++; } } // Count naki's tiles usage for (i = 0; i < Hand.Naki.Count; i++) { Mahjong.Naki N = Hand.Naki[i]; if (N.Type == NakiType.NUKI) continue; for (int j = 0; j < N.Tiles.Count; j++) { Tile T = new Tile(N.Tiles[j]); TehaiUsage[T.TileId]++; } } }
// Get all hands in round public void ReplayGame() { Hand[] TempHands = new Hand[PlayerCount]; List<int>[] TempWaitings = new List<int>[PlayerCount]; List<int>[] Discard = new List<int>[PlayerCount]; for (int i = 0; i < PlayerCount; i++) { TempWaitings[i] = new List<int>(); Discard[i] = new List<int>(); } int LastTile = -1; // Init hands for (int i = 0; i < PlayerCount; i++) { Hands[i].Clear(); Hands[i].Add(StartHands[i]); Shanten[i].Add(StartHands[i].Shanten); TempHands[i] = new Hand(StartHands[i]); } for (int i = 0; i < Steps.Count; i++) { Step S = Steps[i]; switch (S.Type) { case StepType.STEP_NEWDORA: { DoraCount++; } break; case StepType.STEP_DRAWTILE: { TempHands[S.Player].Draw(S.Tile); // analyze danger tiles S.Danger = AnalyzeDangerTiles(TempHands, TempWaitings, S.Player); } break; case StepType.STEP_DRAWDEADTILE: { LastTile = S.Tile; TempHands[S.Player].Draw(S.Tile); // analyze danger tiles S.Danger = AnalyzeDangerTiles(TempHands, TempWaitings, S.Player); } break; case StepType.STEP_DISCARDTILE: { TempHands[S.Player].Discard(S.Tile); Hands[S.Player].Add(new Hand(TempHands[S.Player])); int TShanten = TempHands[S.Player].Shanten; if(TShanten == 0) Tempai[S.Player] = true; S.Shanten = TShanten; Shanten[S.Player].Add(TShanten); Discard[S.Player].Add(new Tile(S.Tile).TileId); if (TShanten == 0) // Tempai { TempWaitings[S.Player] = TempHands[S.Player].WaitingList; S.Waiting = TempWaitings[S.Player].ToArray(); S.Furiten = IsFuriten(Discard[S.Player], S.Waiting); } } break; case StepType.STEP_NAKI: { Hand H = TempHands[S.Player]; if (S.NakiData.Type == NakiType.CHAKAN) { Tile T = new Tile(S.NakiData.Tiles[0]); // Remove pon with this tiles for (int n = 0; n < H.Naki.Count; n++) { if (new Tile(H.Naki[n].Tiles[0]).TileId == T.TileId) { H.Naki.RemoveAt(n); } } } TempHands[S.Player].Naki.Add(S.NakiData); TempHands[S.Player].OpenTiles(S.NakiData.Tiles); // analyze danger tiles S.Danger = AnalyzeDangerTiles(TempHands, TempWaitings, S.Player); } break; case StepType.STEP_TSUMO: { WinWaiting[S.Player] = Hands[S.Player][Hands[S.Player].Count - 1].WaitingList; Hands[S.Player].Add(new Hand(TempHands[S.Player])); Shanten[S.Player].Add(-1); } break; case StepType.STEP_RON: { WinWaiting[S.Player] = Hands[S.Player][Hands[S.Player].Count - 1].WaitingList; TempHands[S.Player].Draw(LastTile); Hands[S.Player].Add(new Hand(TempHands[S.Player])); Shanten[S.Player].Add(-1); } break; } } }
private int[] AnalyzeDangerTiles(Hand[] Hands, List<int>[] Waitings, int Player) { List<int> DangerTiles = new List<int>(); // Build danger tiles list List<int> Danger = new List<int>(); for (int j = 0; j < PlayerCount; j++) { if (Player == j) continue; // Skip player's self hand if(Waitings[j] == null) continue; // Skip noten hands for(int k = 0; k < Waitings[j].Count; k++) { if (Waitings[j][k] == -1) continue; // Skip exists if (Danger.Contains(Waitings[j][k])) continue; Danger.Add(Waitings[j][k]); } } for (int j = 0; j < Hands[Player].Tiles.Length; j++) { if (Hands[Player].Tiles[j] == -1) continue; Tile T = new Tile(Hands[Player].Tiles[j]); if (Danger.Contains(T.TileId)) DangerTiles.Add(T.Index); } return (DangerTiles.Count > 0) ? DangerTiles.ToArray() : null; }
public string GetText() { Tile[] TileList = new Tile[Tiles.Count]; string[] TileName = new string[Tiles.Count]; for (int i = 0; i < Tiles.Count; i++) { TileList[i] = new Tile(Convert.ToUInt16(Tiles[i])); TileName[i] = TileList[i].Value.ToString(); } string TType = TileList[0].TileType; switch (Type) { case NakiType.NUKI: return TileList[0].TileName; case NakiType.CHI: { string A = TileName[0]; string B = TileName[1]; string C = TileName[2]; return "[" + A + "]" + B + C + TType; } case NakiType.PON: { string A = TileName[0]; string B = TileName[1]; string C = TileName[2]; switch (FromWho) { case 1: return A + B + "[" + C + "]" + TType; case 2: return A + "[" + B + "]" + C + TType; case 3: return "[" + A + "]" + B + C + TType; } } break; case NakiType.ANKAN: { string A = TileName[0]; string B = TileName[1]; string C = TileName[2]; string D = TileName[2]; return "[" + A + B + C + D + TType + "]"; } case NakiType.MINKAN: { string A = TileName[0]; string B = TileName[1]; string C = TileName[2]; string D = TileName[2]; switch (FromWho) { case 1: return A + B + C + "[" + D + "]" + TType; case 2: return A + "[" + B + "]" + C + D + TType; case 3: return "[" + A + "]" + B + C + D + TType; } } break; case NakiType.CHAKAN: { string A = TileName[0]; string B = TileName[1]; string C = TileName[2]; string D = TileName[2]; switch (FromWho) { case 1: return A + B + "[" + C + "][" + D + "]" + TType; case 2: return A + "[" + B + "][" + C + "]" + D + TType; case 3: return "[" + A + "][" + B + "]" + C + D + TType; } } break; } return ""; }