コード例 #1
0
ファイル: Tehai.cs プロジェクト: iuvei/mahjong3d
    public Tehai(Tehai src)
    {
        initialize();
        copy(this, src, true);

        Sort();
    }
コード例 #2
0
        public void 手配大明槓テスト()
        {
            Tehai testTehai = new Tehai(new List <string> {
                "1m", "2m", "3m", "4m", "5m", "6m", "7m", "8m", "9m", "1s", "2s", "3s", "1m"
            });

            testTehai.Tsumo(new Pai("1m"));


            //chi
            var actor    = 0;
            var target   = 3;
            var furopai  = new Pai("1m");
            var consumed = new List <Pai> {
                new Pai("1m"), new Pai("1m"), new Pai("1m")
            };

            consumed.Sort();

            Assert.IsTrue(testTehai.tehai.Contains(new Pai("1m")));

            //実施
            testTehai.Daiminkan(actor, target, furopai, consumed);

            //フーロオブジェクトの構成が正しいか
            Assert.AreEqual(testTehai.furos[0].ftype, MJUtil.TartsuType.MINKANTSU);
            Assert.AreEqual(testTehai.furos[0].furopai, furopai);
            CollectionAssert.AreEqual(testTehai.furos[0].consumed, consumed);

            //晒した牌が手配に残っていないか
            Assert.IsFalse(testTehai.tehai.Contains(new Pai("1m")));
        }
コード例 #3
0
ファイル: AI.cs プロジェクト: jerry-zeng/JapaneseMahjong
    protected virtual void thinkSutehai(Hai addHai)
    {
        _action.SutehaiIndex = Tehai.getJyunTehaiCount();

        Tehai tehaiCopy = new Tehai(Tehai);

        FormatWorker.setCounterFormat(tehaiCopy, null);
        int maxScore = getCountFormatScore(FormatWorker);

        for (int i = 0; i < tehaiCopy.getJyunTehaiCount(); i++)
        {
            Hai hai = tehaiCopy.removeJyunTehaiAt(i);

            FormatWorker.setCounterFormat(tehaiCopy, addHai);

            int score = getCountFormatScore(FormatWorker);
            if (score > maxScore)
            {
                maxScore             = score;
                _action.SutehaiIndex = i;
            }

            tehaiCopy.insertJyunTehai(i, hai);
        }
    }
コード例 #4
0
        public void 手配暗槓テスト()
        {
            Tehai testTehai = new Tehai(new List <Pai> {
                new Pai("1m"), new Pai("1m"), new Pai("1m")
            });

            //ankan
            var actor    = 0;
            var consumed = new List <Pai> {
                new Pai("1m"), new Pai("1m"), new Pai("1m"), new Pai("1m")
            };

            consumed.Sort();

            Assert.IsTrue(testTehai.tehai.Contains(new Pai("1m")));

            //実施
            testTehai.Ankan(actor, consumed);

            //フーロオブジェクトの構成が正しいか
            Assert.AreEqual(testTehai.furos[0].ftype, MJUtil.TartsuType.ANKANTSU);
            CollectionAssert.AreEqual(testTehai.furos[0].consumed, consumed);

            //晒した牌が手配に残っていないか
            Assert.IsFalse(testTehai.tehai.Contains(new Pai("1m")));
        }
コード例 #5
0
ファイル: AI.cs プロジェクト: jerry-zeng/JapaneseMahjong
    protected virtual void thinkReach()
    {
        _action.ReachSelectIndex = 0;

        List <int> reachHaiIndex = _action.ReachHaiIndexList;

        Tehai tehaiCopy = new Tehai(Tehai);
        int   minScore  = int.MaxValue;

        for (int i = 0; i < reachHaiIndex.Count; i++)
        {
            Hai hai = tehaiCopy.removeJyunTehaiAt(reachHaiIndex[i]);   // reachHaiIndex[i], not i

            List <Hai> machiiHais;
            if (MahjongAgent.tryGetMachiHais(tehaiCopy, out machiiHais))
            {
                for (int m = 0; m < machiiHais.Count; m++)
                {
                    Hai addHai = machiiHais[m];

                    FormatWorker.setCounterFormat(tehaiCopy, addHai);

                    int score = MahjongAgent.getAgariScore(tehaiCopy, addHai, JiKaze);
                    if (score <= minScore)
                    {
                        minScore = score;
                        _action.ReachSelectIndex = i;
                    }
                }
            }

            tehaiCopy.insertJyunTehai(i, hai);
        }
    }
コード例 #6
0
ファイル: AI.cs プロジェクト: jerry-zeng/JapaneseMahjong
    protected virtual void thinkSelectSuteHai()
    {
        thinkSutehai(null);

        if (_action.SutehaiIndex == Tehai.getJyunTehaiCount())
        {
            _action.SutehaiIndex = Utils.GetRandomNum(0, Tehai.getJyunTehaiCount());
        }
    }
コード例 #7
0
ファイル: ShantenCalclator.cs プロジェクト: majiang/MjModel
        public int CalcShanten(Tehai tehai){
            var syu = new int[MJUtil.LENGTH_SYU_ALL];
            foreach (var p in tehai.tehai)
            {
                syu[p.PaiNumber]++;
            }

            return CalcShantenWithFuro(syu, tehai.furos.Count);
        }
コード例 #8
0
ファイル: ShantenCalclator.cs プロジェクト: majiang/MjModel
 public int CalcShanten(Tehai tehai, string pai)
 {
     var syu = new int[MJUtil.LENGTH_SYU_ALL];
     foreach (var p in tehai.tehai)
     {
         syu[p.PaiNumber]++;
     }
     syu[PaiConverter.STRING_TO_ID[pai]]++;
     return CalcShantenWithFuro(syu, tehai.furos.Count);
 }
コード例 #9
0
        public void 手配ツモテスト()
        {
            Tehai testTehai = new Tehai(new List <string> {
                "1m", "2m", "3m", "4m", "5m", "6m", "7m", "8m", "9m", "1s", "2s", "3s", "4s"
            });

            Assert.IsFalse(testTehai.tehai.Contains(new Pai("5s")));
            testTehai.Tsumo(new Pai("5s"));
            Assert.IsTrue(testTehai.tehai.Contains(new Pai("5s")));
        }
コード例 #10
0
ファイル: ShantenCalclator.cs プロジェクト: majiang/MjModel
        public int CalcShanten(Tehai tehai, string pai)
        {
            var syu = new int[MJUtil.LENGTH_SYU_ALL];

            foreach (var p in tehai.tehai)
            {
                syu[p.PaiNumber]++;
            }
            syu[PaiConverter.STRING_TO_ID[pai]]++;
            return(CalcShantenWithFuro(syu, tehai.furos.Count));
        }
コード例 #11
0
ファイル: ShantenCalclator.cs プロジェクト: majiang/MjModel
        public int CalcShanten(Tehai tehai)
        {
            var syu = new int[MJUtil.LENGTH_SYU_ALL];

            foreach (var p in tehai.tehai)
            {
                syu[p.PaiNumber]++;
            }

            return(CalcShantenWithFuro(syu, tehai.furos.Count));
        }
