Beispiel #1
0
        private static bool IsChurenpoto(InfoForResult ifr, int[] horaSyu)
        {
            if (ifr.IsMenzen == false)
            {
                return(false);
            }

            for (int mps = 0; mps < 3; mps++)
            {
                if (
                    (horaSyu[0 + mps * 9] >= 3) &&
                    (horaSyu[1 + mps * 9] >= 1) &&
                    (horaSyu[2 + mps * 9] >= 1) &&
                    (horaSyu[3 + mps * 9] >= 1) &&
                    (horaSyu[4 + mps * 9] >= 1) &&
                    (horaSyu[5 + mps * 9] >= 1) &&
                    (horaSyu[6 + mps * 9] >= 1) &&
                    (horaSyu[7 + mps * 9] >= 1) &&
                    (horaSyu[8 + mps * 9] >= 3)
                    )
                {
                    return(true);
                }
            }
            return(false);
        }
Beispiel #2
0
        private static bool IsPinfu(HoraPattern hp, InfoForResult ifr)
        {
            int headSyu = hp.Head.TartsuStartPaiSyu;

            //頭が役牌でないか判定
            if (ifr.IsBafuu(headSyu) || ifr.IsJifuu(headSyu) || MJUtil.IsDragonPai(headSyu))
            {
                return(false);
            }

            //門前順子またはロン和了明順メンツではない場合ピンフではない
            foreach (var tartsu in hp.WithoutHeadTartsuList)
            {
                if (((tartsu.IsAnsyun()) || (tartsu.IsMinsyun() && tartsu.IsRonedTartsu)) == false)
                {
                    return(false);
                }
            }

            //リャンメン待ちか判定
            int lastAddedSyu = ifr.GetLastAddedSyu();

            foreach (var tartsu in hp.WithoutHeadTartsuList)
            {
                if ((tartsu.TartsuStartPaiSyu == lastAddedSyu) && (lastAddedSyu % 9 != 6) ||
                    (tartsu.TartsuStartPaiSyu == lastAddedSyu - 2) && (lastAddedSyu % 9 != 2))
                {
                    return(true);
                }
            }
            return(false);
        }
Beispiel #3
0
 private static bool IsYakuhai(HoraPattern hp, InfoForResult ifr)
 {
     foreach (var tartsu in hp.WithoutHeadTartsuList)
     {
         if (ifr.IsJifuu(tartsu.TartsuStartPaiSyu) ||
             ifr.IsBafuu(tartsu.TartsuStartPaiSyu) ||
             MJUtil.IsDragonPai(tartsu.TartsuStartPaiSyu)
             )
         {
             return(true);
         }
     }
     return(false);
 }
Beispiel #4
0
        private static int CalcDoraNum(InfoForResult ifr, int[] horaSyu)
        {
            var doraNum = 0;


            foreach (var syu in horaSyu.Select((val, index) => new { val, index }))
            {
                if (syu.val == 0)
                {
                    continue;
                }

                if (ifr.IsDora(syu.index))
                {
                    doraNum += syu.val;
                }
            }
            return(doraNum);
        }
