//Meが動くとする。「Meのスコア - Enemyのスコア」の最大値を返す。 private int NegaMax(int deepness, SearchState state, int alpha, int beta, int count, PointEvaluator.Base evaluator, Decided ngMove, int greedyDepth) { if (deepness == 0) { for (int j = 0; j < greedyDepth; j++) { Way move = state.MakeGreedyMove(ScoreBoard, WayEnumerator); state.Move(move.Agent1Way, move.Agent2Way); //Ways moves = state.MakeMoves(WayEnumerator); //SortMoves(ScoreBoard, state, moves, 49, null); //state.Move(moves[0].Agent1Way, moves[1].Agent2Way); } int score = evaluator.Calculate(ScoreBoard, state.MeBoard, 0) - evaluator.Calculate(ScoreBoard, state.EnemyBoard, 0); if (greedyDepth % 2 == 1) { return(-score); } return(score); } Ways ways = state.MakeMoves(WayEnumerator); SortMoves(ScoreBoard, state, ways, count, ngMove); for (int i = 0; i < ways.Count; i++) { if (CancellationToken.IsCancellationRequested == true) { return(alpha); } //何を返しても良いのでとにかく返す //if (count == 0 && !(ngMove is null) && new Decided(ways[i].Agent1Way, ways[i].Agent2Way).Equals(ngMove)) { continue; } //競合手を避ける場合 if (count == 0 && !(ngMove is null) && (ways[i].Agent1Way.Equals(ngMove.MeAgent1) || ways[i].Agent2Way.Equals(ngMove.MeAgent2))) { continue; } //2人とも競合手とは違う手を指す SearchState nextState = state; nextState.Move(ways[i].Agent1Way, ways[i].Agent2Way); int res = -NegaMax(deepness - 1, nextState, -beta, -alpha, count + 1, evaluator, ngMove, greedyDepth); if (alpha < res) { alpha = res; if (ngMove is null) { dp1[count].UpdateScore(alpha, ways[i].Agent1Way, ways[i].Agent2Way); } else { dp2[count].UpdateScore(alpha, ways[i].Agent1Way, ways[i].Agent2Way); } if (alpha >= beta) { return(beta); //βcut } } } ways.Erase(); WaysPool.Return(ways); return(alpha); }
//Meが動くとする。「Meのスコア - Enemyのスコア」の最大値を返す。 private int NegaMax(int deepness, SearchState state, int alpha, int beta, int count, PointEvaluator.Base evaluator) { if (deepness == 0) { return(evaluator.Calculate(ScoreBoard, state.MeBoard, 0) - evaluator.Calculate(ScoreBoard, state.EnemyBoard, 0)); } Ways ways = state.MakeMoves(WayEnumerator); SortMoves(ScoreBoard, state, ways, count); for (int i = 0; i < ways.Count; i++) { if (CancellationToken.IsCancellationRequested == true) { return(alpha); } //何を返しても良いのでとにかく返す SearchState backup = state; state.Move(ways[i].Agent1Way, ways[i].Agent2Way); int res = -NegaMax(deepness - 1, state, -beta, -alpha, count + 1, evaluator); if (alpha < res) { alpha = res; dp[count].UpdateScore(alpha, ways[i].Agent1Way, ways[i].Agent2Way); if (alpha >= beta) { return(beta); //βcut } } state = backup; } ways.Erase(); WaysPool.Return(ways); return(alpha); }
//Meが動くとする。「Meのスコア - Enemyのスコア」の最大値を返す。 private int NegaMax(int deepness, SearchState state, int alpha, int beta, int count, PointEvaluator.Base evaluator, int greedyDepth) { if (deepness == 0) { //深さgreedyDepth分だけ貪欲をしてから、評価関数を呼び出す for (int i = 0; i < greedyDepth; i++) { Ways moves = state.MakeMoves(WayEnumerator); SortMoves(ScoreBoard, state, moves, dp.Length - 1); state.Move(moves[0].Agent1Way, moves[0].Agent2Way); } int eval = evaluator.Calculate(ScoreBoard, state.MeBoard, 0) - evaluator.Calculate(ScoreBoard, state.EnemyBoard, 0); if (greedyDepth % 2 == 1) { return(-eval); } return(eval); } Ways ways = state.MakeMoves(WayEnumerator); SortMoves(ScoreBoard, state, ways, count); for (int i = 0; i < ways.Count; i++) { if (CancellationToken.IsCancellationRequested == true) { return(alpha); } //何を返しても良いのでとにかく返す if (count == 0 && ngMove != null && new Decided(ways[i].Agent1Way, ways[i].Agent2Way).Equals(ngMove) == true) { continue; } //競合手は指さない SearchState backup = state; state.Move(ways[i].Agent1Way, ways[i].Agent2Way); int res = -NegaMax(deepness - 1, state, -beta, -alpha, count + 1, evaluator, greedyDepth); if (alpha < res) { alpha = res; dp[count].UpdateScore(alpha, ways[i].Agent1Way, ways[i].Agent2Way); if (alpha >= beta) { return(beta); //βcut } } state = backup; } ways.Erase(); WaysPool.Return(ways); return(alpha); }
//Meが動くとする。「Meのタイルポイント - Enemyのタイルポイント」の最大値を返す。 private int NegaMax(int deepness, SearchState state, int alpha, int beta, int count, int tilePoint) { if (deepness == 0) { return(tilePoint); } VelocityPoint[] WayEnumerator = CurrentTurn * 2 + deepness <= 50 ? WayEnumerator1 : WayEnumerator2; Ways ways = state.MakeMoves(WayEnumerator); SortMoves(ScoreBoard, state, ways, count); for (int i = 0; i < ways.Count; i++) { if (CancellationToken.IsCancellationRequested == true) { return(alpha); } //何を返しても良いのでとにかく返す SearchState backup = state; state.Move(ways[i].Agent1Way, ways[i].Agent2Way); int res = -NegaMax(deepness - 1, state, -beta, -alpha, count + 1, -(tilePoint + ways[i].Point)); if (alpha < res) { alpha = res; dp[count].UpdateScore(alpha, ways[i].Agent1Way, ways[i].Agent2Way); if (alpha >= beta) { return(beta); //βcut } } state = backup; } ways.Erase(); WaysPool.Return(ways); return(alpha); }