Esempio n. 1
0
        /// <summary>
        /// 後手からも、先手のような座標で指示できるように変換します。
        /// </summary>
        /// <param name="masu"></param>
        /// <param name="pside"></param>
        /// <returns></returns>
        public static SyElement BothSenteView(SyElement masu, Playerside pside)
        {
            SyElement result = masu;

            // 将棋盤上で後手なら、180°回転します。
            if (Okiba.ShogiBan == Util_Masu.Masu_ToOkiba(masu) && pside == Playerside.P2)
            {
                result = Masu_Honshogi.Items_All[80 - Util_Masu.AsMasuNumber(masu)];
            }

            // 将棋盤で先手、または 駒台か 駒袋なら、指定されたマスにそのまま入れます。

            return(result);
        }
Esempio n. 2
0
        /// <summary>
        /// 0.0d ~100.0d の範囲で、評価値を返します。数字が大きい方がグッドです。
        /// </summary>
        /// <param name="input_node"></param>
        /// <param name="playerInfo"></param>
        /// <returns></returns>
        public override void Keisan(out KyHyokaItem kyokumenScore, KyHandanArgs args)
        {
            double   score;
            SkyConst src_Sky = args.Node.Value.ToKyokumenConst;

            //
            // 「紐が付いていない駒の少なさ」による加点。
            //
            int mikataHimoduki = 0; // 味方の駒に、味方の駒の利きが1つ被っていれば+1。
            int mikataNeraware = 0; // 味方の駒に、相手の駒の利きが1つ被っていれば+1。
            int aiteHimoduki   = 0; // 相手の駒に、相手の駒の利きが1つ被っていれば+1。
            int aiteNeraware   = 0; // 相手の駒に、味方の駒の利きが1つ被っていれば+1。


            List <string> mikataYaburareMasu = new List <string>();
            int           aiteWin            = 0; // 利きの枚数で相手が勝っていた件数。

            List <string> aiteYaburareMasu = new List <string>();
            int           mikataWin        = 0; // 利きの枚数で味方が勝っていた件数。



            //
            // 駒の利きの計算。
            //
            KomanoKiki komanoKiki = KomanoKikiImpl.MasuBETUKikisu(src_Sky, args.Node.Tebanside);



            //
            // 味方の駒があるマスの得点は、マイナスなら集計。(減点法)
            // 敵の駒があるマスの得点は、プラスなら集計。(減点法)
            //
            // 駒は40枚あり、貫通して加点するのもある。
            //
            foreach (Finger figKoma in Finger_Honshogi.Items_KomaOnly)// 全駒
            {
                RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(figKoma).Now);

                if (Okiba.ShogiBan != Util_Masu.Masu_ToOkiba(koma.Masu))
                {
                    goto gt_Next2;
                }

                if (args.PlayerInfo.Playerside == koma.Pside)
                {
                    // 味方の駒

                    // その升に利いている味方の利きの数。
                    int mikataKiki = komanoKiki.Kikisu_AtMasu_Mikata[Util_Masu.AsMasuNumber(koma.Masu)];

                    // その升に利いている相手の利きの数。
                    int aiteKiki = komanoKiki.Kikisu_AtMasu_Teki[Util_Masu.AsMasuNumber(koma.Masu)];

                    mikataHimoduki += mikataKiki;
                    mikataNeraware += aiteKiki;

                    // 破られる場合
                    if (mikataKiki < aiteKiki)
                    {
                        aiteWin++;
                        mikataYaburareMasu.Add(Converter04.Masu_ToKanji(koma.Masu));
                    }
                }
                else
                {
                    // 相手の駒

                    // その升に利いている相手の利きの数。
                    int aiteKiki = komanoKiki.Kikisu_AtMasu_Mikata[Util_Masu.AsMasuNumber(koma.Masu)];

                    // その升に利いている味方の利きの数。
                    int mikataKiki = komanoKiki.Kikisu_AtMasu_Teki[Util_Masu.AsMasuNumber(koma.Masu)];

                    aiteHimoduki = aiteKiki;
                    aiteNeraware = mikataKiki;

                    // 破られる場合
                    if (aiteKiki < mikataKiki)
                    {
                        mikataWin++;
                        aiteYaburareMasu.Add(Converter04.Masu_ToKanji(koma.Masu));
                    }
                }

gt_Next2:
                ;
            }


            // 集計。
            score = (double)(mikataWin - aiteWin) * 1.0 + 50.0d;

            string meisai = "";