Beispiel #5
0
        private static int CalcDoraNum(HoraPattern hp, InfoForResult ifr)
        {
            //赤ドラはカウントしない
            var doraNum = 0;

            foreach (var tartsu in hp.TartsuList)
            {
                if (tartsu.TartsuType == MJUtil.TartsuType.ANSYUN || tartsu.TartsuType == MJUtil.TartsuType.MINSYUN)
                {
                    if (ifr.IsDora(tartsu.TartsuStartPaiSyu) ||
                        ifr.IsDora(tartsu.TartsuStartPaiSyu + 1) ||
                        ifr.IsDora(tartsu.TartsuStartPaiSyu + 2))
                    {
                        doraNum++;
                    }
                }
                else if (tartsu.TartsuType == MJUtil.TartsuType.ANKO || tartsu.TartsuType == MJUtil.TartsuType.MINKO)
                {
                    if (ifr.IsDora(tartsu.TartsuStartPaiSyu))
                    {
                        doraNum += 3;
                    }
                }
                else if (tartsu.TartsuType == MJUtil.TartsuType.HEAD)
                {
                    if (ifr.IsDora(tartsu.TartsuStartPaiSyu))
                    {
                        doraNum += 2;
                    }
                }
                else if (tartsu.TartsuType == MJUtil.TartsuType.ANKANTSU || tartsu.TartsuType == MJUtil.TartsuType.MINKANTSU)
                {
                    if (ifr.IsDora(tartsu.TartsuStartPaiSyu))
                    {
                        doraNum += 4;
                    }
                }
            }
            return(doraNum);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        private static int CalcYakuhaiNum(HoraPattern hp, InfoForResult ifr)
        {
            int yakuhaiNum = 0;

            //TODO
            foreach (var tartsu in hp.WithoutHeadTartsuList)
            {
                //ダブ東、ダブ南の場合があるので自風と場風は独立に判定する
                if (ifr.IsJifuu(tartsu.TartsuStartPaiSyu))
                {
                    yakuhaiNum++;
                }
                if (ifr.IsBafuu(tartsu.TartsuStartPaiSyu))
                {
                    yakuhaiNum++;
                }
                if (MJUtil.IsDragonPai(tartsu.TartsuStartPaiSyu))
                {
                    yakuhaiNum++;
                }
            }
            return(yakuhaiNum);
        }
Beispiel #8
0
 private static bool IsDora(HoraPattern hp, InfoForResult ifr)
 {
     foreach (var tartsu in hp.TartsuList)
     {
         if (tartsu.TartsuType == MJUtil.TartsuType.ANSYUN || tartsu.TartsuType == MJUtil.TartsuType.MINSYUN)
         {
             if (ifr.IsDora(tartsu.TartsuStartPaiSyu) ||
                 ifr.IsDora(tartsu.TartsuStartPaiSyu + 1) ||
                 ifr.IsDora(tartsu.TartsuStartPaiSyu + 2))
             {
                 return(true);
             }
         }
         else
         {
             if (ifr.IsDora(tartsu.TartsuStartPaiSyu))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Beispiel #9
0
        private static bool IsIipeiko(HoraPattern hp, InfoForResult ifr)
        {
            //門前でない場合は終了
            if (ifr.IsMenzen == false)
            {
                return(false);
            }

            //一盃口対象である門前順子またはロンした明順のみ抜き出し
            var ansyuns = hp.WithoutHeadTartsuList.Where(e => e.IsAnsyun() || (e.IsMinsyun() && e.IsRonedTartsu))
                          .OrderBy(e => e.TartsuStartPaiSyu);
            var prevStartPaisyu = -1;

            foreach (var ansyun in ansyuns)
            {
                if (ansyun.TartsuStartPaiSyu == prevStartPaisyu)
                {
                    return(true);
                }
                prevStartPaisyu = ansyun.TartsuStartPaiSyu;
            }
            return(false);
        }
Beispiel #10
0
        private static bool IsRyanpeiko(HoraPattern hp, InfoForResult ifr)
        {
            //門前でない場合は終了
            if (ifr.IsMenzen == false)
            {
                return(false);
            }

            //4ターツ全てが門前順子またはロンした明順でない場合は終了
            if (hp.TartsuList.Where(e => (e.IsAnsyun() || (e.IsMinsyun() && e.IsRonedTartsu)) == false).Count() != 4)
            {
                return(false);
            }


            var sorted = hp.WithoutHeadTartsuList.OrderBy(e => e.TartsuStartPaiSyu).ToList();

            if (sorted[0].TartsuStartPaiSyu == sorted[1].TartsuStartPaiSyu && sorted[2].TartsuStartPaiSyu == sorted[3].TartsuStartPaiSyu)
            {
                return(true);
            }

            return(false);
        }
Beispiel #11
0
        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;
        }
Beispiel #12
0
        public static YakuResult CalcNormalYaku(HoraPattern horaMentsu, InfoForResult ifr, Field field,int[] horaSyu)
        {
            YakuResult result = new YakuResult();

            result.Fu = CalcFu(horaMentsu, field, ifr);
            result.IsTsumo = ifr.IsTsumo;
            result.IsOya = ifr.IsOya;


            //役の文字列取得
            var yakuString = MJUtil.YAKU_STRING;
            //飜数の辞書選択
            var yakuHanNum = ifr.IsMenzen ? MJUtil.YAKU_HAN_MENZEN : MJUtil.YAKU_HAN_FUROED;

            if (ifr.IsDoubleReach)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.DOUBLEREACH], yakuHanNum[(int)MJUtil.Yaku.DOUBLEREACH]);
            }
            else if (ifr.IsReach)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.REACH], yakuHanNum[(int)MJUtil.Yaku.REACH]);
            }

            if (ifr.IsTsumo && ifr.IsMenzen)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TSUMO], yakuHanNum[(int)MJUtil.Yaku.TSUMO]);
            }
            if (ifr.IsIppatsu)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.IPPATSU], yakuHanNum[(int)MJUtil.Yaku.IPPATSU]);
            }
            if (IsPinfu(horaMentsu, ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.PINFU], yakuHanNum[(int)MJUtil.Yaku.PINFU]);
                result.Fu = ifr.IsTsumo ? 20 : 30;//ピンフツモは20符、ピンフロンは30符
            }
            if (IsTannyao(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TANNYAO], yakuHanNum[(int)MJUtil.Yaku.TANNYAO]);
            }

            //一盃口と二盃口は両立しない
            if (IsRyanpeiko(horaMentsu, ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.RYANPEIKO], yakuHanNum[(int)MJUtil.Yaku.RYANPEIKO]);
            }
            else if (IsIipeiko(horaMentsu, ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.IIPEIKOU], yakuHanNum[(int)MJUtil.Yaku.IIPEIKOU]);
            }

            if (IsYakuhai(horaMentsu, ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.YAKUHAI], CalcYakuhaiNum(horaMentsu, ifr));
            }
            if (ifr.IsHoutei)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HOUTEI], yakuHanNum[(int)MJUtil.Yaku.HOUTEI]);
            }
            if (ifr.IsHaitei)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HAITEI], yakuHanNum[(int)MJUtil.Yaku.HAITEI]);
            }
            if (ifr.IsRinshan)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.RINSHAN], yakuHanNum[(int)MJUtil.Yaku.RINSHAN]);
            }
            if (ifr.IsChankan)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHANKAN], yakuHanNum[(int)MJUtil.Yaku.CHANKAN]);
            }
            if (IsDora(horaMentsu, ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.DORA], CalcDoraNum(horaMentsu, ifr));
            }
            if (IsSansyokuDoujun(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SANSYOKUDOJUN], yakuHanNum[(int)MJUtil.Yaku.SANSYOKUDOJUN]);
            }

            if (IsIttsuu(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.ITTSUU], yakuHanNum[(int)MJUtil.Yaku.ITTSUU]);
            }

            if (IsSananko(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SANANKO], yakuHanNum[(int)MJUtil.Yaku.SANANKO]);
            }

            if (IsToitoi(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TOITOI], yakuHanNum[(int)MJUtil.Yaku.TOITOI]);
            }

            if (IsShosangen(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SHOSANGEN], yakuHanNum[(int)MJUtil.Yaku.SHOSANGEN]);
            }

            //混老頭とチャンタ系は同時に成立しないためif elseで判定する
            if (IsHonroto(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HONROTO], yakuHanNum[(int)MJUtil.Yaku.HONROTO]);
            }
            else
            {
                if (IsChanta(horaMentsu))
                {
                    result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHANTA], yakuHanNum[(int)MJUtil.Yaku.CHANTA]);
                }
                if (IsJunChanta(horaMentsu))
                {
                    result.yakus.Add(yakuString[(int)MJUtil.Yaku.JUNCHANTA], yakuHanNum[(int)MJUtil.Yaku.JUNCHANTA]);
                }
            }


            if (IsSansyokuDoko(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SANSYOKUDOKO], yakuHanNum[(int)MJUtil.Yaku.SANSYOKUDOKO]);
            }

            if (IsSankantsu(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SANKANTSU], yakuHanNum[(int)MJUtil.Yaku.SANKANTSU]);
            }

            //混一色と清一色は同時に成立しないためif elseで判定する
            if (IsHonnitsu(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HONNITSU], yakuHanNum[(int)MJUtil.Yaku.HONNITSU]);
            }
            else if (IsChinnitsu(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHINNITSU], yakuHanNum[(int)MJUtil.Yaku.CHINNITSU]);
            }



            //ここから役満
            if(IsSuuanko(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SUUANKO], yakuHanNum[(int)MJUtil.Yaku.SUUANKO]);
            }

            if (IsDaisangen(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.DAISANGEN], yakuHanNum[(int)MJUtil.Yaku.DAISANGEN]);
            }

            if (IsShosushi(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SHOSUSHI], yakuHanNum[(int)MJUtil.Yaku.SHOSUSHI]);
            }

            if (IsDaisushi(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.DAISUSHI], yakuHanNum[(int)MJUtil.Yaku.DAISUSHI]);
            }

            if(IsTsuiso(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TSUISO], yakuHanNum[(int)MJUtil.Yaku.TSUISO]);
            }

            if (IsRyuiso(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.RYUISO], yakuHanNum[(int)MJUtil.Yaku.RYUISO]);
            }

            if (IsChinroto(horaMentsu)) {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHINROTO], yakuHanNum[(int)MJUtil.Yaku.CHINROTO]);
            }

            if(IsChurenpoto(ifr,horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHURENPOTO], yakuHanNum[(int)MJUtil.Yaku.CHURENPOTO]);
            }

            if (IsSukantsu(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SUKANTSU], yakuHanNum[(int)MJUtil.Yaku.SUKANTSU]);
            }

            if (IsTenho(ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TENHO], yakuHanNum[(int)MJUtil.Yaku.TENHO]);
            }
            
            if( IsChiho(ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHIHO], yakuHanNum[(int)MJUtil.Yaku.CHIHO]);
            }

            if (HasYakuman(result.yakus))
            {
                result.yakus = SelectYakuman(result.yakus);
                result.IsYakuman = true;
            }

            //飜数計算
            result.Han = CalcHanSum(result);
            return result;
        }
