/// <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); }
/// <summary> /// 駒の利きを調べます。 /// </summary> /// <param name="src_Sky"></param> /// <returns></returns> public static KomanoKikiImpl MasuBETUKikisu(SkyConst src_Sky, Playerside tebanside) { { return(KomanoKikiImpl.BETUKAI(src_Sky, tebanside)); } /* * 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:貫通してないか? * // * SySet<SyElement> kikiZukei = Util_Sky.KomaKidou_Potential(figKoma, src_Sky); * * * * 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; */ }
/// <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); }
/// <summary> /// 0.0d ~100.0d の範囲で、評価値を返します。数字が大きい方がグッドです。 /// </summary> /// <param name="input_node"></param> /// <param name="playerInfo"></param> /// <returns></returns> public override void Keisan(out KyHyokaItem kyHyoka, KyHandanArgs args) { double score = 0.0d; SkyConst src_Sky = args.Node.Value.ToKyokumenConst; bool b1 = false; bool b2 = false; SyElement masuKtou;//角頭 if (args.PlayerInfo.Playerside == Playerside.P1) { masuKtou = Masu_Honshogi.ban87_8七; } else { masuKtou = Masu_Honshogi.ban23_2三; } // // 角頭に味方の駒があるか? // Finger masuKtou_KomaFig; RO_Star_Koma komaKtou = null; { masuKtou_KomaFig = Util_Sky.Fingers_AtMasuNow(src_Sky, masuKtou).ToFirst(); if (Fingers.Error_1 == masuKtou_KomaFig) { // 角頭に駒がない。 goto gt_Next1; } komaKtou = Util_Koma.FromFinger(src_Sky, masuKtou_KomaFig); if (args.PlayerInfo.Playerside != komaKtou.Pside) { // 味方の駒ではない。 goto gt_Next1; } score = 0.01d; b1 = true; } gt_Next1: // // 角頭の駒に、味方の駒が1つ以上利いているか? // int kikisu; { KomanoKiki komaNoKiki = KomanoKikiImpl.MasuBETUKikisu(src_Sky, args.Node.Tebanside); kikisu = komaNoKiki.Kikisu_AtMasu_Mikata[Util_Masu.AsMasuNumber(masuKtou)]; if (kikisu < 1) { // 1つも利いていない。 goto gt_Next2; } score = 1.0d; b2 = true; } gt_Next2: // // 項1と項2を同時に満たしている。 (計 100点) // if (b1 && b2) { score = 100.0d; } string meisai = ""; #if DEBUG // 明細 { StringBuilder sb = new StringBuilder(); if (args.PlayerInfo.Playerside == Playerside.P1) { sb.Append("(角頭 8七)"); } else { sb.Append("(角頭 2三)"); } if (Fingers.Error_1 == masuKtou_KomaFig) { // 角頭に駒がない。 sb.Append("(角頭 味方駒無)"); } else if (args.PlayerInfo.Playerside != komaKtou.Pside) { // 味方の駒ではない。 sb.Append("(角頭 非味方駒)"); } else if (b1) { sb.Append("(角頭 味方駒有 0.01)"); } if (kikisu < 1) { // 1つも利いていない。 sb.Append("(角頭に味方駒利き無 " + kikisu + ")"); } else if (b2) { sb.Append("(角頭に味方駒利き有 1.0)"); } // 項1と項2を同時に満たしている。 (計 100点) if (b1 && b2) { sb.Append("(項1、項2を同時に満たす 100.0)"); } meisai = sb.ToString(); } #endif kyHyoka = new KyHyoka100limitItemImpl(args.TenonagareGenjo.ScoreKeisu, score, meisai); }