#if DEBUG
            // 明細
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(" " + score);
                sb.Append("点    ");
                sb.Append(" 衝突箇所勝ち数=" + (mikataWin - aiteWin));
                sb.Append(" 味方が破られる" + aiteWin + "箇所");
                foreach (string s in mikataYaburareMasu)
                {
                    sb.Append("[");
                    sb.Append(s);
                    sb.Append("]");
                }

                sb.Append(" 相手が破られる" + mikataWin + "箇所");
                foreach (string s in aiteYaburareMasu)
                {
                    sb.Append("[");
                    sb.Append(s);
                    sb.Append("]");
                }
                meisai = sb.ToString();
            }
#endif

            kyokumenScore = new KyHyoka100limitItemImpl(args.TenonagareGenjo.ScoreKeisu, score, meisai);
        }
Esempio n. 3
0
        /// <summary>
        /// 別方法試し中。
        ///
        /// </summary>
        /// <param name="src_Sky"></param>
        public static KomanoKikiImpl BETUKAI(SkyConst src_Sky, Playerside tebanside)
        {
            // ①現手番の駒の移動可能場所_被王手含む
            List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus;

            Util_MovableMove.LA_Get_KomaBETUSusumeruMasus(
                out komaBETUSusumeruMasus, //進めるマス
                new MmGenjo_MovableMasuImpl(
                    true,                  //本将棋か
                    src_Sky,               //現在の局面
                    tebanside,             //手番
                    false                  //相手番か
                    ),
                null
                );

            KomanoKikiImpl self = new KomanoKikiImpl();

            //
            // 「升ごとの敵味方」を調べます。
            //
            foreach (Finger figKoma in Finger_Honshogi.Items_KomaOnly)// 全駒
            {
                RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(figKoma).Now);

                self.HMasu_PlayersideList[Util_Masu.AsMasuNumber(koma.Masu)] = koma.Pside;
            }

            //
            // 駒のない升は無視します。
            //

            //
            // 駒のあるマスに、その駒の味方のコマが効いていれば 味方+1
            //
            foreach (Finger figKoma in Finger_Honshogi.Items_KomaOnly)// 全駒
            {
                //
                // 駒
                //
                RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(figKoma).Now);

                // 将棋盤上の戦駒のみ判定
                if (Okiba.ShogiBan != Util_Masu.Masu_ToOkiba(koma.Masu))
                {
                    goto gt_Next1;
                }


                //
                // 駒の利き FIXME:貫通してないか?
                //
                komaBETUSusumeruMasus.Foreach_Entry((Finger figKoma2, SySet <SyElement> kikiZukei, ref bool toBreak) =>
                {
                    IEnumerable <SyElement> kikiMasuList = kikiZukei.Elements;
                    foreach (SyElement masu in kikiMasuList)
                    {
                        // その枡に利いている駒のハンドルを追加
                        if (self.HMasu_PlayersideList[Util_Masu.AsMasuNumber(masu)] == Playerside.Empty)
                        {
                            // 駒のないマスは無視。
                        }
                        else if (self.HMasu_PlayersideList[Util_Masu.AsMasuNumber(masu)] == koma.Pside)
                        {
                            // 利きのあるマスにある駒と、この駒のプレイヤーサイドが同じ。
                            self.Kikisu_AtMasu_Mikata[Util_Masu.AsMasuNumber(masu)] += 1;
                        }
                        else
                        {
                            // 反対の場合。
                            self.Kikisu_AtMasu_Teki[Util_Masu.AsMasuNumber(masu)] += 1;
                        }
                    }
                });

gt_Next1:
                ;
            }

            return(self);
        }