Beispiel #13
0
        public static YakuResult CalcSpecialYaku(InfoForResult ifr, Field field, int[] horaSyu)
        {
            YakuResult result = new YakuResult();

            result.Fu      = 25;//国士無双の場合は符を考慮しなくてよいため七対子の符に設定
            result.IsTsumo = ifr.IsTsumo;
            result.IsOya   = ifr.IsOya;



            //役の文字列取得
            var yakuString = MJUtil.YAKU_STRING;
            //飜数の辞書選択
            var yakuHanNum = ifr.IsMenzen ? MJUtil.YAKU_HAN_MENZEN : MJUtil.YAKU_HAN_FUROED;

            //七対子をあらかじめセット
            //国士無双の場合はSelectYakumanで七対子が消えるため初期段階でセットして問題ない
            result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHITOITSU], yakuHanNum[(int)MJUtil.Yaku.CHITOITSU]);


            if (ifr.IsDoubleReach)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.DOUBLEREACH], yakuHanNum[(int)MJUtil.Yaku.DOUBLEREACH]);
            }
            else if (ifr.IsReach)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.REACH], yakuHanNum[(int)MJUtil.Yaku.REACH]);
            }

            if (ifr.IsTsumo && ifr.IsMenzen)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TSUMO], yakuHanNum[(int)MJUtil.Yaku.TSUMO]);
            }
            if (ifr.IsIppatsu)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.IPPATSU], yakuHanNum[(int)MJUtil.Yaku.IPPATSU]);
            }

            if (IsDora(ifr, horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.DORA], CalcDoraNum(ifr, horaSyu));
            }
            if (IsChinnitsu(horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHINNITSU], yakuHanNum[(int)MJUtil.Yaku.CHINNITSU]);
            }
            if (IsHonnitsu(horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HONNITSU], yakuHanNum[(int)MJUtil.Yaku.HONNITSU]);
            }
            if (IsTannyao(horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TANNYAO], yakuHanNum[(int)MJUtil.Yaku.TANNYAO]);
            }
            if (IsHonroto(horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HONROTO], yakuHanNum[(int)MJUtil.Yaku.HONROTO]);
            }
            if (ifr.IsHoutei)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HOUTEI], yakuHanNum[(int)MJUtil.Yaku.HOUTEI]);
            }
            if (ifr.IsHaitei)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HAITEI], yakuHanNum[(int)MJUtil.Yaku.HAITEI]);
            }
            if (ifr.IsChankan)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHANKAN], yakuHanNum[(int)MJUtil.Yaku.CHANKAN]);
            }
            if (IsTenho(ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TENHO], yakuHanNum[(int)MJUtil.Yaku.TENHO]);
            }

            if (IsChiho(ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHIHO], yakuHanNum[(int)MJUtil.Yaku.CHIHO]);
            }
            if (IsTsuiso(horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TSUISO], yakuHanNum[(int)MJUtil.Yaku.TSUISO]);
            }


            if (HasYakuman(result.yakus))
            {
                result.yakus = SelectYakuman(result.yakus);
            }


            return(result);
        }