コード例 #12
0
    public bool CheckHaiTypeOver9(Tehai tehai, Hai addHai)
    {
        if (!_game.isChiHou)
        {
            return(false);
        }

        if (tehai.getJyunTehaiCount() < Tehai.JYUN_TEHAI_LENGTH_MAX - 1)
        {
            return(false);
        }


        int[] checkId =
        {
            Hai.ID_WAN_1, Hai.ID_WAN_9, Hai.ID_PIN_1, Hai.ID_PIN_9, Hai.ID_SOU_1, Hai.ID_SOU_9,
            Hai.ID_TON,   Hai.ID_NAN,   Hai.ID_SYA,   Hai.ID_PE,    Hai.ID_HAKU,  Hai.ID_HATSU, Hai.ID_CHUN
        };
        int[] countNumber = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //length = 13

        //手牌をコピーする
        Hai[] checkHais = tehai.getJyunTehai();

        for (int i = 0; i < checkHais.Length; i++)
        {
            for (int j = 0; j < checkId.Length; j++)
            {
                if (checkHais[i].ID == checkId[j])
                {
                    countNumber[j]++;
                }
            }
        }

        for (int j = 0; j < checkId.Length; j++)
        {
            if (addHai.ID == checkId[j])
            {
                countNumber[j]++;
            }
        }

        int totalHaiType = 0;

        for (int c = 0; c < countNumber.Length; c++)
        {
            if (countNumber[c] > 0)
            {
                totalHaiType++;
            }
        }

        return(totalHaiType >= 9);
    }
コード例 #13
0
    // 是否可以听牌,只需要检查一个成立的牌.
    public bool canTenpai(Tehai tehai)
    {
        for (int id = Hai.ID_MIN; id <= Hai.ID_MAX; id++)
        {
            countFormat.setCounterFormat(tehai, new Hai(id));

            if (countFormat.calculateCombisCount(combis) > 0)
            {
                return(true);
            }
        }
        return(false);
    }
コード例 #14
0
ファイル: Hand.cs プロジェクト: tkitada/mahjong
        public TileId Dahai(int index)
        {
            TileId dahai;

            if (index == 13)
            {
                dahai     = TsumoTile;
                TsumoTile = null;
            }
            else
            {
                dahai = Tehai[index];
                Tehai.RemoveAt(index);
                Tehai.Add(TsumoTile);
            }
            return(dahai);
        }
コード例 #15
0
    // hais为听牌列表.
    public bool tryGetMachiHais(Tehai tehai, out List <Hai> hais)
    {
        hais = new List <Hai>();

        for (int id = Hai.ID_MIN; id <= Hai.ID_MAX; id++)
        {
            Hai addHai = new Hai(id);

            countFormat.setCounterFormat(tehai, addHai);

            if (countFormat.calculateCombisCount(combis) > 0)
            {
                hais.Add(addHai);
            }
        }

        return(hais.Count > 0);
    }
コード例 #16
0
ファイル: Tehai.cs プロジェクト: iuvei/mahjong3d
    // 手牌をコピーする
    public static void copy(Tehai dest, Tehai src, bool jyunTehaiCopy)
    {
        if (jyunTehaiCopy == true)
        {
            dest._jyunTehais.Clear();

            for (int i = 0; i < src._jyunTehais.Count; i++)
            {
                dest._jyunTehais.Add(new Hai(src._jyunTehais[i]));
            }
        }

        dest._fuuros.Clear();

        for (int i = 0; i < src._fuuros.Count; i++)
        {
            dest._fuuros.Add(new Fuuro(src._fuuros[i]));
        }
    }
コード例 #17
0
ファイル: TehaiAnalizerTest.cs プロジェクト: majiang/MjModel
        public void 和了時構成分割テスト()
        {
            Tehai testTehai = new Tehai(new List <string> {
                "1m", "2m", "3m", "4m", "5m", "6m", "7m", "7m", "1m", "1m", "2m", "2m", "3m"
            });

            var isRon  = true;
            var result = SplitedTehaiCalclator.CalcSplitedTehai(testTehai, "3m", isRon);

            Debug.WriteLine(result.AllHoraPatternList.Count);
            foreach (var r in result.AllHoraPatternList)
            {
                foreach (var t in r.TartsuList)
                {
                    Debug.WriteLine(t.TartsuType + "," + t.TartsuStartPaiSyu);
                }
                Debug.WriteLine("");
            }

            Assert.AreEqual(result.AllHoraPatternList.Count, 4);//testTehaiは111222333の部分が順子3つのパターンと暗刻3つのパターンがある
        }
コード例 #18
0
ファイル: ResultCalclator.cs プロジェクト: rick0000/MjModel
        public static HoraResult CalcHoraResult(Tehai tehai, InfoForResult ifr, Field field, string horaPai)
        {
            //面子手の取りうる和了形を全て列挙
            SplitedTehai splited = SplitedTehaiCalclator.CalcSplitedTehai(tehai, horaPai, !ifr.IsTsumo );
            List<YakuResult> yakuResultList = new List<YakuResult>();

            int[] realPaiNum = tehai.GetRealPaiNum();
            if (ifr.IsTsumo == false)
            {
                realPaiNum[PaiConverter.STRING_TO_ID[horaPai]]++;
            }
            //面子手和了型が0の場合はチートイツか国士無双
            if (splited.AllHoraPatternList.Count == 0)
            {
                yakuResultList.Add(YakuResultCalclator.CalcSpecialYaku(ifr, field, splited.SyuNum, splited.RedDoraNum));
            }
            else
            {
                //面子手の役を計算
                foreach (var pattern in splited.AllHoraPatternList)
                {
                    yakuResultList.Add(YakuResultCalclator.CalcNormalYaku(pattern, ifr, field, splited.SyuNum, realPaiNum, splited.RedDoraNum));
                }
            }

            Dictionary<YakuResult, PointResult> pointResultMap = new Dictionary<YakuResult, PointResult>();
            foreach (var yakuResult in yakuResultList)
            {
                //役と符から点数を計算
                pointResultMap.Add(yakuResult, PointResultCalclator.AnalyzePoint(yakuResult));
            }

            //一番点数が高い和了形の役と点数を返却
            var maxMap = pointResultMap.OrderBy(e => e.Value.HoraPlayerIncome).Last();
            HoraResult maxResult = new HoraResult();
            maxResult.yakuResult = maxMap.Key;
            maxResult.pointResult = maxMap.Value;

            return maxResult;
        }
