/// <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 = 0.0d; SkyConst src_Sky = args.Node.Value.ToKyokumenConst; // // どの駒(のある場所)が // 指定のマスより、どれぐらい離れているか(距離) // int kyori = Util_KomanoKyori.GetKyori(args.TenonagareGenjo.Masu, args.TenonagareGenjo.Koma1.Masu); score = 100.0d - 3.0d * kyori;//てきとーな数字です。 //// ログ //{ // string move = Converter04.Move_ToString_ForLog(args.Input_node.Key);// どの指し手の局面で // ((ShogiEngine)args.Owner).Log_Engine.WriteLine_AddMemo("駒[" + Haiyaku184Array.Name[(int)koma.Haiyaku].Trim() + "(No." + (int)((Atamanosumi)args.atamanosumi).Finger + ")]が、マス[" + Converter04.Masu_ToKanji(((Atamanosumi)args.Input_atamanosumi).Masu) + "]を目指したいんだぜ~☆。指し手が[" + move + "]なら、距離は[" + kyori + "]、スコアは[" + score + "]だぜ☆"); //} string meisai = ""; #if DEBUG // 明細 { StringBuilder sb = new StringBuilder(); sb.Append("100.0d - 3.0d * (距離 " + kyori + ")"); meisai = sb.ToString(); } #endif kyokumenScore = new KyHyoka100limitItemImpl(args.TenonagareGenjo.ScoreKeisu, score, meisai); }
/// <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 = 0.0d; SkyConst src_Sky = args.Node.Value.ToKyokumenConst; // // 指定された駒。 // RO_Star_Koma koma1 = args.TenonagareGenjo.Koma1; if (Okiba.ShogiBan != Util_Masu.Masu_ToOkiba(koma1.Masu)) { // 指定された駒が将棋盤の上になければ、無視。 goto gt_EndMethod; } // // 初期位置にいると、点数が低いものとします。 // if (koma1.Masu == args.TenonagareGenjo.Masu) { score = 0.0d; } else { score = 100.0d; } //// //// 先手から見た盤に回転。 //// //SyElement komaMasu = Util_Masu.BothSenteView(koma1.Masu, koma1.Pside); //int dan; //Util_MasuNum.MasuToDan(komaMasu, out dan); gt_EndMethod: string meisai = ""; #if DEBUG // 明細 { StringBuilder sb = new StringBuilder(); // 初期位置にいると、点数が低いものとします。 if (koma1.Masu == args.TenonagareGenjo.Masu) { sb.Append("(初期位置 0.0d)"); } else { sb.Append("(初期位置から離れている 100.0d)"); } meisai = sb.ToString(); } #endif kyokumenScore = new KyHyoka100limitItemImpl(args.TenonagareGenjo.ScoreKeisu, score, meisai); }
/// <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 keisanArgs) { Util_Lua_KifuWarabe.Perform("score_kimagure"); string meisai = ""; double score; #if DEBUG // 明細 { StringBuilder sb = new StringBuilder(); sb.Append("きまぐれ "); sb.Append(Util_Lua_KifuWarabe.Score); meisai = sb.ToString(); score = Util_Lua_KifuWarabe.Score; } #else score = LarabeRandom.Random.NextDouble() * 100.0d; #endif kyokumenScore = new KyHyoka100limitItemImpl(keisanArgs.TenonagareGenjo.ScoreKeisu, score, meisai); }
/// <summary> /// 0.0d ~100.0d の範囲で、評価値を返します。数字が大きい方がグッドです。 /// </summary> /// <param name="keisanArgs"></param> /// <returns></returns> abstract public void Keisan(out KyHyokaItem kyokumenScore, KyHandanArgs keisanArgs);
/// <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> /// 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); }
/// <summary> /// 0.0d ~100.0d の範囲で、評価値を返します。数字が大きい方がグッドです。 /// </summary> /// <param name="args"></param> /// <returns></returns> public override void Keisan(out KyHyokaItem kyokumenScore, KyHandanArgs args) { double score = 0.0d; SkyConst src_Sky = args.Node.Value.ToKyokumenConst; // まず、プレイヤー1の視点で得点計算します。 double score_player1 = 0.0d; src_Sky.Foreach_Starlights((Finger finger, Starlight light, ref bool toBreak) => { RO_MotionlessStarlight ms = (RO_MotionlessStarlight)light; RO_Star_Koma koma = Util_Koma.AsKoma(ms.Now); // 単純に駒の種類による点数。 double komaScore = 0.0d; switch (koma.Syurui) { case PieceType.P: komaScore = 1.0d; break; case PieceType.L: komaScore = 3.0d; break; case PieceType.N: komaScore = 3.5d; break; case PieceType.S: komaScore = 9.0d; break; case PieceType.G: komaScore = 9.5d; break; case PieceType.K: komaScore = 100.0d; break; case PieceType.R: komaScore = 25.0d; break; case PieceType.B: komaScore = 20.0d; break; case PieceType.PR: komaScore = 25.0d; break; case PieceType.PB: komaScore = 20.0d; break; case PieceType.PP: komaScore = 9.5d; break; case PieceType.PL: komaScore = 10.0d; break; case PieceType.PN: komaScore = 10.5d; break; case PieceType.PS: komaScore = 11.0d; break; default: komaScore = 0; break; } if (koma.Pside == Playerside.P1) { // プレイヤー1の駒はそのまま } else { // プレイヤー1の駒以外は、ひっくり返します。 komaScore *= -1; } score_player1 += komaScore; }); if (args.PlayerInfo.Playerside == Playerside.P1) { // プレイヤー1はそのまま score = score_player1; } else { // プレイヤー1以外は、ひっくり返します。 score = 100.0d - score_player1; } string meisai = ""; #if DEBUG // 明細 { StringBuilder sb = new StringBuilder(); sb.Append("駒得"); meisai = sb.ToString(); } #endif kyokumenScore = new KyHyoka100limitItemImpl(args.TenonagareGenjo.ScoreKeisu, score, meisai); }
/// <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); }
/// <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 = 0.0d; SkyConst src_Sky = args.Node.Value.ToKyokumenConst; // // 自玉 // RO_Star_Koma jiGyoku = null; foreach (Finger figKoma in Finger_Honshogi.Items_KomaOnly)// 全駒 { RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(figKoma).Now); if (koma.Pside == args.PlayerInfo.Playerside && koma.Syurui == PieceType.K) { jiGyoku = koma; break; } } if (null == jiGyoku) { goto gt_EndMethod; } int jiGyoku_Suji; Util_MasuNum.MasuToSuji(jiGyoku.Masu, out jiGyoku_Suji); int jiGyoku_Dan; Util_MasuNum.MasuToDan(jiGyoku.Masu, out jiGyoku_Dan); int[] sujis = new int[25]; int[] dans = new int[25]; { // // 25近傍。12の位置に、視点の中心となる駒があるとします。 // // -2 -1 0 +1 +2 // ┌─┬─┬─┬─┬─┐ //-2│ 0│ 1│ 2│ 3│ 4│ // ├─┼─┼─┼─┼─┤ //-1│ 5│ 6│ 7│ 8│ 9│ // ├─┼─┼─┼─┼─┤ // 0│10│11│12│13│14│ // ├─┼─┼─┼─┼─┤ //+1│15│16│17│18│19│ // ├─┼─┼─┼─┼─┤ //+2│20│21│22│23│24│ // └─┴─┴─┴─┴─┘ // int index = 0; for (int dDan = -2; dDan < 3; dDan++) { for (int dSuji = -2; dSuji < 3; dSuji++) { sujis[index] = jiGyoku_Suji + dSuji; dans[index] = jiGyoku_Dan + dDan; index++; } } } // 25近傍に、得点の重みを付けます。 double aa = 0.0d; double bb = 100.0d; double cc = 100.0d / 3.0d; double dd = 100.0d / 3.0d / 3.0d; double ee = 100.0d / 3.0d / 3.0d / 3.0d; double ff = 100.0d / 3.0d / 3.0d / 3.0d / 3.0d; double[] omomi = new double[] { ff, ee, dd, ee, ff, ee, cc, bb, cc, ee, dd, bb, aa, bb, dd, ee, cc, bb, cc, ee, ff, ee, dd, ee, ff, }; // 25近傍のマス番号を取得しておきます。該当がなければ Masu_Honshogi.Error。 Dictionary <SyElement, double> masuOmomi = new Dictionary <SyElement, double>(); { for (int index = 0; index < 25; index++) { SyElement masu = Util_Masu.OkibaSujiDanToMasu(Okiba.ShogiBan, sujis[index], dans[index]); if (masu != Masu_Honshogi.Error) { masuOmomi.Add(masu, omomi[index]); } } } // // 味方の金、銀について。 // int countKanagoma = 0; // カナゴマ foreach (Finger figKoma in Finger_Honshogi.Items_KomaOnly) // 全駒 { RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(figKoma).Now); if (koma.Pside == args.PlayerInfo.Playerside && koma.Syurui == PieceType.S && koma.Syurui == PieceType.G ) { if (masuOmomi.ContainsKey(koma.Masu)) { score += masuOmomi[koma.Masu]; countKanagoma++; if (3 <= countKanagoma) { break; } } } } gt_EndMethod: string meisai = ""; #if DEBUG // 明細の作成 { StringBuilder sb = new StringBuilder(); sb.Append("略"); meisai = sb.ToString(); } #endif kyokumenScore = new KyHyoka100limitItemImpl(args.TenonagareGenjo.ScoreKeisu, score, meisai); }
/// <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 = 100.0d; StringBuilder sbMeisai = new StringBuilder(); SkyConst src_Sky = args.Node.Value.ToKyokumenConst; // // 各、味方の駒 // Fingers jiFigs = Util_Sky.Fingers_ByOkibaPsideNow(src_Sky, Okiba.ShogiBan, args.PlayerInfo.Playerside); foreach (Finger figKoma in jiFigs.Items) { // 自駒 RO_Star_Koma jiKoma = Util_Koma.FromFinger(src_Sky, figKoma); SyElement aiteMasu; if (args.PlayerInfo.Playerside == Playerside.P1) { aiteMasu = Util_Masu.Offset(Okiba.ShogiBan, jiKoma.Masu, 0, -1); } else { aiteMasu = Util_Masu.Offset(Okiba.ShogiBan, jiKoma.Masu, 0, +1); } Finger aiteKomaFig = Util_Sky.Fingers_AtMasuNow(src_Sky, aiteMasu).ToFirst(); if (Fingers.Error_1 == aiteKomaFig) { goto gt_Next1; } // 相手駒 RO_Star_Koma aiteKoma = Util_Koma.FromFinger(src_Sky, aiteKomaFig); if (aiteKoma.Syurui != PieceType.P) { // 歩じゃなければ無視。「と金」も無視。 goto gt_Next1; } score -= 20.0d; #if DEBUG // 明細 { sbMeisai.Append("-(20.0d)"); } #endif if (score <= 0.0d) { break; } gt_Next1: ; } kyokumenScore = new KyHyoka100limitItemImpl(args.TenonagareGenjo.ScoreKeisu, score, sbMeisai.ToString()); }