Beispiel #14
0
        private static int CalcDoraNum(InfoForResult ifr, int[] horaSyu)
        {
            var doraNum = 0;

            
            foreach(var syu in horaSyu.Select( (val,index) => new { val,index } ))
            {
                if(syu.val == 0)
                {
                    continue;
                }

                if (ifr.IsDora(syu.index))
                {
                    doraNum += syu.val;
                }
            }
            return doraNum;
        }
Beispiel #15
0
 private static bool IsDora(InfoForResult ifr, int[] horaSyu)
 {
     return ifr.CalcDoraNum(horaSyu) > 0;
 }
Beispiel #16
0
 private static int CalcYakuhaiNum(HoraPattern hp, InfoForResult ifr)
 {
     int yakuhaiNum = 0;
     //TODO
     foreach (var tartsu in hp.WithoutHeadTartsuList)
     {
         //ダブ東、ダブ南の場合があるので自風と場風は独立に判定する
         if (ifr.IsJifuu(tartsu.TartsuStartPaiSyu))
         {
             yakuhaiNum++;
         }
         if (ifr.IsBafuu(tartsu.TartsuStartPaiSyu))
         {
             yakuhaiNum++;
         }
         if (MJUtil.IsDragonPai(tartsu.TartsuStartPaiSyu))
         {
             yakuhaiNum++;
         }
     }
     return yakuhaiNum;
 }
Beispiel #17
0
        private static bool IsIipeiko(HoraPattern hp, InfoForResult ifr)
        {
            //門前でない場合は終了
            if (ifr.IsMenzen == false)
            {
                return false;
            }

            //一盃口対象である門前順子またはロンした明順のみ抜き出し
            var ansyuns = hp.WithoutHeadTartsuList.Where(e => e.IsAnsyun() || (e.IsMinsyun() && e.IsRonedTartsu))
                                                  .OrderBy(e => e.TartsuStartPaiSyu);
            var prevStartPaisyu = -1;
            foreach (var ansyun in ansyuns)
            {
                if (ansyun.TartsuStartPaiSyu == prevStartPaisyu)
                {
                    return true;
                }
                prevStartPaisyu = ansyun.TartsuStartPaiSyu;
            }
            return false;
        }
Beispiel #18
0
        private static bool IsPinfu(HoraPattern hp, InfoForResult ifr) {
            int headSyu = hp.Head.TartsuStartPaiSyu;

            //頭が役牌でないか判定
            if (ifr.IsBafuu(headSyu) || ifr.IsJifuu(headSyu) || MJUtil.IsDragonPai(headSyu))
            {
                return false;
            }

            //門前順子またはロン和了明順メンツではない場合ピンフではない
            foreach (var tartsu in hp.WithoutHeadTartsuList) {
                if ( ( (tartsu.IsAnsyun()) || ( tartsu.IsMinsyun() && tartsu.IsRonedTartsu) ) == false)
                {
                    return false;
                }
            }

            //リャンメン待ちか判定
            int lastAddedSyu = ifr.GetLastAddedSyu();
            foreach (var tartsu in hp.WithoutHeadTartsuList )
            {
                if ( (tartsu.TartsuStartPaiSyu == lastAddedSyu) && (lastAddedSyu % 9 != 6)
                    || (tartsu.TartsuStartPaiSyu == lastAddedSyu - 2) && (lastAddedSyu % 9 != 2))
                {
                    return true;
                }
            }
            return false;
        }
Beispiel #19
0
 private static bool IsTenho(InfoForResult ifr)
 {
     return(ifr.PassedTurn == 0);
 }
Beispiel #20
0
 private static bool IsChiho(InfoForResult ifr)
 {
     return(ifr.IsFirstTurn() && ifr.IsOya == false);
 }