コード例 #19
0
        public static SplitedTehai CalcSplitedTehai(Tehai tehai, string horaPai, bool isRon)
        {
            //手配&和了牌の牌の合計枚数をカウント
            int[] inHandSyu = new int[MJUtil.LENGTH_SYU_ALL];
            foreach (var pai in tehai.tehai)
            {
                inHandSyu[pai.PaiNumber]++;
            }
            if (isRon)
            {
                inHandSyu[PaiConverter.STRING_TO_ID[horaPai]]++;
            }

            TehaiSpliter ts = new TehaiSpliter();

            //手に残っている手配のターツ構成を全て算出
            var splited = ts.SplitTehai(inHandSyu, tehai.furos, horaPai, isRon);

            foreach (var furopai in tehai.furos)
            {
                switch (furopai.ftype)
                {
                case MJUtil.TartsuType.MINSYUN:
                    splited.SyuNum[furopai.minPaiSyu]++;
                    splited.SyuNum[furopai.minPaiSyu + 1]++;
                    splited.SyuNum[furopai.minPaiSyu + 2]++;
                    break;

                case MJUtil.TartsuType.MINKO:
                    splited.SyuNum[furopai.minPaiSyu] += 3;
                    break;

                case MJUtil.TartsuType.MINKANTSU:
                    splited.SyuNum[furopai.minPaiSyu] += 4;
                    break;
                }
            }

            return(splited);
        }
コード例 #20
0
        public static SplitedTehai CalcSplitedTehai(Tehai tehai, string horaPai, bool isRon)
        {

            //手配&和了牌の牌の合計枚数をカウント
            int[] inHandSyu = new int[MJUtil.LENGTH_SYU_ALL];
            foreach (var pai in tehai.tehai)
            {
                inHandSyu[pai.PaiNumber]++;
            }
            if (isRon)
            {
                inHandSyu[PaiConverter.STRING_TO_ID[horaPai]]++;
            }

            TehaiSpliter ts = new TehaiSpliter();

            //手に残っている手配のターツ構成を全て算出
            var splited = ts.SplitTehai(inHandSyu, tehai.furos, horaPai, isRon);

            foreach (var furopai in tehai.furos)
            {
                switch (furopai.ftype)
                {
                    case MJUtil.TartsuType.MINSYUN:
                        splited.SyuNum[furopai.minPaiSyu]++;
                        splited.SyuNum[furopai.minPaiSyu + 1]++;
                        splited.SyuNum[furopai.minPaiSyu + 2]++;
                        break;
                    case MJUtil.TartsuType.MINKO:
                        splited.SyuNum[furopai.minPaiSyu] += 3;
                        break;
                    case MJUtil.TartsuType.MINKANTSU:
                        splited.SyuNum[furopai.minPaiSyu] += 4;
                        break;
                }
            }

            return splited;
        }
コード例 #21
0
ファイル: ResultCalclator.cs プロジェクト: majiang/MjModel
        public static HoraResult CalcHoraResult(Tehai tehai, InfoForResult ifr, Field field, string horaPai)
        {
            //面子手の取りうる和了形を全て列挙
            SplitedTehai      splited        = SplitedTehaiCalclator.CalcSplitedTehai(tehai, horaPai, !ifr.IsTsumo);
            List <YakuResult> yakuResultList = new List <YakuResult>();

            //面子手和了型が0の場合はチートイツか国士無双
            if (splited.AllHoraPatternList.Count == 0)
            {
                yakuResultList.Add(YakuResultCalclator.CalcSpecialYaku(ifr, field, splited.SyuNum));
            }
            else
            {
                //面子手の役を計算
                foreach (var pattern in splited.AllHoraPatternList)
                {
                    yakuResultList.Add(YakuResultCalclator.CalcNormalYaku(pattern, ifr, field, splited.SyuNum));
                }
            }

            Dictionary <YakuResult, PointResult> pointResultMap = new Dictionary <YakuResult, PointResult>();

            foreach (var yakuResult in yakuResultList)
            {
                //役と符から点数を計算
                pointResultMap.Add(yakuResult, PointResultCalclator.AnalyzePoint(yakuResult));
            }


            //一番点数が高い和了形の役と点数を返却
            var        maxMap    = pointResultMap.OrderBy(e => e.Value.HoraPlayerIncome).Last();
            HoraResult maxResult = new HoraResult();

            maxResult.yakuResult  = maxMap.Key;
            maxResult.pointResult = maxMap.Value;

            return(maxResult);
        }
コード例 #22
0
ファイル: TehaiAnalizerTest.cs プロジェクト: majiang/MjModel
        public void 役算出テスト()
        {
            //清一色ピンフ一盃口
            {
                Tehai testTehai = new Tehai(new List <string> {
                    "1m", "2m", "3m", "4m", "5m", "6m", "7m", "7m", "1m", "2m", "2m", "3m", "3m", "4m"
                });

                var lastAdded = "4m";
                var testIfr   = new InfoForResult();
                testIfr.IsMenzen   = true;
                testIfr.IsOya      = true;
                testIfr.IsTsumo    = true;
                testIfr.PassedTurn = 10;
                testIfr.SetLastAddedPai(lastAdded);
                var result = new HoraResult();
                result = ResultCalclator.CalcHoraResult(testTehai, testIfr, new Field(), lastAdded);
                var yakuMap = result.yakuResult.yakus;
                Assert.IsTrue(yakuMap.ContainsKey(MJUtil.YAKU_STRING[(int)MJUtil.Yaku.CHINNITSU]));
                Assert.IsTrue(yakuMap.ContainsKey(MJUtil.YAKU_STRING[(int)MJUtil.Yaku.PINFU]));
                Assert.IsTrue(yakuMap.ContainsKey(MJUtil.YAKU_STRING[(int)MJUtil.Yaku.IIPEIKOU]));
            }
        }
コード例 #23
0
    public int GetAgariScore(Tehai tehai, Hai addHai, EKaze jikaze, AgariParam param = null)
    {
        if (param == null)
        {
            param = AgariParam;
            param.ResetDoraHais();
        }

        param.setBakaze(getBaKaze());
        param.setJikaze(jikaze);

        param.ResetYakuFlags(); // should reset params or create a new.

        if (m_activePlayer.IsReach)
        {
            if (m_activePlayer.IsDoubleReach)
            {
                param.setYakuFlag(EYakuFlagType.DOUBLE_REACH, true);
            }
            else
            {
                param.setYakuFlag(EYakuFlagType.REACH, true);
            }
        }

        if (m_isTsumo)
        {
            param.setYakuFlag(EYakuFlagType.TSUMO, true);

            if (m_isTenhou)
            {
                param.setYakuFlag(EYakuFlagType.TENHOU, true);
            }
            else if (m_isChihou)
            {
                param.setYakuFlag(EYakuFlagType.TIHOU, true);
            }
        }
        else if (m_isRenhou)
        {
            if (getPlayerIndex(jikaze) != OyaIndex)    // only ko can Renhou.
            {
                param.setYakuFlag(EYakuFlagType.RENHOU, true);
            }
        }

        if (m_isTsumo && m_isRinshan)
        {
            param.setYakuFlag(EYakuFlagType.RINSYAN, true);
        }

        if (m_isChanKan)
        {
            param.setYakuFlag(EYakuFlagType.CHANKAN, true);
        }

        if (m_isLast)
        {
            if (m_isTsumo)
            {
                param.setYakuFlag(EYakuFlagType.HAITEI, true);
            }
            else
            {
                param.setYakuFlag(EYakuFlagType.HOUTEI, true);
            }
        }

        if (m_activePlayer.IsIppatsu)
        {
            param.setYakuFlag(EYakuFlagType.IPPATU, true);
        }

        if (GameSettings.UseKuitan)
        {
            param.setYakuFlag(EYakuFlagType.KUITAN, true);
        }

        return(AgariScoreManager.GetAgariScore(tehai, addHai, param, ref m_combis, ref m_agariInfo));
    }
