示例#1
0
        public static void Assert_HirateHonsyogi(SkyBuffer dst_Sky, string failMessage)
        {
            //平手本将棋用
            //#if DEBUG
            //            {
            //                StringBuilder sb = new StringBuilder();
            //                int fukuro = 0;
            //                int ban = 0;
            //                int dai = 0;
            //                dst_Sky.Foreach_Starlights((Finger finger, Starlight light, ref bool toBreak) =>
            //                {
            //                    RO_Star_Koma koma = Util_Koma.AsKoma(light.Now);

            //                    if (Util_MasuNum.OnKomabukuro(Util_Masu.AsMasuNumber(koma.Masu)))
            //                    {
            //                        sb.Append("[袋" + Util_Masu.AsMasuNumber(koma.Masu) + "]");
            //                        fukuro++;
            //                    }
            //                    else if (Util_MasuNum.OnShogiban(Util_Masu.AsMasuNumber(koma.Masu)))
            //                    {
            //                        sb.Append("[盤" + Util_Masu.AsMasuNumber(koma.Masu) + "]");
            //                        ban++;
            //                    }
            //                    else if (Util_MasuNum.OnKomadai(Util_Masu.AsMasuNumber(koma.Masu)))
            //                    {
            //                        sb.Append("[台" + Util_Masu.AsMasuNumber(koma.Masu) + "]");
            //                        dai++;
            //                    }
            //                });
            //                Debug.Assert(40 == ban + dai || 40 == fukuro, "駒袋に駒が!fukuro=[" + fukuro + "] ban=[" + ban + "] dai=[" + dai + "] " + failMessage + " "+sb.ToString());
            //            }
            //#endif
        }
示例#2
0
        public static SkyConst Sasu(
            SkyConst src_Sky,         //現局面
            Finger finger,            //動かす駒
            SyElement masu,           //移動先マス
            Playerside pside_genTeban //動かす駒がどちらのプレイヤーのものか
            )
        {
            SkyBuffer dst_Sky = new SkyBuffer(src_Sky.Clone()); // 現局面をコピーします。

            // 移動先に相手の駒がないか、確認します。
            Finger tottaKoma = Util_Sky.Fingers_AtMasuNow(new SkyConst(dst_Sky), masu).ToFirst();

            if (tottaKoma != Fingers.Error_1)
            {
                // なにか駒を取ったら
                SyElement akiMasu;

                if (pside_genTeban == Playerside.P1)
                {
                    akiMasu = KifuIO.GetKomadaiKomabukuroSpace(Okiba.Sente_Komadai, new SkyConst(dst_Sky));
                }
                else
                {
                    akiMasu = KifuIO.GetKomadaiKomabukuroSpace(Okiba.Gote_Komadai, new SkyConst(dst_Sky));
                }


                RO_Star_Koma koma = Util_Koma.AsKoma(dst_Sky.StarlightIndexOf(tottaKoma).Now);

                // FIXME:配役あってるか?
                dst_Sky.AddOverwriteStarlight(tottaKoma, new RO_MotionlessStarlight(new RO_Star_Koma(pside_genTeban, akiMasu, koma.Syurui)));//tottaKoma,
            }

            // 駒を1個動かします。
            // FIXME: 取った駒はどうなっている?
            {
                RO_Star_Koma koma = Util_Koma.AsKoma(dst_Sky.StarlightIndexOf(finger).Now);

                dst_Sky.AddOverwriteStarlight(finger, new RO_MotionlessStarlight(new RO_Star_Koma(pside_genTeban, masu, koma.Syurui)));//finger,
            }

            return(new SkyConst(dst_Sky));
        }