Beispiel #21
0
        private static int CalcFu(HoraPattern horaMentsu, Field field, InfoForResult ifpc)
        {
            int fuSum = 0;
            int futei = 20;

            fuSum += futei;

            //門前ロンの場合
            if (ifpc.IsMenzen && (!ifpc.IsTsumo))
            {
                fuSum += 10;
            }

            //頭が役牌の場合
            int headSyuId = horaMentsu.TartsuList.Where(e => e.IsHead()).First().TartsuStartPaiSyu;

            if (ifpc.IsBafuu(headSyuId))
            {
                fuSum += 2;
            }
            if (ifpc.IsJifuu(headSyuId))
            {
                fuSum += 2;
            }
            if (MJUtil.IsDragonPai(headSyuId))
            {
                fuSum += 2;
            }

            //ツモの場合
            if (ifpc.IsTsumo)
            {
                fuSum += 2;
            }


            int multiple;

            foreach (var tartsu in horaMentsu.TartsuList)
            {
                if (tartsu.IsYaochuTartsu())
                {
                    multiple = 2;
                }
                else
                {
                    multiple = 1;
                }

                switch (tartsu.TartsuType)
                {
                case MJUtil.TartsuType.MINKO:
                    fuSum += 2 * multiple;
                    continue;

                case MJUtil.TartsuType.ANKO:
                    fuSum += 4 * multiple;
                    continue;

                case MJUtil.TartsuType.MINKANTSU:
                    fuSum += 8 * multiple;
                    continue;

                case MJUtil.TartsuType.ANKANTSU:
                    fuSum += 16 * multiple;
                    continue;
                }
            }

            int lastAddedSyu = ifpc.GetLastAddedSyu();

            //待ちによる符加算
            //単騎待ちの場合
            if (horaMentsu.Head.IsRonedTartsu)
            {
                fuSum += 2;
            }
            else
            {
                //カンチャンorペンチャンの場合
                for (int i = 1; i < horaMentsu.TartsuList.Count; i++)
                {
                    if ((horaMentsu.TartsuList[i].IsAnsyun() || horaMentsu.TartsuList[i].IsMinsyun()) == false)
                    {
                        continue;
                    }
                    //順子前提
                    if (lastAddedSyu == horaMentsu.TartsuList[i].TartsuStartPaiSyu + 1)  //カンチャン
                    {
                        fuSum += 2;
                        break;
                    }
                    else if ((lastAddedSyu == horaMentsu.TartsuList[i].TartsuStartPaiSyu) && (lastAddedSyu % 9 == 6))    //7待ちの89ペンチャン
                    {
                        fuSum += 2;
                        break;
                    }
                    else if ((lastAddedSyu == horaMentsu.TartsuList[i].TartsuStartPaiSyu + 2) && (lastAddedSyu % 9 == 2))    //3待ちの12ペンチャン
                    {
                        fuSum += 2;
                        break;
                    }
                }
            }


            //喰い平和系の場合そのまま計算すると20符だが、ルール的にピンフ以外は最低30符のため2符足して30符に切り上げる
            if ((fuSum == 20) && (ifpc.IsMenzen == false))
            {
                fuSum += 2;
            }

            return((int)(Math.Ceiling(fuSum / 10.0) * 10));
        }
Beispiel #22
0
        public static YakuResult CalcSpecialYaku(InfoForResult ifr, Field field, int[] horaSyu)
        {
            YakuResult result = new YakuResult();
            result.Fu = 25;//国士無双の場合は符を考慮しなくてよいため七対子の符に設定
            result.IsTsumo = ifr.IsTsumo;
            result.IsOya = ifr.IsOya;




            //役の文字列取得
            var yakuString = MJUtil.YAKU_STRING;
            //飜数の辞書選択
            var yakuHanNum = ifr.IsMenzen ? MJUtil.YAKU_HAN_MENZEN : MJUtil.YAKU_HAN_FUROED;

            //七対子をあらかじめセット
            //国士無双の場合はSelectYakumanで七対子が消えるため初期段階でセットして問題ない
            result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHITOITSU], yakuHanNum[(int)MJUtil.Yaku.CHITOITSU]);


            if (ifr.IsDoubleReach)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.DOUBLEREACH], yakuHanNum[(int)MJUtil.Yaku.DOUBLEREACH]);
            }
            else if (ifr.IsReach)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.REACH], yakuHanNum[(int)MJUtil.Yaku.REACH]);
            }

            if (ifr.IsTsumo && ifr.IsMenzen)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TSUMO], yakuHanNum[(int)MJUtil.Yaku.TSUMO]);
            }
            if (ifr.IsIppatsu)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.IPPATSU], yakuHanNum[(int)MJUtil.Yaku.IPPATSU]);
            }
            
            if (IsDora(ifr,horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.DORA], CalcDoraNum(ifr, horaSyu));
            }
            if (IsChinnitsu(horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHINNITSU], yakuHanNum[(int)MJUtil.Yaku.CHINNITSU]);
            }
            if (IsHonnitsu(horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HONNITSU], yakuHanNum[(int)MJUtil.Yaku.HONNITSU]);
            }
            if (IsTannyao(horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TANNYAO], yakuHanNum[(int)MJUtil.Yaku.TANNYAO]);
            }
            if (IsHonroto(horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HONROTO], yakuHanNum[(int)MJUtil.Yaku.HONROTO]);
            }
            if (ifr.IsHoutei)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HOUTEI], yakuHanNum[(int)MJUtil.Yaku.HOUTEI]);
            }
            if (ifr.IsHaitei)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HAITEI], yakuHanNum[(int)MJUtil.Yaku.HAITEI]);
            }
            if (ifr.IsChankan)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHANKAN], yakuHanNum[(int)MJUtil.Yaku.CHANKAN]);
            }
            if (IsTenho(ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TENHO], yakuHanNum[(int)MJUtil.Yaku.TENHO]);
            }

            if (IsChiho(ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHIHO], yakuHanNum[(int)MJUtil.Yaku.CHIHO]);
            }
            if (IsTsuiso(horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TSUISO], yakuHanNum[(int)MJUtil.Yaku.TSUISO]);
            }


            if (HasYakuman(result.yakus))
            {
                result.yakus = SelectYakuman(result.yakus);
            }


            return result;
        }