コード例 #24
0
 public int CalcShanten(Tehai tehai)
 {
     return sf.CalcShanten(tehai);
 }
コード例 #25
0
 public int CalcShanten(Tehai tehai, string pai)
 {
     return sf.CalcShanten(tehai, pai);
 }
コード例 #26
0
    /*
     * // 流局满贯 //
     * public static void SetNagashiMangan(AgariInfo agariInfo)
     * {
     * agariInfo.han = 5;
     * agariInfo.fu = 30;
     * agariInfo.scoreInfo = GetScoreInfo(5, 30);
     *
     * agariInfo.hanteiYakus = new YakuHelper.YakuHandler[]
     * {
     *  new YakuHelper.CheckNagashimangan(null)
     * };
     * }
     */

    // 符を計算します
    public static int CalculateHu(Tehai tehai, Hai addHai, HaiCombi combi, AgariParam param, Yaku yaku)
    {
        int countHu = 20;

        //頭の牌を取得
        Hai atamaHai = new Hai(Hai.NumKindToID(combi.atamaNumKind));

        // 3元牌なら2符追加
        if (atamaHai.Kind == Hai.KIND_SANGEN)
        {
            countHu += 2;
        }

        // 場風なら2符追加
        if ((atamaHai.ID - Hai.ID_TON) == (int)param.getBakaze())
        {
            countHu += 2;
        }

        // 自風なら2符追加
        if ((atamaHai.ID - Hai.ID_TON) == (int)param.getJikaze())
        {
            countHu += 2;
        }

        //平和が成立する場合は、待ちによる2符追加よりも優先される
        if (yaku.checkPinfu() == false)
        {
            // 単騎待ちの場合2符追加
            if (addHai.NumKind == combi.atamaNumKind)
            {
                countHu += 2;
            }

            // 嵌張待ちの場合2符追加
            // 数牌の2~8かどうか判定
            if (addHai.IsYaochuu == false)
            {
                for (int i = 0; i < combi.shunCount; i++)
                {
                    if ((addHai.NumKind - 1) == combi.shunNumKinds[i])
                    {
                        countHu += 2;
                    }
                }
            }

            // 辺張待ち(3)の場合2符追加
            if (addHai.IsYaochuu == false && addHai.Num == Hai.NUM_3)
            {
                for (int i = 0; i < combi.shunCount; i++)
                {
                    if ((addHai.NumKind - 2) == combi.shunNumKinds[i])
                    {
                        countHu += 2;
                    }
                }
            }

            // 辺張待ち(7)の場合2符追加
            if (addHai.IsYaochuu == false && addHai.Num == Hai.NUM_7)
            {
                for (int i = 0; i < combi.shunCount; i++)
                {
                    if (addHai.NumKind == combi.shunNumKinds[i])
                    {
                        countHu += 2;
                    }
                }
            }
        }

        // 暗刻による加点
        Hai checkHai = null;

        for (int i = 0; i < combi.kouCount; i++)
        {
            checkHai = new Hai(Hai.NumKindToID(combi.kouNumKinds[i]));

            // 牌が字牌もしくは1,9
            if (checkHai.IsYaochuu == true)
            {
                countHu += 8;
            }
            else
            {
                countHu += 4;
            }
        }


        Fuuro[] fuuros = tehai.getFuuros();

        for (int i = 0; i < fuuros.Length; i++)
        {
            switch (fuuros[i].Type)
            {
            case EFuuroType.MinKou:
            {
                // 牌が字牌もしくは1,9
                if (fuuros[i].Hais[0].IsYaochuu == true)
                {
                    countHu += 4;
                }
                else
                {
                    countHu += 2;
                }
            }
            break;

            case EFuuroType.KaKan:
            case EFuuroType.DaiMinKan:
            {
                // 牌が字牌もしくは1,9
                if (fuuros[i].Hais[0].IsYaochuu == true)
                {
                    countHu += 16;
                }
                else
                {
                    countHu += 8;
                }
            }
            break;

            case EFuuroType.AnKan:
            {
                // 牌が字牌もしくは1,9
                if (fuuros[i].Hais[0].IsYaochuu == true)
                {
                    countHu += 32;
                }
                else
                {
                    countHu += 16;
                }
            }
            break;
            }
        }

        // ツモ上がりで平和が成立していなければ2譜追加
        if (param.getYakuFlag(EYakuFlagType.TSUMO) == true)
        {
            if (yaku.checkPinfu() == false)
            {
                countHu += 2;
            }
        }

        // 面前ロン上がりの場合は10符追加
        if (param.getYakuFlag(EYakuFlagType.TSUMO) == false)
        {
            if (yaku.isNaki == false)
            {
                countHu += 10;
            }
        }

        // 一の位がある場合は、切り上げ
        if (countHu % 10 != 0)  // 23 -> 30.
        {
            countHu = countHu - (countHu % 10) + 10;
        }

        return(countHu);
    }
