コード例 #1
0
ファイル: Shanten.cs プロジェクト: yagamiiori/Eda
        //=====================================================================
        // 面子構成判定関数
        // このメソッドの中で、stateクラスのメンバを変更しないこと!
        //=====================================================================
        public static State CountMentsuAndKouho(Dictionary<int, int> kind, int level, State state)
        {
            State result = state;
            int minShanten = state.getShanten();

            for (int j = 1; j < PAI_MAX; j++)
            {
                if (!kind.ContainsKey(j))
                    continue;

                if (kind[j] >= 3)
                {
                    Dictionary<int, int> tmp = new Dictionary<int, int>(kind);
                    tmp[j] -= 3;

                    string partition = string.Format("{0} {1} {2} /", j, j, j);

                    State st = state.Clone();
                    st.mentsu += 1;
                    st.partition += partition;

                    // とった残りの手牌を再帰的に計算
                    State subResult = CountMentsuAndKouho(tmp, level + 1, st);

                    if (subResult.getShanten() < minShanten)
                    {
                        minShanten = subResult.getShanten();
                        result = subResult;
                    }
                }

                if (j < 29 && kind[j] >= 1 && kind[j + 1] >= 1 && kind[j + 2] >= 1)
                {
                    Dictionary<int, int> tmp = new Dictionary<int, int>(kind);
                    tmp[j] -= 1;
                    tmp[j+1] -= 1;
                    tmp[j+2] -= 1;

                    string partition = string.Format("{0} {1} {2} /", j, j+1, j+2);

                    State st = state.Clone();
                    st.mentsu += 1;
                    st.partition += partition;

                    // とった残りの手牌を再帰的に計算
                    State subResult = CountMentsuAndKouho(tmp, level + 1, st);

                    if (subResult.getShanten() < minShanten)
                    {
                        minShanten = subResult.getShanten();
                        result = subResult;
                    }
                }

                // 刻子候補があればとる
                if (kind[j] >= 2)
                {
                    Dictionary<int, int> tmp = new Dictionary<int, int>(kind);
                    tmp[j] -= 2;

                    string partition = string.Format("{0} {1} /", j, j);

                    State st = state.Clone();
                    st.kouho += 1;
                    st.partition += partition;

                    // とった残りの手牌を再帰的に計算
                    State subResult = CountMentsuAndKouho(tmp, level + 1, st);

                    if (subResult.getShanten() < minShanten)
                    {
                        minShanten = subResult.getShanten();
                        result = subResult;
                    }
                }

                // 順子候補があればとる(ペンチャンorリャンメン)
                if (j <= 29 && kind[j] >= 1 && kind[j + 1] >= 1)
                {
                    Dictionary<int, int> tmp = new Dictionary<int, int>(kind);
                    tmp[j] -= 1;
                    tmp[j+1] -= 1;

                    string partition = string.Format("{0} {1} /", j, j+1);

                    State st = state.Clone();
                    st.kouho += 1;
                    st.partition += partition;

                    // とった残りの手牌を再帰的に計算
                    State subResult = CountMentsuAndKouho(tmp, level + 1, st);

                    if (subResult.getShanten() < minShanten)
                    {
                        minShanten = subResult.getShanten();
                        result = subResult;
                    }
                }

                // 順子候補があればとる(カンチャン)
                if (j <= 29 && kind[j] >= 1 && kind[j + 2] >= 1 && (j/10 == (j+2)/10))
                {
                    Dictionary<int, int> tmp = new Dictionary<int, int>(kind);
                    tmp[j] -= 1;
                    tmp[j + 2] -= 1;

                    string partition = string.Format("{0} {1} /", j, j + 2);

                    // Stateクラスインスタンスの簡易コピーを生成
                    State st = state.Clone();

                    // 面子候補数を+1
                    st.kouho += 1;

                    // 手牌分割文字列を+1
                    st.partition += partition;

                    // とった残りの手牌を再帰的に計算
                    State subResult = CountMentsuAndKouho(tmp, level + 1, st);

                    if (subResult.getShanten() < minShanten)
                    {
                        minShanten = subResult.getShanten();
                        result = subResult;
                    }
                }
            }
            return result;
        }
コード例 #2
0
ファイル: Shanten.cs プロジェクト: yagamiiori/Eda
        //=====================================================================
        // 向聴数を求めるアルゴリズム - あらの(一人)麻雀研究所
        // http://mahjong.ara3.net/etc/shanten/index.htm
        // を実装
        //
        // テーブルは使用していない
        //=====================================================================
        public static State ShantenCheck2(List<int> tehai)
        {
            // テーブル構成関数より手牌を構築
            Dictionary<int, int> kind = GroupByKind(tehai);

            List<State> results = new List<State>();

            foreach (int pai in kind.Keys)
            {
                int cnt = kind[pai];

                // 雀頭(同じ牌が2つ)ある場合
                if (cnt >= 2)
                {
                    Dictionary<int, int> tmp = new Dictionary<int,int>(kind);
                    tmp[pai] -= 2;

                    // 雀頭判定フラグをtrueにして面子構成関数を起動
                    State state = new State();
                    state.hasAtama = true;
                    State subResult = CountMentsuAndKouho(tmp, 0, state);
                    results.Add(subResult);	// リストresults
                }
            }

            // 雀頭判定フラグをfalseにして面子構成関数を起動
            State state2 = new State();
            state2.hasAtama = false;
            State subResultr2 = CountMentsuAndKouho(kind, 0, state2);
            results.Add(subResult2);

            int min_shanten = 999;
            State ret = null;
            foreach (State r in results)
            {
                if (min_shanten > r.getShanten())
                {
                    min_shanten = r.getShanten();
                    ret = r;
                }
            }

            return ret;
        }