Beispiel #23
0
        private static int CalcFu(HoraPattern horaMentsu, Field field, InfoForResult ifpc) {
            int fuSum = 0;
            int futei = 20;
            fuSum += futei;

            //門前ロンの場合
            if (ifpc.IsMenzen && (!ifpc.IsTsumo)) {
                fuSum += 10;
            }

            //頭が役牌の場合
            int headSyuId = horaMentsu.TartsuList.Where(e => e.IsHead()).First().TartsuStartPaiSyu;
            if (ifpc.IsBafuu(headSyuId)) {
                fuSum += 2;
            }
            if (ifpc.IsJifuu(headSyuId)) {
                fuSum += 2;
            }
            if (MJUtil.IsDragonPai(headSyuId)) {
                fuSum += 2;
            }

            //ツモの場合
            if (ifpc.IsTsumo) {
                fuSum += 2;
            }


            int multiple;

            foreach (var tartsu in horaMentsu.TartsuList)
            {
                if (tartsu.IsYaochuTartsu())
                {
                    multiple = 2;
                }
                else
                {
                    multiple = 1;
                }

                switch (tartsu.TartsuType)
                {
                    case MJUtil.TartsuType.MINKO:
                        fuSum += 2 * multiple;
                        continue;
                    case MJUtil.TartsuType.ANKO:
                        fuSum += 4 * multiple;
                        continue;
                    case MJUtil.TartsuType.MINKANTSU:
                        fuSum += 8 * multiple;
                        continue;
                    case MJUtil.TartsuType.ANKANTSU:
                        fuSum += 16 * multiple;
                        continue;
                }

            }

            int lastAddedSyu = ifpc.GetLastAddedSyu();

            //待ちによる符加算
            //単騎待ちの場合
            if (horaMentsu.Head.IsRonedTartsu)
            {
                fuSum += 2;
            }
            else
            {
                //カンチャンorペンチャンの場合
                for (int i = 1; i < horaMentsu.TartsuList.Count; i++) {
                    if ((horaMentsu.TartsuList[i].IsAnsyun() || horaMentsu.TartsuList[i].IsMinsyun()) == false)
                    {
                        continue;
                    }
                    //順子前提
                    if (lastAddedSyu == horaMentsu.TartsuList[i].TartsuStartPaiSyu + 1) {//カンチャン
                        fuSum += 2;
                        break;
                    } else if ((lastAddedSyu == horaMentsu.TartsuList[i].TartsuStartPaiSyu) && (lastAddedSyu % 9 == 6)) {//7待ちの89ペンチャン
                        fuSum += 2;
                        break;
                    } else if ((lastAddedSyu == horaMentsu.TartsuList[i].TartsuStartPaiSyu + 2) && (lastAddedSyu % 9 == 2)) {//3待ちの12ペンチャン
                        fuSum += 2;
                        break;
                    }
                }
            }


            //喰い平和系の場合そのまま計算すると20符だが、ルール的にピンフ以外は最低30符のため2符足して30符に切り上げる
            if ((fuSum == 20) && (ifpc.IsMenzen == false)) {
                fuSum += 2;
            }

            return (int)(Math.Ceiling(fuSum / 10.0) * 10);
        }
Beispiel #24
0
 private static bool IsDora(InfoForResult ifr, int[] horaSyu)
 {
     return(ifr.CalcDoraNum(horaSyu) > 0);
 }
Beispiel #25
0
        private static bool IsRyanpeiko(HoraPattern hp, InfoForResult ifr)
        {
            //門前でない場合は終了
            if (ifr.IsMenzen == false)
            {
                return false;
            }

            //4ターツ全てが門前順子またはロンした明順でない場合は終了
            if (hp.TartsuList.Where(e => ( e.IsAnsyun() || (e.IsMinsyun() && e.IsRonedTartsu) ) == false ).Count() != 4)
            {
                return false;
            }


            var sorted = hp.WithoutHeadTartsuList.OrderBy(e => e.TartsuStartPaiSyu).ToList();

            if (sorted[0].TartsuStartPaiSyu == sorted[1].TartsuStartPaiSyu && sorted[2].TartsuStartPaiSyu == sorted[3].TartsuStartPaiSyu)
            {
                return true;
            }

            return false;
        }
Beispiel #26
0
        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]));
            }
        }