コード例 #27
0
    public static int GetAgariScore(Tehai tehai, Hai addHai, AgariParam param, ref HaiCombi[] combis, ref AgariInfo agariInfo)
    {
        formatWorker.setCounterFormat(tehai, addHai);

        // あがりの組み合わせを取得します
        int combisCount = formatWorker.calculateCombisCount(combis);

        //Debug.Log ("GetAgariScore() combisCount="+combisCount);
        combis = formatWorker.getCombis();

        /*
         * /// 1. check Chiitoitsu(七对子)
         * if( formatWorker.isChiitoitsu() )
         * {
         * Yaku yaku = Yaku.NewYaku_Chiitoitsu(tehai, addHai, param);
         *
         * agariInfo.han = yaku.getHan();
         * agariInfo.fu = 25;
         * agariInfo.hanteiYakus = yaku.getHanteiYakus();
         *
         * agariInfo.scoreInfo = GetScoreInfo(agariInfo.han, agariInfo.fu);
         *
         * return agariInfo.scoreInfo.koAgari;
         * }
         */
        /*
         * /// 2. check Kokushi(国士无双)
         * if( formatWorker.isKokushi() )
         * {
         * Yaku yaku = Yaku.NewYaku_Kokushi(tehai, addHai, param);
         *
         * if( yaku.isKokushi )
         * {
         * agariInfo.han = 13;
         * agariInfo.fu = 20;
         * agariInfo.hanteiYakus = yaku.getHanteiYakus();
         *
         * agariInfo.scoreInfo = GetScoreInfo(agariInfo.han, agariInfo.fu);
         *
         * return agariInfo.scoreInfo.koAgari;
         * }
         *
         * return 0;
         * }
         */
        //return combisCount;

        /// 3. check common combi yaku.
        if (combisCount <= 0)
        {
            return(0);
        }

        int[] hanSuuArr = new int[combisCount];         // 役 計算台數
        //int[] huSuuArr  = new int[combisCount]; // 符
        //int[] scoreArr = new int[combisCount]; // 点数(子のロン上がり)

        int maxAgariScore = 0; // 最大の点数

        for (int i = 0; i < combisCount; i++)
        {
            Yaku yaku = Yaku.NewYaku_Common(tehai, addHai, combis[i], param);
            hanSuuArr[i] = yaku.calculateHanSuu();//計算台數
            //maxAgariScore += hanSuuArr[i];
            //huSuuArr[i] = CalculateHu(tehai, addHai, combis[i], param, yaku);

            //Score scoreInfo = GetScoreInfo(hanSuuArr[i], huSuuArr[i]);

            //scoreArr[i] = scoreInfo.koAgari;

            if (hanSuuArr[i] > maxAgariScore)
            {
                agariInfo.han = hanSuuArr[i];
                //agariInfo.fu = huSuuArr[i];
                agariInfo.hanteiYakus = yaku.getHanteiYakus();

                //agariInfo.scoreInfo = scoreInfo;

                maxAgariScore = hanSuuArr[i];
            }
        }
        //agariInfo.han = maxAgariScore;
        //agariInfo.fu = 0;
        //agariInfo.scoreInfo = GetScoreInfo(5, 30);

        //agariInfo.hanteiYakus = yaku.getHanteiYakus();
        // 最大値を探す
        //maxAgariScore = 0;

        //for(int i = 0; i < combisCount; i++)
        //{
        //    if( scoreArr[i] > maxAgariScore )
        //        maxAgariScore = scoreArr[i];
        //}
        //return maxAgariScore;
        return(combisCount);
    }
コード例 #28
0
ファイル: CountFormat.cs プロジェクト: iuvei/mahjong3d
    /// <summary>
    /// Calculate all hai's count in tehai. the 'tehai' should be sorted.
    /// </summary>

    public void setCounterFormat(Tehai tehai, Hai addHai)
    {
        _counterArr.Clear();


        int  addHaiNumKind = 0;
        bool set           = true;

        if (addHai != null)
        {
            addHaiNumKind = addHai.NumKind;
            set           = false;
        }

        Hai[] jyunTehais = tehai.getJyunTehai();

        for (int i = 0; i < jyunTehais.Length;)
        {
            int jyunTehaiNumKind = jyunTehais[i].NumKind;

            // if the first one hai's NK is bigger than the addHai's,
            // add the addHai to _counterArr firstly, then re-check the first one(as no i++).
            if (set == false && jyunTehaiNumKind > addHaiNumKind)
            {
                _counterArr.Add(new HaiCounterInfo(addHaiNumKind, 1));
                set = true;

                continue;
            }

            // in middle range of tehai there exsits one as the same to addHai
            _counterArr.Add(new HaiCounterInfo(jyunTehaiNumKind, 1));
            if (set == false && jyunTehaiNumKind == addHaiNumKind)
            {
                _counterArr[_counterArr.Count - 1].count++;
                set = true;
            }

            // check if the after one(at i+1) is the same to current one at 'i'
            while (++i < jyunTehais.Length)
            {
                if (jyunTehaiNumKind == jyunTehais[i].NumKind)
                {
                    _counterArr[_counterArr.Count - 1].count++;
                }
                else
                {
                    break;
                }
            }
        }

        // the addHai is the biggest one.
        if (set == false)
        {
            _counterArr.Add(new HaiCounterInfo(addHaiNumKind, 1));
        }

        for (int i = 0; i < _counterArr.Count; i++)
        {
            if (_counterArr[i].count > MENTSU_LENGTH_MAX)
            {
                _counterArr[i].count = MENTSU_LENGTH_MAX;
            }
        }
    }
コード例 #29
0
ファイル: Hand.cs プロジェクト: tkitada/mahjong
 public void Dahai(TileId dahai)
 {
     Tehai.Remove(dahai);
     Tehai.Add(TsumoTile);
 }
コード例 #30
0
    protected override EResponse OnHandle_TsumoHai(EKaze fromPlayerKaze, Hai haiToHandle)
    {
        _action.Reset();
        _action.State = EActionState.Select_Sutehai;

        if (inTest)
        {
            //_action.State = EActionState.Select_Sutehai;
            //return DisplayMenuList();
        }

        // 手牌をコピーする。
        Hai tsumoHai = haiToHandle;

        // check enable Tsumo
        int agariScore = MahjongAgent.getAgariScore(Tehai, tsumoHai, JiKaze);

        if (agariScore > 0)
        {
            if (GameSettings.AllowFuriten || !isFuriten())
            {
                _action.IsValidTsumo = true;
                _action.MenuList.Add(EActionType.Tsumo);

                if (MahjongAgent.isReach(JiKaze))
                {
                    return(DisplayMenuList());
                }
            }
            else
            {
                Utils.LogWarningFormat("Player {0} is enable tsumo but furiten...", JiKaze.ToString());
            }
        }

        // 九种九牌check
        if (MahjongAgent.CheckHaiTypeOver9(Tehai, tsumoHai))
        {
            _action.MenuList.Add(EActionType.RyuuKyoku);
        }

        // check enable Reach
        if (CheckReachPreConditions() == true)
        {
            List <int> reachHaiIndexList;
            if (MahjongAgent.tryGetReachHaiIndex(Tehai, tsumoHai, out reachHaiIndexList))
            {
                _action.IsValidReach      = true;
                _action.ReachHaiIndexList = reachHaiIndexList;
                _action.MenuList.Add(EActionType.Reach);
            }
        }

        // 制限事項。リーチ後のカンをさせない
        if (!MahjongAgent.isReach(JiKaze))
        {
            if (MahjongAgent.getTotalKanCount() < GameSettings.KanCountMax)
            {
                // tsumo kans
                List <Hai> kanHais = new List <Hai>();
                if (Tehai.validAnyTsumoKan(tsumoHai, kanHais))
                {
                    _action.setValidTsumoKan(true, kanHais);

                    _action.MenuList.Add(EActionType.Kan);
                }
            }
        }
        else
        {
            if (MahjongAgent.getTotalKanCount() < GameSettings.KanCountMax)
            {
                // if player machi hais won't change after setting AnKan, enable to to it.
                if (Tehai.validAnKan(tsumoHai))
                {
                    List <Hai> machiHais;
                    if (MahjongAgent.tryGetMachiHais(Tehai, out machiHais))
                    {
                        Tehai tehaiCopy = new Tehai(Tehai);
                        tehaiCopy.setAnKan(tsumoHai);
                        tehaiCopy.Sort();

                        List <Hai> newMachiHais;

                        if (MahjongAgent.tryGetMachiHais(tehaiCopy, out newMachiHais))
                        {
                            if (machiHais.Count == newMachiHais.Count)
                            {
                                machiHais.Sort(Tehai.Compare);
                                newMachiHais.Sort(Tehai.Compare);

                                bool enableAnkan = true;

                                for (int i = 0; i < machiHais.Count; i++)
                                {
                                    if (machiHais[i].ID != newMachiHais[i].ID)
                                    {
                                        enableAnkan = false;
                                        break;
                                    }
                                }

                                if (enableAnkan == true)
                                {
                                    _action.setValidTsumoKan(true, new List <Hai>()
                                    {
                                        tsumoHai
                                    });

                                    _action.MenuList.Add(EActionType.Kan);
                                    _action.MenuList.Add(EActionType.Nagashi);

                                    _action.State = EActionState.Select_Kan;
                                }
                            }
                        }
                    }
                } // end if(valid ankan)
            }     // end kan count check

            // can Ron or Ankan, sute hai automatically.
            if (_action.MenuList.Count == 0)
            {
                _action.SutehaiIndex = Tehai.getJyunTehaiCount(); // sute the tsumo hai on Reach

                return(DoResponse(EResponse.SuteHai));
            }
        }

        // always display menu on pick tsumo hai.
        return(DisplayMenuList());
    }
