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 }
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)); }
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)); }
/// <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); } }