Beispiel #27
0
 private static bool IsYakuhai(HoraPattern hp, InfoForResult ifr)
 {
     foreach (var tartsu in hp.WithoutHeadTartsuList)
     {
         if (ifr.IsJifuu(tartsu.TartsuStartPaiSyu) 
             || ifr.IsBafuu(tartsu.TartsuStartPaiSyu)
             || MJUtil.IsDragonPai(tartsu.TartsuStartPaiSyu)
             )
         {
             return true;
         }
     }
     return false;
 }
Beispiel #28
0
        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);
            }

        }
Beispiel #29
0
 private static bool IsDora(HoraPattern hp, InfoForResult ifr)
 {
     foreach (var tartsu in hp.TartsuList)
     {
         if (tartsu.TartsuType == MJUtil.TartsuType.ANSYUN || tartsu.TartsuType == MJUtil.TartsuType.MINSYUN)
         {
             if (ifr.IsDora(tartsu.TartsuStartPaiSyu) ||
                  ifr.IsDora(tartsu.TartsuStartPaiSyu + 1) ||
                  ifr.IsDora(tartsu.TartsuStartPaiSyu + 2))
             {
                 return true;
             }
         }
         else
         {
             if (ifr.IsDora(tartsu.TartsuStartPaiSyu))
             {
                 return true;
             }
         }
     }
     return false;
 }
Beispiel #30
0
        private static bool IsChurenpoto(InfoForResult ifr,int[] horaSyu)
        {
            if (ifr.IsMenzen == false)
            {
                return false;
            }

            for (int mps = 0; mps < 3; mps++)
            {
                if (
                       (horaSyu[0 + mps * 9] >= 3)
                    && (horaSyu[1 + mps * 9] >= 1)
                    && (horaSyu[2 + mps * 9] >= 1)
                    && (horaSyu[3 + mps * 9] >= 1)
                    && (horaSyu[4 + mps * 9] >= 1)
                    && (horaSyu[5 + mps * 9] >= 1)
                    && (horaSyu[6 + mps * 9] >= 1)
                    && (horaSyu[7 + mps * 9] >= 1)
                    && (horaSyu[8 + mps * 9] >= 3)
                )
                {
                    return true;
                }
            }
            return false;
        }
Beispiel #31
0
 private static int CalcDoraNum(HoraPattern hp, InfoForResult ifr)
 {
     //赤ドラはカウントしない
     var doraNum = 0;
     foreach (var tartsu in hp.TartsuList)
     {
         if (tartsu.TartsuType == MJUtil.TartsuType.ANSYUN || tartsu.TartsuType == MJUtil.TartsuType.MINSYUN)
         {
             if (ifr.IsDora(tartsu.TartsuStartPaiSyu) ||
                  ifr.IsDora(tartsu.TartsuStartPaiSyu + 1) ||
                  ifr.IsDora(tartsu.TartsuStartPaiSyu + 2))
             {
                 doraNum++;
             }
         }
         else if (tartsu.TartsuType == MJUtil.TartsuType.ANKO || tartsu.TartsuType == MJUtil.TartsuType.MINKO)
         {
             if (ifr.IsDora(tartsu.TartsuStartPaiSyu))
             {
                 doraNum += 3;
             }
         }
         else if (tartsu.TartsuType == MJUtil.TartsuType.HEAD)
         {
             if (ifr.IsDora(tartsu.TartsuStartPaiSyu))
             {
                 doraNum += 2;
             }
         }
         else if (tartsu.TartsuType == MJUtil.TartsuType.ANKANTSU || tartsu.TartsuType == MJUtil.TartsuType.MINKANTSU)
         {
             if (ifr.IsDora(tartsu.TartsuStartPaiSyu))
             {
                 doraNum += 4;
             }
         }
     }
     return doraNum;
 }
Beispiel #32
0
 private static bool IsTenho(InfoForResult ifr)
 {
     return ifr.PassedTurn == 0;
 }
Beispiel #33
0
 private static bool IsChiho(InfoForResult ifr)
 {
     return ifr.IsFirstTurn() && ifr.IsOya == false; 
 }