Esempio n. 4
0
        /// <summary>
        /// 「成り」ができるなら真。
        /// </summary>
        /// <returns></returns>
        private static bool IsPromotionable(
            out bool isPromotionable,
            RO_Star_Koma srcKoma,
            RO_Star_Koma dstKoma
            )
        {
            bool successful = true;

            isPromotionable = false;

            if (Okiba.ShogiBan != Util_Masu.Masu_ToOkiba(srcKoma.Masu))
            {
                successful = false;
                goto gt_EndMethod;
            }

            if (KomaSyurui14Array.IsNari(srcKoma.Syurui))
            {
                // 既に成っている駒は、「成り」の指し手を追加すると重複エラーになります。
                // 成りになれない、で正常終了します。
                goto gt_EndMethod;
            }

            int srcDan;

            if (!Util_MasuNum.MasuToDan(srcKoma.Masu, out srcDan))
            {
                throw new Exception("段に変換失敗");
            }

            int dstDan;

            if (!Util_MasuNum.MasuToDan(dstKoma.Masu, out dstDan))
            {
                throw new Exception("段に変換失敗");
            }

            // 先手か、後手かで大きく処理を分けます。
            switch (dstKoma.Pside)
            {
            case Playerside.P1:
            {
                if (srcDan <= 3)
                {
                    // 3段目から上にあった駒が移動したのなら、成りの資格ありです。
                    isPromotionable = true;
                    goto gt_EndMethod;
                }

                if (dstDan <= 3)
                {
                    // 3段目から上に駒が移動したのなら、成りの資格ありです。
                    isPromotionable = true;
                    goto gt_EndMethod;
                }
            }
            break;

            case Playerside.P2:
            {
                if (7 <= srcDan)
                {
                    // 7段目から下にあった駒が移動したのなら、成りの資格ありです。
                    isPromotionable = true;
                    goto gt_EndMethod;
                }

                if (7 <= dstDan)
                {
                    // 7段目から下に駒が移動したのなら、成りの資格ありです。
                    isPromotionable = true;
                    goto gt_EndMethod;
                }
            }
            break;

            default: throw new Exception("未定義のプレイヤーサイドです。");
            }
gt_EndMethod:
            ;
            return(successful);
        }
Esempio n. 5
0
        /// <summary>
        /// 0.0d ~100.0d の範囲で、評価値を返します。数字が大きい方がグッドです。
        /// </summary>
        /// <param name="input_node"></param>
        /// <param name="playerInfo"></param>
        /// <returns></returns>
        public override void Keisan(out KyHyokaItem kyokumenScore, KyHandanArgs args)
        {
            double   score   = 50.0d;
            SkyConst src_Sky = args.Node.Value.ToKyokumenConst;



            //
            // 「紐が付いていない駒の少なさ」による加点。
            //
            // 自分の駒について、味方の駒の利きが被っていれば+1(貫通)
            //                     敵の駒の利きが被っていれば-1(貫通)
            //
            //   敵の駒について、味方の駒の利きが被っていれば+1(貫通)
            //                     敵の駒の利きが被っていれば-1(貫通)
            //



            //
            // 駒のない升は無視し、
            // 駒のあるマスに、その駒の味方のコマが効いていれば +1
            // 駒のあるマスに、その駒の相手のコマが効いていれば -1
            //
            foreach (Finger figKoma in Finger_Honshogi.Items_KomaOnly)// 全駒
            {
                RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(figKoma).Now);

                if (Okiba.ShogiBan != Util_Masu.Masu_ToOkiba(koma.Masu))
                {
                    goto gt_Next1;
                }
                // 将棋盤上のみ。

                // 駒の利き
                SySet <SyElement> kikiZukei = Util_Sky.KomaKidou_Potential(figKoma, src_Sky);

                IEnumerable <SyElement> kikiMasuList = kikiZukei.Elements;
                // 通し
                double toosi = kikiMasuList.Count();

                // 係数
                switch (koma.Syurui)
                {
                case PieceType.P: toosi *= this.Keisu_Fu; break;

                case PieceType.L: toosi *= this.Keisu_Kyo; break;

                case PieceType.N: toosi *= this.Keisu_Kei; break;

                case PieceType.S: toosi *= this.Keisu_Gin; break;

                case PieceType.G: toosi *= this.Keisu_Kin; break;

                case PieceType.K: toosi *= this.Keisu_Oh; break;

                case PieceType.R: toosi *= this.Keisu_Hisya; break;

                case PieceType.B: toosi *= this.Keisu_Kaku; break;

                case PieceType.PR: toosi *= this.Keisu_Ryu; break;

                case PieceType.PB: toosi *= this.Keisu_Uma; break;

                case PieceType.PP: toosi *= this.Keisu_Tokin; break;

                case PieceType.PL: toosi *= this.Keisu_NariKyo; break;

                case PieceType.PN: toosi *= this.Keisu_NariKei; break;

                case PieceType.PS: toosi *= this.Keisu_NariGin; break;

                default: break;
                }

                if (args.PlayerInfo.Playerside == koma.Pside)
                {
                    // 味方の駒
                    score += toosi;
                }
                else
                {
                    // 敵の駒
                    score -= toosi;
                }

gt_Next1:
                ;
            }


            string meisai = "";