コード例 #31
0
    protected override EResponse OnHandle_SuteHai(EKaze fromPlayerKaze, Hai haiToHandle)
    {
        _action.Reset();

        if (inTest)
        {
            //_action.MenuList.Add(EActionType.Nagashi);
            //return DisplayMenuList();
        }

        Hai suteHai = haiToHandle;

        // check Ron
        int agariScore = MahjongAgent.getAgariScore(Tehai, suteHai, JiKaze);

        if (agariScore > 0)  // Ron
        {
            if (GameSettings.AllowFuriten || !isFuriten())
            {
                _action.IsValidRon = true;
                _action.MenuList.Add(EActionType.Ron);

                if (MahjongAgent.isReach(JiKaze))
                {
                    //_action.MenuList.Add( EActionType.Nagashi );
                    return(DisplayMenuList());
                }
                else
                {
                    _action.MenuList.Add(EActionType.Nagashi);
                }
            }
            else
            {
                Utils.LogWarningFormat("Player {0} is enable to ron but furiten...", JiKaze.ToString());
            }
        }

        if (MahjongAgent.getTsumoRemain() <= 0)
        {
            return(DoResponse(EResponse.Nagashi));
        }

        if (MahjongAgent.isReach(JiKaze))
        {
            return(DoResponse(EResponse.Nagashi));
        }


        // check menu Kan
        if (MahjongAgent.getTotalKanCount() < GameSettings.KanCountMax)
        {
            if (Tehai.validDaiMinKan(suteHai))
            {
                _action.IsValidDaiMinKan = true;
                _action.MenuList.Add(EActionType.Kan);
            }
        }

        // check menu Pon
        if (Tehai.validPon(suteHai))
        {
            _action.IsValidPon = true;
            _action.MenuList.Add(EActionType.Pon);
        }

        // check menu Chii
        int relation = Mahjong.getRelation(fromPlayerKaze, JiKaze);

        if (relation == (int)ERelation.KaMiCha)
        {
            List <Hai> sarashiHaiRight = new List <Hai>();
            if (Tehai.validChiiRight(suteHai, sarashiHaiRight))
            {
                _action.setValidChiiRight(true, sarashiHaiRight);

                if (!_action.MenuList.Contains(EActionType.Chii))
                {
                    _action.MenuList.Add(EActionType.Chii);
                }
            }

            List <Hai> sarashiHaiCenter = new List <Hai>();
            if (Tehai.validChiiCenter(suteHai, sarashiHaiCenter))
            {
                _action.setValidChiiCenter(true, sarashiHaiCenter);

                if (!_action.MenuList.Contains(EActionType.Chii))
                {
                    _action.MenuList.Add(EActionType.Chii);
                }
            }

            List <Hai> sarashiHaiLeft = new List <Hai>();
            if (Tehai.validChiiLeft(suteHai, sarashiHaiLeft))
            {
                _action.setValidChiiLeft(true, sarashiHaiLeft);

                if (!_action.MenuList.Contains(EActionType.Chii))
                {
                    _action.MenuList.Add(EActionType.Chii);
                }
            }
        }

        if (_action.MenuList.Count > 0)
        {
            _action.MenuList.Add(EActionType.Nagashi);
            return(DisplayMenuList());
        }

        return(DoResponse(EResponse.Nagashi));
    }
