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]++;
                }
            }
        }
Example #2
0
        // 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;
                }
            }
        }
Example #3
0
        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;
        }
Example #4
0
        public void Load(string FileName)
        {
            FileName = "round/" + FileName;

            XmlLoad X = new XmlLoad();

            if (!X.Load(FileName)) return;

            this.FileName = FileName;

            while (X.Read())
            {
                switch (X.ElementName)
                {
                    case "hash": Hash = X.GetAttribute("value"); break;
                    case "playercount": PlayerCount = X.GetIntAttribute("value"); break;
                    case "lobby": Lobby = X.GetIntAttribute("value"); break;
                    case "lobbytype": LobbyType = (LobbyType)X.GetIntAttribute("value"); break;
                    case "game": Index = X.GetIntAttribute("index"); break;
                    case "round": CurrentRound = X.GetIntAttribute("index"); break;
                    case "result": StringResult = X.GetAttribute("value"); break;
                    case "drawreason": DrawReason = X.GetIntAttribute("value"); break;
                    case "riichistick": RiichiStick = X.GetIntAttribute("value"); break;
                    case "renchanstick": RenchanStick = X.GetIntAttribute("value"); break;
                    case "balancebefore": BalanceBefore = X.ReadIntArray(); break;
                    case "balanceafter": BalanceAfter = X.ReadIntArray(); break;
                    case "pay": Pay = X.ReadIntArray(); break;
                    case "winner": Winner = X.ReadBoolArray(); break;
                    case "loser": Loser = X.ReadBoolArray(); break;
                    case "openedsets": OpenedSets = X.ReadIntArray(); break;
                    case "naki": Naki = X.ReadIntArray(); break;
                    case "riichi": Riichi = X.ReadIntArray(); break;
                    case "dealer": Dealer = X.ReadBoolArray(); break;
                    case "tempai": Tempai = X.ReadBoolArray(); break;
                    case "wind": Wind = X.ReadIntArray(); break;
                    case "stepcount": StepCount = X.ReadIntArray(); break;
                    case "firstdora": FirstDora = X.GetIntAttribute("pointer"); break;
                    case "wall":
                    {
                        if (Wall == null) Wall = new Mahjong.Wall();

                        Wall.Dice = DecompositeIntList(X.GetAttribute("dice"));
                        Wall.Tiles = DecompositeIntList(X.GetAttribute("tiles"));
                    }
                    break;
                    case "steps":
                        {
                            int Count = X.GetIntAttribute("count");
                            XmlLoad Subtree = X.GetSubtree();
 
                            for (int j = 0; j < Count; j++)
                            {
                                Step NewStep = new Step(-1);

                                NewStep.ReadXml(Subtree);

                                Steps.Add(NewStep);
                            }

                            Subtree.Close();
                        }
                        break;
                    case "hands":
                        {
                            XmlLoad Subtree = X.GetSubtree();

                            while (Subtree.Read())
                            {
                                switch (Subtree.ElementName)
                                {
                                    case "hand":
                                        {
                                            int Player = Subtree.GetIntAttribute("player");

                                            XmlLoad HandData = Subtree.GetSubtree();
                                            StartHands[Player] = new Hand();

                                            StartHands[Player].ReadXml(HandData);

                                            HandData.Close();
                                        }
                                        break;
                                }
                            }

                            Subtree.Close();
                        }
                        break;
                    case "shantenlist":
                        {
                            XmlLoad Subtree = X.GetSubtree();

                            while (Subtree.Read())
                            {
                                switch (Subtree.ElementName)
                                {
                                    case "shanten":
                                        {
                                            int Player = Subtree.GetIntAttribute("player");
                                            int Count = Subtree.GetIntAttribute("shanten");

                                            XmlLoad ShantenData = Subtree.GetSubtree();

                                            while (ShantenData.Read())
                                            {
                                                switch (ShantenData.ElementName)
                                                {
                                                    case "step":
                                                        {
                                                            int Value = ShantenData.GetIntAttribute("value");
                                                            Shanten[Player].Add(Value);
                                                        }
                                                        break;
                                                }
                                            }

                                            ShantenData.Close();
                                        }
                                        break;
                                }
                            }

                            Subtree.Close();
                        }
                        break;
                    case "agari":
                        {
                            int Player = X.GetIntAttribute("player");

                            HanCount[Player] = X.GetIntAttribute("han");
                            FuCount[Player] = X.GetIntAttribute("fu");
                            Cost[Player] = X.GetIntAttribute("cost");

                            XmlLoad Subtree = X.GetSubtree();
                            while (Subtree.Read())
                            {
                                switch (Subtree.ElementName)
                                {
                                    case "yakulist":
                                        {
                                            int Count = Subtree.GetIntAttribute("count");
                                            XmlLoad YakuList = Subtree.GetSubtree();

                                            while (YakuList.Read())
                                            {
                                                switch (YakuList.ElementName)
                                                {
                                                    case "yaku":
                                                        Yaku Y = new Yaku();
                                                        Y.Cost = YakuList.GetIntAttribute("cost");
                                                        Y.Index = YakuList.GetIntAttribute("index");

                                                        Yaku[Player].Add(Y);
                                                        break;
                                                }
                                            }

                                            YakuList.Close();
                                        }
                                        break;
                                    case "waitings":
                                        {
                                            int Count = Subtree.GetIntAttribute("count");
                                            XmlLoad WaitList = Subtree.GetSubtree();

                                            while (WaitList.Read())
                                            {
                                                switch (WaitList.ElementName)
                                                {
                                                    case "waiting":
                                                        WinWaiting[Player].Add(WaitList.GetIntAttribute("value"));
                                                        break;
                                                }
                                            }

                                            WaitList.Close();
                                        }
                                        break;
                                }
                            }

                            Subtree.Close();
                        }
                        break;

                    case "dora":
                        {
                            int Count = X.GetIntAttribute("count");
                            Dora.Clear();

                            XmlLoad Doras = X.GetSubtree();
                            while (Doras.Read())
                            {
                                switch (Doras.ElementName)
                                {
                                    case "dora":
                                        Dora.Add(Doras.GetIntAttribute("pointer"));
                                        break;
                                }
                            }
                            Doras.Close();
                        }
                        break;
                    case "uradora":
                        {
                            int Count = X.GetIntAttribute("count");

                            UraDora.Clear();

                            XmlLoad Doras = X.GetSubtree();
                            while (Doras.Read())
                            {
                                switch (Doras.ElementName)
                                {
                                    case "dora":
                                        UraDora.Add(Doras.GetIntAttribute("pointer"));
                                        break;
                                }
                            }
                            Doras.Close();
                        }
                        break;
                }
            }
        }
Example #5
0
        public Hand(Hand H)
        {
            for (int i = 0; i < Tiles.Length; i++) this.Tiles[i] = H.Tiles[i];

            for (int i = 0; i < H.Naki.Count; i++) Naki.Add(H.Naki[i]);
        }
        public bool KaratenNotenHand = false; // Waiting only on 5th tile

        public ShantenCalculator(Hand Hand)
        {
            this.Hand = Hand;

            TehaiCreate(Hand);
        }