Exemple #1
0
        //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);
        }
Exemple #2
0
        //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);
        }
Exemple #3
0
        //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);
        }