Beispiel #34
0
        public static YakuResult CalcNormalYaku(HoraPattern horaMentsu, InfoForResult ifr, Field field, int[] horaSyu)
        {
            YakuResult result = new YakuResult();

            result.Fu      = CalcFu(horaMentsu, field, ifr);
            result.IsTsumo = ifr.IsTsumo;
            result.IsOya   = ifr.IsOya;


            //役の文字列取得
            var yakuString = MJUtil.YAKU_STRING;
            //飜数の辞書選択
            var yakuHanNum = ifr.IsMenzen ? MJUtil.YAKU_HAN_MENZEN : MJUtil.YAKU_HAN_FUROED;

            if (ifr.IsDoubleReach)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.DOUBLEREACH], yakuHanNum[(int)MJUtil.Yaku.DOUBLEREACH]);
            }
            else if (ifr.IsReach)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.REACH], yakuHanNum[(int)MJUtil.Yaku.REACH]);
            }

            if (ifr.IsTsumo && ifr.IsMenzen)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TSUMO], yakuHanNum[(int)MJUtil.Yaku.TSUMO]);
            }
            if (ifr.IsIppatsu)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.IPPATSU], yakuHanNum[(int)MJUtil.Yaku.IPPATSU]);
            }
            if (IsPinfu(horaMentsu, ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.PINFU], yakuHanNum[(int)MJUtil.Yaku.PINFU]);
                result.Fu = ifr.IsTsumo ? 20 : 30;//ピンフツモは20符、ピンフロンは30符
            }
            if (IsTannyao(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TANNYAO], yakuHanNum[(int)MJUtil.Yaku.TANNYAO]);
            }

            //一盃口と二盃口は両立しない
            if (IsRyanpeiko(horaMentsu, ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.RYANPEIKO], yakuHanNum[(int)MJUtil.Yaku.RYANPEIKO]);
            }
            else if (IsIipeiko(horaMentsu, ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.IIPEIKOU], yakuHanNum[(int)MJUtil.Yaku.IIPEIKOU]);
            }

            if (IsYakuhai(horaMentsu, ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.YAKUHAI], CalcYakuhaiNum(horaMentsu, ifr));
            }
            if (ifr.IsHoutei)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HOUTEI], yakuHanNum[(int)MJUtil.Yaku.HOUTEI]);
            }
            if (ifr.IsHaitei)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HAITEI], yakuHanNum[(int)MJUtil.Yaku.HAITEI]);
            }
            if (ifr.IsRinshan)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.RINSHAN], yakuHanNum[(int)MJUtil.Yaku.RINSHAN]);
            }
            if (ifr.IsChankan)
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHANKAN], yakuHanNum[(int)MJUtil.Yaku.CHANKAN]);
            }
            if (IsDora(horaMentsu, ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.DORA], CalcDoraNum(horaMentsu, ifr));
            }
            if (IsSansyokuDoujun(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SANSYOKUDOJUN], yakuHanNum[(int)MJUtil.Yaku.SANSYOKUDOJUN]);
            }

            if (IsIttsuu(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.ITTSUU], yakuHanNum[(int)MJUtil.Yaku.ITTSUU]);
            }

            if (IsSananko(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SANANKO], yakuHanNum[(int)MJUtil.Yaku.SANANKO]);
            }

            if (IsToitoi(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TOITOI], yakuHanNum[(int)MJUtil.Yaku.TOITOI]);
            }

            if (IsShosangen(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SHOSANGEN], yakuHanNum[(int)MJUtil.Yaku.SHOSANGEN]);
            }

            //混老頭とチャンタ系は同時に成立しないためif elseで判定する
            if (IsHonroto(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HONROTO], yakuHanNum[(int)MJUtil.Yaku.HONROTO]);
            }
            else
            {
                if (IsChanta(horaMentsu))
                {
                    result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHANTA], yakuHanNum[(int)MJUtil.Yaku.CHANTA]);
                }
                if (IsJunChanta(horaMentsu))
                {
                    result.yakus.Add(yakuString[(int)MJUtil.Yaku.JUNCHANTA], yakuHanNum[(int)MJUtil.Yaku.JUNCHANTA]);
                }
            }


            if (IsSansyokuDoko(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SANSYOKUDOKO], yakuHanNum[(int)MJUtil.Yaku.SANSYOKUDOKO]);
            }

            if (IsSankantsu(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SANKANTSU], yakuHanNum[(int)MJUtil.Yaku.SANKANTSU]);
            }

            //混一色と清一色は同時に成立しないためif elseで判定する
            if (IsHonnitsu(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.HONNITSU], yakuHanNum[(int)MJUtil.Yaku.HONNITSU]);
            }
            else if (IsChinnitsu(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHINNITSU], yakuHanNum[(int)MJUtil.Yaku.CHINNITSU]);
            }



            //ここから役満
            if (IsSuuanko(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SUUANKO], yakuHanNum[(int)MJUtil.Yaku.SUUANKO]);
            }

            if (IsDaisangen(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.DAISANGEN], yakuHanNum[(int)MJUtil.Yaku.DAISANGEN]);
            }

            if (IsShosushi(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SHOSUSHI], yakuHanNum[(int)MJUtil.Yaku.SHOSUSHI]);
            }

            if (IsDaisushi(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.DAISUSHI], yakuHanNum[(int)MJUtil.Yaku.DAISUSHI]);
            }

            if (IsTsuiso(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TSUISO], yakuHanNum[(int)MJUtil.Yaku.TSUISO]);
            }

            if (IsRyuiso(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.RYUISO], yakuHanNum[(int)MJUtil.Yaku.RYUISO]);
            }

            if (IsChinroto(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHINROTO], yakuHanNum[(int)MJUtil.Yaku.CHINROTO]);
            }

            if (IsChurenpoto(ifr, horaSyu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHURENPOTO], yakuHanNum[(int)MJUtil.Yaku.CHURENPOTO]);
            }

            if (IsSukantsu(horaMentsu))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.SUKANTSU], yakuHanNum[(int)MJUtil.Yaku.SUKANTSU]);
            }

            if (IsTenho(ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.TENHO], yakuHanNum[(int)MJUtil.Yaku.TENHO]);
            }

            if (IsChiho(ifr))
            {
                result.yakus.Add(yakuString[(int)MJUtil.Yaku.CHIHO], yakuHanNum[(int)MJUtil.Yaku.CHIHO]);
            }

            if (HasYakuman(result.yakus))
            {
                result.yakus     = SelectYakuman(result.yakus);
                result.IsYakuman = true;
            }

            //飜数計算
            result.Han = CalcHanSum(result);
            return(result);
        }