示例#3
0
        public SkyConst ToSky()
        {
            // 駒40個に、Finger番号を割り当てておきます。
            SkyBuffer dst_Sky = new SkyBuffer();// 駒数0。
            //SkyBuffer dst_Sky = new SkyBuffer(Util_Sky.New_Komabukuro());// SFENインポート時


            Dictionary <Finger, RO_Star_Koma> komaDic = new Dictionary <Finger, RO_Star_Koma>();


            // ・インクリメントするので、Finger型ではなく int型で。
            // ・駒を取ったときに、先手後手は浮動するので区別できない。
            // 王 0~1
            int int_fingerK1 = 0;
            int int_fingerK2 = 1;
            // 飛車 2~3
            int int_fingerR1 = 2;
            int int_fingerR2 = 3;
            // 角 4~5
            int int_fingerB1 = 4;
            int int_fingerB2 = 5;
            // 金 6~9
            int int_fingerG1 = 6;
            int int_fingerG2 = 8;
            // 銀 10~13
            int int_fingerS1 = 10;
            int int_fingerS2 = 12;
            // 桂 14~17
            int int_fingerN1 = 14;
            int int_fingerN2 = 16;
            // 香 18~21
            int int_fingerL1 = 18;
            int int_fingerL2 = 20;
            // 歩 22~30,31~39
            int int_fingerP1 = 22;
            int int_fingerP2 = 31;

            //
            // どの升に、どの駒がいるか
            //
            foreach (KeyValuePair <Basho, RO_Star_Koma> entry in this.banAndKoma)
            {
                int int_finger;

                // 今回のカウント
                switch (entry.Value.Syurui)
                {
                case PieceType.P:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerP1; break;

                    case Playerside.P2: int_finger = int_fingerP2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.L:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerL1; break;

                    case Playerside.P2: int_finger = int_fingerL2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.N:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerN1; break;

                    case Playerside.P2: int_finger = int_fingerN2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.S:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerS1; break;

                    case Playerside.P2: int_finger = int_fingerS2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.G:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerG1; break;

                    case Playerside.P2: int_finger = int_fingerG2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.K:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerK1; break;

                    case Playerside.P2: int_finger = int_fingerK2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.R:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerR1; break;

                    case Playerside.P2: int_finger = int_fingerR2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.B:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerB1; break;

                    case Playerside.P2: int_finger = int_fingerB2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.PR:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerR1; break;

                    case Playerside.P2: int_finger = int_fingerR2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.PB:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerB1; break;

                    case Playerside.P2: int_finger = int_fingerB2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.PP:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerP1; break;

                    case Playerside.P2: int_finger = int_fingerP2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.PL:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerL1; break;

                    case Playerside.P2: int_finger = int_fingerL2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.PN:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerN1; break;

                    case Playerside.P2: int_finger = int_fingerN2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.PS:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_finger = int_fingerS1; break;

                    case Playerside.P2: int_finger = int_fingerS2; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                default: throw new Exception($"未対応の駒種類=[{entry.Value.Syurui}]");
                }

                Debug.Assert(0 <= int_finger && int_finger <= 39, "finger=[" + int_finger + "]");

                Debug.Assert(!komaDic.ContainsKey(int_finger), "finger=[" + int_finger + "]");

                komaDic.Add(int_finger, entry.Value);


                // カウントアップ
                switch (entry.Value.Syurui)
                {
                case PieceType.P:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerP1++; break;

                    case Playerside.P2: int_fingerP2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.L:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerL1++; break;

                    case Playerside.P2: int_fingerL2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.N:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerN1++; break;

                    case Playerside.P2: int_fingerN2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.S:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerS1++; break;

                    case Playerside.P2: int_fingerS2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.G:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerG1++; break;

                    case Playerside.P2: int_fingerG2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.K:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerK1++; break;

                    case Playerside.P2: int_fingerK2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.R:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerR1++; break;

                    case Playerside.P2: int_fingerR2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.B:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerB1++; break;

                    case Playerside.P2: int_fingerB2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.PR:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerR1++; break;

                    case Playerside.P2: int_fingerR2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.PB:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerB1++; break;

                    case Playerside.P2: int_fingerB2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.PP:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerP1++; break;

                    case Playerside.P2: int_fingerP2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.PL:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerL1++; break;

                    case Playerside.P2: int_fingerL2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.PN:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerN1++; break;

                    case Playerside.P2: int_fingerN2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                case PieceType.PS:
                    switch (entry.Value.Pside)
                    {
                    case Playerside.P1: int_fingerS1++; break;

                    case Playerside.P2: int_fingerS2++; break;

                    default: throw new Exception("未対応のプレイヤー番号");
                    }
                    break;

                default:
                    throw new Exception($"未対応の駒種類=[{entry.Value.Syurui}]");
                }
            }

            //
            // 40個の駒が、どの升に居るか
            //
            {
                // finger の順に並べる。
                RO_Star_Koma[] komas = new RO_Star_Koma[40];

                foreach (KeyValuePair <Finger, RO_Star_Koma> entry in komaDic)
                {
                    Debug.Assert(0 <= (int)entry.Key && (int)entry.Key <= 39, "entry.Key=[" + (int)entry.Key + "]");

                    komas[(int)entry.Key] = entry.Value;
                }

                // finger の順に追加。
                int komaHandle = 0;
                foreach (RO_Star_Koma koma in komas)
                {
                    dst_Sky.AddOverwriteStarlight(
                        komaHandle,
                        new RO_MotionlessStarlight(
                            //komaHandle,
                            koma
                            )
                        );
                    komaHandle++;
                }
            }

            StartposImporter.Assert_HirateHonsyogi(dst_Sky, "ToSkyの終了直前 this.InputLine=[" + this.InputLine + "]");

            return(new SkyConst(dst_Sky));
        }