#if DEBUG
            // 明細
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("略");
                meisai = sb.ToString();
            }
#endif
            kyokumenScore = new KyHyoka100limitItemImpl(args.TenonagareGenjo.ScoreKeisu, score, meisai);
        }
Esempio n. 6
0
        /// <summary>
        /// デバッグ用文字列を作ります。
        /// </summary>
        /// <param name="masus"></param>
        /// <param name="memo"></param>
        /// <returns></returns>
        public static string Log_Masus(SySet <SyElement> masus, string memo)
        {
            StringBuilder sb = new StringBuilder();

            int errorCount = 0;

            // フォルスクリア
            bool[] ban81 = new bool[81];

            // フラグ立て
            foreach (Basho hMasu in masus.Elements)
            {
                if (Okiba.ShogiBan == Util_Masu.Masu_ToOkiba(Masu_Honshogi.Items_All[hMasu.MasuNumber]))
                {
                    ban81[hMasu.MasuNumber] = true;
                }
            }



            sb.AppendLine("...(^▽^)さて、局面は☆?");

            if (null != memo && "" != memo.Trim())
            {
                sb.AppendLine(memo);
            }

            sb.AppendLine(" 9 8 7 6 5 4 3 2 1");
            sb.AppendLine("┏━┯━┯━┯━┯━┯━┯━┯━┯━┓");
            for (int dan = 1; dan <= 9; dan++)
            {
                sb.Append("┃");
                for (int suji = 9; suji >= 1; suji--)// 筋は左右逆☆
                {
                    SyElement masu = Util_Masu.OkibaSujiDanToMasu(Okiba.ShogiBan, suji, dan);
                    if (Okiba.ShogiBan == Util_Masu.Masu_ToOkiba(masu))
                    {
                        if (ban81[Util_Masu.AsMasuNumber(masu)])
                        {
                            sb.Append("●");
                        }
                        else
                        {
                            sb.Append("  ");
                        }
                    }
                    else
                    {
                        errorCount++;
                        sb.Append("  ");
                    }


                    if (suji == 1)//1筋が最後だぜ☆
                    {
                        sb.Append("┃");
                        sb.AppendLine(ConverterKnSh.Int_ToKanSuji(dan));
                    }
                    else
                    {
                        sb.Append("│");
                    }
                }

                if (dan == 9)
                {
                    sb.AppendLine("┗━┷━┷━┷━┷━┷━┷━┷━┷━┛");
                }
                else
                {
                    sb.AppendLine("┠─┼─┼─┼─┼─┼─┼─┼─┼─┨");
                }
            }


            // 後手駒台
            sb.Append("エラー数:");
            sb.AppendLine(errorCount.ToString());
            sb.AppendLine("...(^▽^)ドウダッタカナ~☆");


            return(sb.ToString());
        }