コード例 #32
0
ファイル: TehaiAnalizerTest.cs プロジェクト: majiang/MjModel
        public void 点数算出テスト()
        {
            //親40符3翻 ダブ東 ツモ 7800点
            {
                var expected = 7800;
                var tehai    = new Tehai(new List <string>()
                {
                    "1m", "2m", "3m", "4p", "5p", "6p", "7p", "7p", "7p", "9p", "9p", "E", "E", "E"
                });

                var gameId         = 0;
                var playerPosition = 0;
                var lastAddedPai   = "E";

                var ifr = new InfoForResult(gameId, playerPosition);
                ifr.IsTsumo    = true;
                ifr.IsFured    = false;
                ifr.IsMenzen   = true;
                ifr.PassedTurn = 4;
                ifr.SetLastAddedPai(lastAddedPai);
                var fd = new Field();

                var result = ResultCalclator.CalcHoraResult(tehai, ifr, fd, lastAddedPai);
                Assert.AreEqual(expected, result.pointResult.HoraPlayerIncome);
            }

            //親50符2翻 ツモ 三暗刻
            {
                var expected = 9600;
                var tehai    = new Tehai(new List <string>()
                {
                    "1m", "1m", "1m", "2p", "2p", "2p", "4p", "5p", "5p", "5p", "6p", "E", "E", "5p"
                });

                var gameId         = 0;
                var playerPosition = 0;
                var lastAddedPai   = "5p";

                var ifr = new InfoForResult(gameId, playerPosition);
                ifr.IsTsumo    = true;
                ifr.IsFured    = false;
                ifr.IsMenzen   = true;
                ifr.PassedTurn = 4;
                ifr.SetLastAddedPai(lastAddedPai);
                var fd = new Field();

                var result = ResultCalclator.CalcHoraResult(tehai, ifr, fd, lastAddedPai);
                Assert.AreEqual(expected, result.pointResult.HoraPlayerIncome);
            }

            //子20符2翻 タンピン
            {
                var expected = 2000;
                var tehai    = new Tehai(new List <string>()
                {
                    "2m", "3m", "4m", "2p", "3p", "4p", "4p", "5p", "6p", "4s", "5s", "8s", "8s"
                });

                var gameId         = 0;
                var playerPosition = 1;
                var lastAddedPai   = "6s";

                var ifr = new InfoForResult(gameId, playerPosition);
                ifr.IsTsumo    = false;
                ifr.IsFured    = false;
                ifr.IsMenzen   = true;
                ifr.PassedTurn = 4;
                var fd = new Field();
                ifr.SetLastAddedPai(lastAddedPai);
                var result = ResultCalclator.CalcHoraResult(tehai, ifr, fd, lastAddedPai);
                Assert.AreEqual(expected, result.pointResult.HoraPlayerIncome);
            }


            //子20符3翻 タンヤオ三食一盃口
            {
                var expected = 8000;
                var tehai    = new Tehai(new List <string>()
                {
                    "2m", "3m", "4m", "2p", "3p", "4p", "2p", "4p", "5s", "5s", "2s", "3s", "4s"
                });

                var gameId         = 0;
                var playerPosition = 1;
                var lastAddedPai   = "3p";

                var ifr = new InfoForResult(gameId, playerPosition);
                ifr.IsTsumo    = false;
                ifr.IsFured    = false;
                ifr.IsMenzen   = true;
                ifr.PassedTurn = 4;
                var fd = new Field();
                ifr.SetLastAddedPai(lastAddedPai);
                var result = ResultCalclator.CalcHoraResult(tehai, ifr, fd, lastAddedPai);
                Assert.AreEqual(expected, result.pointResult.HoraPlayerIncome);
            }

            //子40符1翻 自摸
            {
                var expected = 1500;
                var tehai    = new Tehai(new List <string>()
                {
                    "1m", "2m", "3m", "3m", "4m", "5m", "1p", "1p", "1p", "2s", "3s", "4s", "5s", "5s"
                });

                var gameId         = 0;
                var playerPosition = 1;
                var lastAddedPai   = "3m";

                var ifr = new InfoForResult(gameId, playerPosition);
                ifr.IsTsumo    = true;
                ifr.IsFured    = false;
                ifr.IsMenzen   = true;
                ifr.PassedTurn = 4;
                var fd = new Field();
                ifr.SetLastAddedPai(lastAddedPai);
                var result = ResultCalclator.CalcHoraResult(tehai, ifr, fd, lastAddedPai);
                Assert.AreEqual(expected, result.pointResult.HoraPlayerIncome);
            }

            //子50符2翻 ロン
            {
                var expected = 3200;
                var tehai    = new Tehai(new List <string>()
                {
                    "1m", "1m", "1m", "2m", "2m", "2m", "1p", "1p", "1p", "2p", "3p", "4s", "4s"
                });

                var gameId         = 0;
                var playerPosition = 1;
                var lastAddedPai   = "1p";

                var ifr = new InfoForResult(gameId, playerPosition);
                ifr.IsTsumo    = false;
                ifr.IsFured    = false;
                ifr.IsMenzen   = true;
                ifr.PassedTurn = 4;
                var fd = new Field();
                ifr.SetLastAddedPai(lastAddedPai);
                var result = ResultCalclator.CalcHoraResult(tehai, ifr, fd, lastAddedPai);
                Assert.AreEqual(expected, result.pointResult.HoraPlayerIncome);
            }
        }
コード例 #33
0
ファイル: AI.cs プロジェクト: jerry-zeng/JapaneseMahjong
    protected override EResponse OnHandle_TsumoHai(EKaze fromPlayerKaze, Hai haiToHandle)
    {
        _action.Reset();

        if (inTest)
        {
            _action.SutehaiIndex = Tehai.getJyunTehaiCount();
            return(DoResponse(EResponse.SuteHai));
        }

        Hai tsumoHai = haiToHandle;

        // ツモあがりの場合は、イベント(ツモあがり)を返す。
        int agariScore = MahjongAgent.getAgariScore(Tehai, tsumoHai, JiKaze);

        if (agariScore > 0)
        {
            if (GameSettings.AllowFuriten || !isFuriten())
            {
                return(DoResponse(EResponse.Tsumo_Agari));
            }
            else
            {
                Utils.LogWarningFormat("AI {0} is enable tsumo but furiten...", JiKaze.ToString());
            }
        }

        // 九种九牌check
        if (MahjongAgent.CheckHaiTypeOver9(Tehai, tsumoHai))
        {
            return(DoResponse(EResponse.Nagashi));
        }

        // リーチの場合は、ツモ切りする
        if (MahjongAgent.isReach(JiKaze))
        {
            _action.SutehaiIndex = Tehai.getJyunTehaiCount();

            return(DoResponse(EResponse.SuteHai));
        }

        // check enable Reach
        if (CheckReachPreConditions() == true)
        {
            List <int> reachHaiIndexList;
            if (MahjongAgent.tryGetReachHaiIndex(Tehai, tsumoHai, out reachHaiIndexList))
            {
                _action.IsValidReach      = true;
                _action.ReachHaiIndexList = reachHaiIndexList;

                thinkReach();

                return(DoResponse(EResponse.Reach));
            }
        }

        // 制限事項。リーチ後のカンをさせない
        if (!MahjongAgent.isReach(JiKaze))
        {
            /*
             * if( MahjongAgent.getTotalKanCount() < GameSettings.KanCountMax )
             * {
             *  // TODO: tsumo kans
             *  List<Hai> kanHais = new List<Hai>();
             *  if( Tehai.validAnyTsumoKan(tsumoHai, kanHais) )
             *  {
             *      _action.setValidTsumoKan(true, kanHais);
             *
             *  }
             * }
             */
        }
        else
        {
            if (MahjongAgent.getTotalKanCount() < GameSettings.KanCountMax)
            {
                // if player machi hais won't change after setting AnKan, enable to to it.
                if (Tehai.validAnKan(tsumoHai))
                {
                    List <Hai> machiHais;
                    if (MahjongAgent.tryGetMachiHais(Tehai, out machiHais))
                    {
                        Tehai tehaiCopy = new Tehai(Tehai);
                        tehaiCopy.setAnKan(tsumoHai);
                        tehaiCopy.Sort();

                        List <Hai> newMachiHais;

                        if (MahjongAgent.tryGetMachiHais(tehaiCopy, out newMachiHais))
                        {
                            if (machiHais.Count == newMachiHais.Count)
                            {
                                machiHais.Sort(Tehai.Compare);
                                newMachiHais.Sort(Tehai.Compare);

                                bool enableAnkan = true;

                                for (int i = 0; i < machiHais.Count; i++)
                                {
                                    if (machiHais[i].ID != newMachiHais[i].ID)
                                    {
                                        enableAnkan = false;
                                        break;
                                    }
                                }

                                if (enableAnkan == true)
                                {
                                    _action.setValidTsumoKan(true, new List <Hai>()
                                    {
                                        tsumoHai
                                    });
                                    return(DoResponse(EResponse.Ankan));
                                }
                            }
                        }
                    }
                }
            }

            // can Ron or Ankan, sute hai automatically.
            _action.SutehaiIndex = Tehai.getJyunTehaiCount(); // sute the tsumo hai on Reach

            return(DoResponse(EResponse.SuteHai));
        }


        thinkSutehai(tsumoHai);

        return(DoResponse(EResponse.SuteHai));
    }
コード例 #34
0
 // あがり点を取得する
 public int getAgariScore(Tehai tehai, Hai addHai, EKaze jikaze)
 {
     return(_game.GetAgariScore(tehai, addHai, jikaze));
 }
