/// <summary> /// 探索し、結果を返却します。 /// </summary> /// <param name="context">フィールド状態</param> /// <returns>移動方向</returns> public Direction Search(FieldContext context) { StopWatchLogger.StartEventWatch("NegaMaxTemplate.SearchBestValue"); this.Value = this.SearchBestValue(context.DeepCopy(), 1, DefaultAlpha, DefaultBeta); FileHelper.WriteLine("BestScore:" + this.Value); StopWatchLogger.StopEventWatch("NegaMaxTemplate.SearchBestValue"); StopWatchLogger.WriteAllEventTimes("./log/eventtime.txt"); return(this.key); }
/// <summary> /// 評価値を取得する /// </summary> /// <returns></returns> protected override double GetEvaluate(FieldContext context) { StopWatchLogger.StartEventWatch("SearchBestPointer-GetEvaluate"); var score = this.Evaluator.Evaluate(context); StopWatchLogger.StopEventWatch("SearchBestPointer-GetEvaluate"); FileHelper.WriteLine($"score:{score} direction:{context.OperationDirection}"); return(score * this.GetParity(context)); }
/// <summary> /// <para>最善手を探索して取得する</para> /// </summary> /// <returns></returns> protected double SearchBestValue(FieldContext context, int depth, double alpha, double beta) { // 深さ制限に達した if (this.IsLimit(depth)) { return(this.GetEvaluate(context)); } // 可能な手をすべて生成 var leafList = this.GetAllLeaf(context); double maxKeyValue = DefaultAlpha; if (leafList.Count() > 0) { // ソート StopWatchLogger.StartEventWatch("MoveOrdering"); if (this.IsOrdering(depth)) { leafList = this.MoveOrdering(leafList, context); } StopWatchLogger.StopEventWatch("MoveOrdering"); var lastContext = context.DeepCopy(); foreach (Direction leaf in leafList) { // 前処理 StopWatchLogger.StartEventWatch("SearchSetUp"); this.SearchSetUp(context, leaf); StopWatchLogger.StopEventWatch("SearchSetUp"); double value = this.SearchBestValue(context, depth + 1, -beta, -alpha) * -1; // 後処理 StopWatchLogger.StartEventWatch("SearchTearDown"); //context = this.SearchTearDown(lastContext); context = lastContext.DeepCopy(); StopWatchLogger.StopEventWatch("SearchTearDown"); // ベータ刈り if (value >= beta) { this.SetKey(leaf, depth); return(value); } if (value > maxKeyValue) { // より良い手が見つかった this.SetKey(leaf, depth); maxKeyValue = value; // α値の更新 alpha = Math.Max(alpha, maxKeyValue); } } } else { // ▼パスの場合▼ // 前処理 var lastContext = context.DeepCopy(); this.PassSetUp(context); maxKeyValue = this.SearchBestValue(context, depth + 1, -beta, -alpha) * -1; // 後処理 //context = this.PassTearDown(lastContext); context = lastContext.DeepCopy(); } Debug.Assert(((maxKeyValue != DefaultAlpha) && (maxKeyValue != DefaultBeta)), "デフォルト値のまま返そうとしています。"); return(maxKeyValue); }