示例#4
0
        /// <summary>
        /// 棋譜[再生]時用(マウス操作のときは関係ない)
        ///
        ///         一手進む、一手[巻戻し]に対応。
        ///
        /// </summary>
        /// <param name="move">棋譜に記録するために「指す前/指した後」を含めた手。</param>
        /// <param name="kifu"></param>
        /// <param name="isMakimodosi"></param>
        private static void Kifusasi52_WhenKifuRead(
            Starlight dst,
            PieceType syurui2,
            ref Finger figMovedKoma,
            out Finger out_figFoodKoma,
            ShootingStarlightable move,
            KifuTree kifu,
            bool isMakimodosi,
            out Node <ShootingStarlightable, KyokumenWrapper> out_newNode_OrNull
            )
        {
            out_figFoodKoma = Fingers.Error_1;

            // Sky 局面データは、この関数の途中で何回か変更されます。ローカル変数に退避しておくと、同期が取れなくなります。

            //------------------------------------------------------------
            // 駒を取る
            //------------------------------------------------------------
            if (!isMakimodosi)
            {
                RO_Star_Koma dstKoma = Util_Koma.AsKoma(dst.Now);


                PieceType foodKomaSyurui;//取られた駒の種類

                //----------
                // 将棋盤上のその場所に駒はあるか
                //----------
                foodKomaSyurui  = PieceType.None;                                                                         //ひとまずクリアー
                out_figFoodKoma = Util_Sky.Fingers_AtMasuNow(kifu.CurNode.Value.ToKyokumenConst, dstKoma.Masu).ToFirst(); //盤上

                if (Fingers.Error_1 != out_figFoodKoma)
                {
                    //>>>>> 指した先に駒があったなら

                    //
                    // 取られる駒
                    //
                    foodKomaSyurui = Util_Koma.AsKoma(kifu.CurNode.Value.ToKyokumenConst.StarlightIndexOf(out_figFoodKoma).Now).Syurui;

                    //
                    // 取られる駒は、駒置き場の空きマスに移動させます。
                    //
                    Okiba      okiba;
                    Playerside pside;
                    switch (dstKoma.Pside)
                    {
                    case Playerside.P1:
                    {
                        okiba = Okiba.Sente_Komadai;
                        pside = Playerside.P1;
                    }
                    break;

                    case Playerside.P2:
                    {
                        okiba = Okiba.Gote_Komadai;
                        pside = Playerside.P2;
                    }
                    break;

                    default:
                    {
                        //>>>>> エラー: 先後がおかしいです。

                        throw new Exception($@"エラー: 先後がおかしいです。
dst.Pside={dstKoma.Pside}");
                    }
                    }

                    // 駒台の空きスペース
                    SyElement akiMasu = akiMasu = KifuIO.GetKomadaiKomabukuroSpace(okiba, kifu.CurNode.Value.ToKyokumenConst);

                    if (Masu_Honshogi.Error == akiMasu)
                    {
                        //>>>>> エラー: 駒台に空きスペースがありませんでした。
                        throw new Exception($@"エラー: 駒台に空きスペースがありませんでした。
駒台={Okiba.Gote_Komadai}");
                    }

                    //>>>>> 駒台に空きスペースがありました。

                    //
                    // 取られる動き
                    //
                    {
                        SkyBuffer buffer_Sky = new SkyBuffer(kifu.CurNode.Value.ToKyokumenConst);
                        buffer_Sky.AddOverwriteStarlight(
                            out_figFoodKoma,
                            new RO_MotionlessStarlight(
                                //out_figFoodKoma,
                                new RO_Star_Koma(
                                    pside,
                                    akiMasu,                                                                                          //駒台の空きマスへ
                                    Util_Koma.AsKoma(kifu.CurNode.Value.ToKyokumenConst.StarlightIndexOf(out_figFoodKoma).Now).Syurui //駒の種類
                                    )
                                )
                            );
                        kifu.CurNode.Value.SetKyokumen(new SkyConst(buffer_Sky));
                        // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                        // この時点で局面データに変更あり
                        // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                    }



                    //------------------------------
                    // 成っていれば、「成り」は解除。
                    //------------------------------
                    RO_Star_Koma koma3 = Util_Koma.AsKoma(kifu.CurNode.Value.ToKyokumenConst.StarlightIndexOf(out_figFoodKoma).Now);


                    switch (Util_Masu.GetOkiba(koma3.Masu))
                    {
                    case Okiba.Sente_Komadai:    //thru
                    case Okiba.Gote_Komadai:
                        // 駒台へ移動しました
                        //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                        SkyBuffer buffer_Sky = new SkyBuffer(kifu.CurNode.Value.ToKyokumenConst);
                        buffer_Sky.AddOverwriteStarlight(out_figFoodKoma, new RO_MotionlessStarlight(
                                                             //out_figFoodKoma,
                                                             new RO_Star_Koma(koma3.Pside,
                                                                              koma3.Masu,
                                                                              koma3.ToNarazuCase())
                                                             )
                                                         );
                        kifu.CurNode.Value.SetKyokumen(new SkyConst(buffer_Sky));
                        // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                        // この時点で局面データに変更あり
                        // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

                        break;
                    }


                    //------------------------------
                    // 取った駒を棋譜に覚えさせます。(差替え)
                    //------------------------------
                    kifu.AppendChildB_Swap(
                        foodKomaSyurui,
                        kifu.CurNode.Value.ToKyokumenConst,
                        "KifuIO_Kifusasi52"
                        );
                    //}
                }
            }

            //------------------------------------------------------------
            // 駒の移動
            //------------------------------------------------------------
            {
                SkyBuffer buffer_Sky = new SkyBuffer(kifu.CurNode.Value.ToKyokumenConst);
                buffer_Sky.AddOverwriteStarlight(figMovedKoma, dst);
                kifu.CurNode.Value.SetKyokumen(new SkyConst(buffer_Sky));
            }
            // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
            // この時点で局面データに変更あり
            // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


            //------------------------------------------------------------
            // 取った駒を戻す
            //------------------------------------------------------------
            if (isMakimodosi)
            {
                RO_Star_Koma koma = Util_Koma.AsKoma(move.Now);


                if (PieceType.None != (PieceType)move.FoodKomaSyurui)
                {
                    // 駒台から、駒を検索します。
                    Okiba okiba;
                    if (Playerside.P2 == koma.Pside)
                    {
                        okiba = Okiba.Gote_Komadai;
                    }
                    else
                    {
                        okiba = Okiba.Sente_Komadai;
                    }


                    // 取った駒は、種類が同じなら、駒台のどの駒でも同じです。
                    Finger temp_figFoodKoma = Util_Sky.FingerNow_BySyuruiIgnoreCase(kifu.CurNode.Value.ToKyokumenConst, okiba, (PieceType)move.FoodKomaSyurui);
                    if (Fingers.Error_1 != temp_figFoodKoma)
                    {
                        // 取った駒のデータをセットし直します。
                        SkyBuffer buffer_Sky = new SkyBuffer(kifu.CurNode.Value.ToKyokumenConst);

                        buffer_Sky.AddOverwriteStarlight(
                            temp_figFoodKoma,
                            new RO_MotionlessStarlight(
                                //temp_figFoodKoma,
                                new RO_Star_Koma(
                                    Converter04.AlternatePside(koma.Pside), //先後を逆にして駒台に置きます。
                                    koma.Masu,                              // マス
                                    (PieceType)move.FoodKomaSyurui
                                    )
                                )
                            );

                        kifu.CurNode.Value.SetKyokumen(new SkyConst(buffer_Sky));
                        // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                        // この時点で局面データに変更あり
                        // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

                        out_figFoodKoma = temp_figFoodKoma;
                    }
                }
            }


            //
            // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
            // 局面データに変更があったものとして進めます。
            // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
            //
            out_newNode_OrNull = kifu.CurNode;// この変数を返すのがポイント。
            {
                out_newNode_OrNull.Value.SetKyokumen(kifu.CurNode.Value.ToKyokumenConst);

                kifu.CurNode.Value.SetKyokumen(kifu.CurNode.Value.ToKyokumenConst);
            }
        }