コード例 #35
0
    // 打哪些牌可以立直.
    public bool tryGetReachHaiIndex(Tehai a_tehai, Hai tsumoHai, out List <int> haiIndexList)
    {
        haiIndexList = new List <int>();

        // 鳴いている場合は、リーチできない。x
        //if( a_tehai.isNaki() )
        //    return false;

        /// find all reach-enabled hais in a_tehai, also the tsumoHai.
        _reachHaiList.Clear();


        // As _jyunTehais won't sort automatically on new hais added,
        // so we can add tsumo hai directly to simplify the checks.
        Tehai tehai_copy = new Tehai(a_tehai);

        tehai_copy.addJyunTehai(tsumoHai);
        tehai_copy.Sort();

        Hai[] jyunTehai = tehai_copy.getJyunTehai();

        for (int i = 0; i < jyunTehai.Length; i++)
        {
            Hai haiTemp = tehai_copy.removeJyunTehaiAt(i);

            for (int id = Hai.ID_MIN; id <= Hai.ID_MAX; id++)
            {
                countFormat.setCounterFormat(tehai_copy, new Hai(id));

                if (countFormat.calculateCombisCount(combis) > 0)
                {
                    _reachHaiList.Add(new Hai(haiTemp));
                    break;
                }
            }

            tehai_copy.insertJyunTehai(i, haiTemp);
        }


        /// transfer to index list.
        if (_reachHaiList.Count > 0)
        {
            jyunTehai = a_tehai.getJyunTehai();

            for (int i = 0; i < _reachHaiList.Count; i++)
            {
                for (int j = 0; j < jyunTehai.Length; j++)
                {
                    if (jyunTehai[j].ID == _reachHaiList[i].ID && !haiIndexList.Contains(j))
                    {
                        haiIndexList.Add(j);
                    }
                }

                if (tsumoHai.ID == _reachHaiList[i].ID && !haiIndexList.Contains(jyunTehai.Length))
                {
                    haiIndexList.Add(jyunTehai.Length);
                }
            }
            haiIndexList.Sort();

            return(true);
        }

        return(false);
    }
コード例 #36
0
    public static int GetAgariScore(Tehai tehai, Hai addHai, AgariParam param, ref HaiCombi[] combis, ref AgariInfo agariInfo)
    {
        formatWorker.setCounterFormat(tehai, addHai);

        // あがりの組み合わせを取得します
        int combisCount = formatWorker.calculateCombisCount(combis);

        combis = formatWorker.getCombis();

        /// 1. check Chiitoitsu(七对子)
        if (formatWorker.isChiitoitsu())
        {
            Yaku yaku = Yaku.NewYaku_Chiitoitsu(tehai, addHai, param);

            agariInfo.han         = yaku.getHan();
            agariInfo.fu          = 25;
            agariInfo.hanteiYakus = yaku.getHanteiYakus();

            agariInfo.scoreInfo = GetScoreInfo(agariInfo.han, agariInfo.fu);

            return(agariInfo.scoreInfo.koAgari);
        }

        /// 2. check Kokushi(国士无双)
        if (formatWorker.isKokushi())
        {
            Yaku yaku = Yaku.NewYaku_Kokushi(tehai, addHai, param);

            if (yaku.isKokushi)
            {
                agariInfo.han         = 13;
                agariInfo.fu          = 20;
                agariInfo.hanteiYakus = yaku.getHanteiYakus();

                agariInfo.scoreInfo = GetScoreInfo(agariInfo.han, agariInfo.fu);

                return(agariInfo.scoreInfo.koAgari);
            }

            return(0);
        }


        /// 3. check common combi yaku.
        if (combisCount <= 0)
        {
            return(0);
        }

        int[] hanSuuArr = new int[combisCount]; // 役
        int[] huSuuArr  = new int[combisCount]; // 符
        int[] scoreArr  = new int[combisCount]; // 点数(子のロン上がり)

        int maxAgariScore = 0;                  // 最大の点数

        for (int i = 0; i < combisCount; i++)
        {
            Yaku yaku = Yaku.NewYaku_Common(tehai, addHai, combis[i], param);
            hanSuuArr[i] = yaku.calculateHanSuu();
            huSuuArr[i]  = CalculateHu(tehai, addHai, combis[i], param, yaku);

            Score scoreInfo = GetScoreInfo(hanSuuArr[i], huSuuArr[i]);

            scoreArr[i] = scoreInfo.koAgari;

            if (scoreArr[i] > maxAgariScore)
            {
                agariInfo.han         = hanSuuArr[i];
                agariInfo.fu          = huSuuArr[i];
                agariInfo.hanteiYakus = yaku.getHanteiYakus();

                agariInfo.scoreInfo = scoreInfo;

                maxAgariScore = scoreArr[i];
            }
        }


        // 最大値を探す
        maxAgariScore = 0;

        for (int i = 0; i < combisCount; i++)
        {
            if (scoreArr[i] > maxAgariScore)
            {
                maxAgariScore = scoreArr[i];
            }
        }

        return(maxAgariScore);
    }
コード例 #37
-1
        public static SplitedTehai CalcSplitedTehai(Tehai tehai, string horaPaiString, bool isRon)
        {
            //手配&和了牌の牌の合計枚数をカウント
            int[] inHandSyu = new int[MJUtil.LENGTH_SYU_ALL];
            var redDoraCount = 0;
            var horaPai = new Pai(horaPaiString);

            foreach (var pai in tehai.tehai)
            {
                if (pai.IsRedDora)
                {
                    redDoraCount++;
                }
                inHandSyu[pai.PaiNumber]++;
            }

            if (isRon)
            {
                inHandSyu[PaiConverter.STRING_TO_ID[horaPaiString]]++;
            }

            if (horaPai.IsRedDora && isRon)
            {
                redDoraCount++;
            }

            TehaiSpliter ts = new TehaiSpliter();

            //手に残っている手配のターツ構成を全て算出
            var splited = ts.SplitTehai(inHandSyu, tehai.furos, horaPaiString, isRon);

            foreach (var furo in tehai.furos)
            {
                switch (furo.furoType)
                {
                    case MJUtil.TartsuType.MINSYUN:
                        splited.SyuNum[furo.minPaiSyu]++;
                        splited.SyuNum[furo.minPaiSyu + 1]++;
                        splited.SyuNum[furo.minPaiSyu + 2]++;
                        break;
                    case MJUtil.TartsuType.MINKO:
                        splited.SyuNum[furo.minPaiSyu] += 3;
                        break;
                    case MJUtil.TartsuType.MINKANTSU:
                        splited.SyuNum[furo.minPaiSyu] += 4;
                        break;
                    case MJUtil.TartsuType.ANKANTSU:
                        splited.SyuNum[furo.minPaiSyu] += 4;
                        break;
                }

                if (furo.furopai.IsRedDora)
                {
                    redDoraCount++;
                }
                foreach(var pai in furo.consumed)
                {
                    if (pai.IsRedDora)
                    {
                        redDoraCount++;
                    }
                }

            }

            //赤ドラの枚数セット
            splited.RedDoraNum = redDoraCount;

            return splited;
        }