public static int CalcScore(int playerNum, Cell[,] cells)
        {
            byte width = (byte)cells.GetLength(0), height = (byte)cells.GetLength(1);
            ColoredBoardNormalSmaller checker = new ColoredBoardNormalSmaller(width, height);
            int result = 0;
            var state  = playerNum == 0 ? TeamColor.Area1P : TeamColor.Area2P;

            for (uint x = 0; x < width; ++x)
            {
                for (uint y = 0; y < height; ++y)
                {
                    if (cells[x, y].AreaState == state)
                    {
                        result       += cells[x, y].Score;
                        checker[x, y] = true;
                    }
                }
            }
            ScoreEvaluation.BadSpaceFill(ref checker, width, height);

            for (uint x = 0; x < width; ++x)
            {
                for (uint y = 0; y < height; ++y)
                {
                    if (!checker[x, y])
                    {
                        result += Math.Abs(cells[x, y].Score);
                        cells[x, y].SurroundedState |= state;
                    }
                }
            }
            return(result);
        }
Exemplo n.º 2
0
 public Resume(byte turn, byte currentTurn, int boardHeight, int boardWidth, sbyte[,] board, ColoredBoardNormalSmaller meColoredBoard, ColoredBoardNormalSmaller enemyColoredBoard, byte agentsCount)
 {
     Turns             = turn;
     CurrentTurn       = currentTurn;
     BoardHeight       = boardHeight;
     BoardWidth        = boardWidth;
     Board             = board;
     MeColoredBoard    = meColoredBoard;
     EnemyColoredBoard = enemyColoredBoard;
     AgentsCount       = agentsCount;
 }
Exemplo n.º 3
0
        //Meが動くとする。「Meのスコア - Enemyのスコア」の最大値を返す。
        private int NegaMax(int deepness, SearchState state, int alpha, int beta, int count, PointEvaluator.Base evaluator, Decision ngMove, int greedyDepth, ColoredBoardNormalSmaller mySurroundBoard, ColoredBoardNormalSmaller enemySurroundBoard)
        {
            if (deepness == 0)
            {
                //for (int j = 0; j < greedyDepth; j++)
                //{
                //Unsafe16Array<VelocityPoint> move = state.MakeGreedyMove(ScoreBoard, WayEnumerator, AgentsCount);
                //state.Move(move, AgentsCount);
                //Ways moves = state.MakeMoves(AgentsCount, ScoreBoard);
                //SortMoves(ScoreBoard, state, moves, 49, null);
                //state.Move(moves[0].Agent1Way, moves[1].Agent2Way);
                //}
                int score = evaluator.Calculate(ScoreBoard, state.MeBoard, state.EnemyBoard, 0, state.Me, state.Enemy, mySurroundBoard, enemySurroundBoard) - evaluator.Calculate(ScoreBoard, state.EnemyBoard, state.MeBoard, 0, state.Enemy, state.Me, mySurroundBoard, enemySurroundBoard);
                if (greedyDepth % 2 == 1)
                {
                    return(-score);
                }
                return(score);
            }

            Ways      ways  = state.MakeMoves(AgentsCount, ScoreBoard);
            SmallWays sways = new SmallWays(AgentsCount);

            //ways => sways
            foreach (var way in ways.GetEnumerator(AgentsCount))
            {
                sways.Add(new SmallWay(way));
            }
            SortMoves(ScoreBoard, state, sways, count, ngMove);

            for (int i = 0; i < sways.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))    //2人とも競合手とは違う手を指す
                {
                    int j;
                    for (j = 0; j < AgentsCount; ++j)
                    {
                        if (sways[i].Equals(ngMove.Agents[j]))
                        {
                            break;
                        }
                    }
                    if (j != AgentsCount)
                    {
                        continue;
                    }
                }

                SearchState nextState = state;
                nextState = nextState.GetNextState(AgentsCount, sways[i].AgentsWay);
                nextState = nextState.ChangeTurn();
                //negaScoutにするための書き換え(手の入れ替えがあるので遅くなることは防げるかもしれない)
                int r = -NegaMax(deepness - 1, nextState, -(alpha + 1), -(alpha), count + 1, evaluator, ngMove, greedyDepth, mySurroundBoard, enemySurroundBoard);
                if (beta > r && r > alpha)
                {
                    int res = -NegaMax(deepness - 1, nextState, -beta, -alpha, count + 1, evaluator, ngMove, greedyDepth, mySurroundBoard, enemySurroundBoard);
                    if (alpha < res)
                    {
                        alpha = res;
                        if (ngMove is null)
                        {
                            dp1[count].UpdateScore(alpha, sways[i].AgentsWay);
                        }
                        else
                        {
                            dp2[count].UpdateScore(alpha, sways[i].AgentsWay);
                        }
                        if (alpha >= beta)
                        {
                            return(beta);               //βcut
                        }
                    }
                }
            }
            sways.Erase();
            //WaysPool.Return(ways);
            return(alpha);
        }