//
 // Agent constructor
 //
 public Agent()
 {
     behavior       = null;
     LookAheadDepth = 0;
     Move           = null;
     Color          = 0;
 }
Esempio n. 2
0
        // Recursive method that utilizes the Minimax algorithm to help the player make the best move
        private ComputerMove Minimax(int player, Board board, int depth, int maxDepth)
        {
            ComputerMove bestMove   = null;
            Board        boardState = new Board();

            for (int row = 0; row < 8; row++)
            {
                for (int col = 0; col < 8; col++)
                {
                    if (board.IsValidMove(player, row, col))
                    {
                        ComputerMove move = new ComputerMove(row, col);
                        boardState.Copy(board);
                        boardState.MakeMove(player, row, col);

                        if (boardState.IsTerminalState() || depth == maxDepth)
                        {
                            move.rank = Evaluate(boardState);
                        }
                        else
                        {
                            move.rank = Minimax(GetNextPlayer(player, boardState), boardState, depth + 1, maxDepth).rank;
                        }
                        if (bestMove == null || betterMove(player, move.rank, bestMove.rank))
                        {
                            bestMove = move;
                        }
                    }
                }
            }
            return(bestMove);
        }
Esempio n. 3
0
    public ComputerMove getMove()
    {
        Board board = GameObject.FindObjectOfType <Board>();

        bestMove = new ComputerMove(board.mAllCells[11, 11], board.mAllCells[11, 11], board.mAllCells[11, 11].mCurrentPiece);
        minMax(4, -100000000, 1000000000, true);
        return(bestMove);
    }
Esempio n. 4
0
        //
        // Calculates a computer move.
        // Note: Executed in the worker thread.
        //
        private void CalculateComputerMove()
        {
            // Load the AI parameters.
            this.SetAIParameters();

            // Find the best available move.
            ComputerMove move = this.GetBestMove(this.board);

            // Perform a callback to make the move.
            _resultMove = move;
        }
Esempio n. 5
0
        //
        // This function uses look ahead to evaluate all valid moves for a
        // given player color and returns the best move it can find. This
        // method will only be called if there is at least one valid move
        // for the player of the designated color.
        //
        private ComputerMove GetBestMove(int color, Board board, int depth)
        {
            //TODO: the lab
            ComputerMove m_bestMove = null;
            Board        newState   = new Board();

            List <ComputerMove> Moves = new List <ComputerMove>();

            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    if (board.IsValidMove(color, i, j))
                    {
                        Moves.Add(new ComputerMove(i, j));
                    }
                }
            }

            for (int i = 0; i < Moves.Count; i++)
            {
                newState.Copy(board);
                newState.MakeMove(color, Moves[i].row, Moves[i].col);

                if (newState.IsTerminalState() || depth == 0)
                {
                    Moves[i].rank = Evaluate(newState);
                }
                else
                {
                    Moves[i].rank = GetBestMove(GetNextPlayer(color, newState), newState, depth - 1).rank;
                }

                //white
                if (color == 1)
                {
                    if (m_bestMove == null || Moves[i].rank > m_bestMove.rank)
                    {
                        m_bestMove = Moves[i];
                    }
                }
                //black
                else
                {
                    if (m_bestMove == null || Moves[i].rank < m_bestMove.rank)
                    {
                        m_bestMove = Moves[i];
                    }
                }
            }
            return(m_bestMove);
        }
Esempio n. 6
0
        private ComputerMove MinMax(int color, Board board, int lookAheadDepth, int alpha, int beta)
        {
            ComputerMove        bestMove = null;
            Board               newState = new Board();
            List <ComputerMove> moves    = new List <ComputerMove>();

            for (int row = 0; row < Board.Height; row++)
            {
                for (int col = 0; col < Board.Width; col++)
                {
                    if (board.IsValidMove(color, row, col))
                    {
                        moves.Add(new ComputerMove(row, col));
                    }
                }
            }

            foreach (ComputerMove move in moves)
            {
                newState.Copy(board);
                newState.MakeMove(color, move.row, move.column);

                if (newState.IsTerminalState() || lookAheadDepth == 0)
                {
                    move.rank = Evaluate(newState);
                }
                else
                {
                    move.rank = MinMax((newState.HasAnyValidMove(color * -1) ? color * -1 : color), newState, lookAheadDepth - 1, alpha, beta).rank;
                }

                if (bestMove == null || move.rank * color > bestMove.rank * color)
                {
                    bestMove = move;
                    if (color == 1 && bestMove.rank > alpha)
                    {
                        alpha = bestMove.rank;
                    }
                    else if (color == -1 && bestMove.rank < beta)
                    {
                        beta = bestMove.rank;
                    }
                    if (alpha >= beta)
                    {
                        break;
                    }
                }
            }

            return(bestMove);
        }
        //
        // This function will determine a move based on the behavior supplied
        // to this agent. This function returns null on failure.
        //
        public ComputerMove DetermineMove(Board _board)
        {
            // Run the behavior to determine a move. On failure, returns null.
            Move = null;
            if (behavior != null)
            {
                Move = behavior.Run(Color, _board, LookAheadDepth);
            }

            if (Move != null && _board.IsValidMove(Color, Move.row, Move.column))
            {
                return(Move);
            }

            throw new System.NotImplementedException("Behavior returned null or invalid move due to incorrect implementation");
        }
Esempio n. 8
0
    void undoFakeMove(ComputerMove tempMove)
    {
        Cell      movedTo     = tempMove.secondPosition;
        Cell      movedFrom   = tempMove.firstPosition;
        BasePiece pieceKilled = tempMove.pieceKilled;
        BasePiece pieceMoved  = tempMove.pieceMoved;

        movedFrom.mCurrentPiece = movedTo.mCurrentPiece;

        if (pieceKilled != null)
        {
            movedTo.mCurrentPiece = pieceKilled;
        }
        else
        {
            movedTo.mCurrentPiece = null;
        }
    }
Esempio n. 9
0
        ////////////////////////////////////////

        /*
         *      Min-Max Algorithm
         */
        ////////////////////////////////////////
        private ComputerMove GetBestMove(int color, Board board, int depth)
        {
            ComputerMove        bestMove  = null;
            Board               newBoard  = new Board();
            List <ComputerMove> moveslist = new List <ComputerMove>();

            for (int i = 0; i < Board.Height; ++i)
            {
                for (int j = 0; j < Board.Width; ++j)
                {
                    if (board.IsValidMove(color, i, j))
                    {
                        moveslist.Add(new ComputerMove(i, j));
                    }
                }
            }
            for (int i = 0; i < moveslist.Count; ++i)
            {
                newBoard.Copy(board);
                newBoard.MakeMove(color, moveslist[i].row, moveslist[i].col);
                if (newBoard.IsTerminalState() || depth == 0)
                {
                    moveslist[i].rank = Evaluate(newBoard);
                }
                else if (!newBoard.HasAnyValidMove(-color))
                {
                    moveslist[i].rank = GetBestMove(color, newBoard, depth - 1).rank;
                }
                else
                {
                    moveslist[i].rank = GetBestMove(-color, newBoard, depth - 1).rank;
                }
                if (bestMove == null || (color == Board.Black && moveslist[i].rank > bestMove.rank) || (color == Board.White && moveslist[i].rank < bestMove.rank))
                {
                    bestMove = moveslist[i];
                }
            }
            return(bestMove);
        }
        public void ComputerChooseCell(bool i_IsFirstChoose)
        {
            int   randCell   = m_Rand.Next(0, m_UnDiscoveredCells.Count);
            int   choosenRow = m_UnDiscoveredCells[randCell] / m_BoardGame.NumOfCols;
            int   chooseCol  = m_UnDiscoveredCells[randCell] % m_BoardGame.NumOfCols;
            int   convertToUnDiscoveredCellIndex;
            Point choose = new Point(choosenRow, chooseCol);

            if (i_IsFirstChoose)
            {
                m_FirstChoose = choose;
                convertToUnDiscoveredCellIndex = (choosenRow * m_BoardGame.NumOfCols) + chooseCol;
                m_UnDiscoveredCells.Remove(convertToUnDiscoveredCellIndex);
            }
            else
            {
                m_SecondChoose = choose;
            }

            ComputerMove.Invoke(choose);

            //m_BoardGame.MakeCellUnAvailable(choosenRow, chooseCol);
        }
Esempio n. 11
0
    public void ComputerMove(ComputerMove move)
    {
        // Get random cell
        //int i = UnityEngine.Random.Range(0, mHighlightedCells.Count);
        mTargetCell = move.secondPosition;

        // Move to new cell
        Move();

        // End turn

        if (!turnExtra && !this.extraMovement)
        {
            mPieceManager.SwitchSides(mColor);
        }
        if (this.extraMovement)
        {
            extraMovement = false;
        }
        if (turnExtra)
        {
            turnExtra = false;
        }
    }
Esempio n. 12
0
        //
        // This function starts the look ahead process to find the best move
        // for this player color.
        //
        public ComputerMove Run(int _nextColor, Board _board, int _lookAheadDepth)
        {
            ComputerMove nextMove = GetBestMove(_nextColor, _board, _lookAheadDepth);

            return(nextMove);
        }
Esempio n. 13
0
        // TODO: Methods go here
        public ComputerMove Run(int color, Board board, int lookAheadDepth)
        {
            //throw new System.NotImplementedException();
            ComputerMove bestMove = null; //row, column, rank
            //int bestRank = -2147483648;
            int bestRank = 0;

            if (color == -1)
            {
                bestRank = int.MaxValue;
            }
            else
            {
                bestRank = int.MinValue;
            }
            int bestRow = 0;
            int bestCol = 0;
            List <ComputerMove> MoveList = new List <ComputerMove>();
            Board newState = new Board();

            newState.Copy(board);
            for (int row = 0; row < 8; row++)
            {
                for (int col = 0; col < 8; col++)
                {
                    if (newState.IsValidMove(color, row, col))
                    {
                        MoveList.Add(new ComputerMove(row, col));
                    }
                }
            }

            foreach (ComputerMove cm in MoveList)
            {
                newState.Copy(board);
                newState.MakeMove(color, cm.row, cm.column);
                if (newState.IsTerminalState() || lookAheadDepth == 0)
                {
                    cm.rank = Evaluate(newState);
                }
                else
                {
                    if (newState.HasAnyValidMove(color * -1))
                    {
                        cm.rank = Run(color * -1, newState, (lookAheadDepth - 1)).rank;
                    }
                    else
                    {
                        cm.rank = Run(color, newState, (lookAheadDepth - 1)).rank;
                    }
                }
                if (color == -1)
                {
                    if (bestRank > cm.rank)
                    {
                        bestRank = cm.rank;
                        bestRow  = cm.row;
                        bestCol  = cm.column;
                    }
                }
                else
                {
                    if (bestRank < cm.rank)
                    {
                        bestRank = cm.rank;
                        bestRow  = cm.row;
                        bestCol  = cm.column;
                    }
                }
            }
            bestMove      = new ComputerMove(bestRow, bestCol);
            bestMove.rank = bestRank;
            return(bestMove);
        }
Esempio n. 14
0
        //
        // This function uses look ahead to evaluate all valid moves for a
        // given player color and returns the best move it can find.
        //
        private ComputerMove GetBestMove(Board board, int color, int depth, int alpha, int beta)
        {
            // Initialize the best move.
            ComputerMove bestMove = new ComputerMove(-1, -1);
            bestMove.rank = -color * ReversiForm.maxRank;

            // Find out how many valid moves we have so we can initialize the
            // mobility score.
            int validMoves = board.GetValidMoveCount(color);

            // Start at a random position on the board. This way, if two or
            // more moves are equally good, we'll take one of them at random.
            Random random = new Random();
            int rowStart = random.Next(8);
            int colStart = random.Next(8);

            // Check all valid moves.
            int i, j;
            for (i = 0; i < 8; i++)
                for (j = 0; j < 8; j++)
                {
                    // Get the row and column.
                    int row = (rowStart + i) % 8;
                    int col = (colStart + j) % 8;

                    if (board.IsValidMove(color, row, col))
                    {
                        // Update the progress bar for each move when on the
                        // first look ahead depth level.
                        if (depth == 1)
                            this.BeginInvoke(new UpdateStatusProgressDelegate(this.UpdateStatusProgress));

                        // Make the move.
                        ComputerMove testMove = new ComputerMove(row, col);
                        Board testBoard = new Board(board);
                        testBoard.MakeMove(color, testMove.row, testMove.col);
                        int score = testBoard.WhiteCount - testBoard.BlackCount;

                        // Check the board.
                        int nextColor = -color;
                        int forfeit = 0;
                        bool isEndGame = false;
                        int opponentValidMoves = testBoard.GetValidMoveCount(nextColor);
                        if (opponentValidMoves == 0)
                        {
                            // The opponent cannot move, count the forfeit.
                            forfeit = color;

                            // Switch back to the original color.
                            nextColor = -nextColor;

                            // If that player cannot make a move either, the
                            // game is over.
                            if (!testBoard.HasAnyValidMove(nextColor))
                                isEndGame = true;
                        }

                        // If we reached the end of the look ahead (end game or
                        // max depth), evaluate the board and set the move
                        // rank.
                        if (isEndGame || depth == this.lookAheadDepth)
                        {
                            // For an end game, max the ranking and add on the
                            // final score.
                            if (isEndGame)
                            {
                                // Negative value for black win.
                                if (score < 0)
                                    testMove.rank = -ReversiForm.maxRank + score;

                                // Positive value for white win.
                                else if (score > 0)
                                    testMove.rank = ReversiForm.maxRank + score;

                                // Zero for a draw.
                                else
                                    testMove.rank = 0;
                            }

                            // It's not an end game so calculate the move rank.
                            else
                                testMove.rank =
                                    this.forfeitWeight   * forfeit +
                                    this.frontierWeight  * (testBoard.BlackFrontierCount - testBoard.WhiteFrontierCount) +
                                    this.mobilityWeight  * color * (validMoves - opponentValidMoves) +
                                    this.stabilityWeight * (testBoard.WhiteSafeCount - testBoard.BlackSafeCount) +
                                                           score;
                        }

                        // Otherwise, perform a look ahead.
                        else
                        {
                            ComputerMove nextMove = this.GetBestMove(testBoard, nextColor, depth + 1, alpha, beta);

                            // Pull up the rank.
                            testMove.rank = nextMove.rank;

                            // Forfeits are cumulative, so if the move did not
                            // result in an end game, add any current forfeit
                            // value to the rank.
                            if (forfeit != 0 && Math.Abs(testMove.rank) < ReversiForm.maxRank)
                                testMove.rank += forfeitWeight * forfeit;

                            // Adjust the alpha and beta values, if necessary.
                            if (color == Board.White && testMove.rank > beta)
                                beta = testMove.rank;
                            if (color == Board.Black && testMove.rank < alpha)
                                alpha = testMove.rank;
                        }

                        // Perform a cutoff if the rank is outside tha alpha-beta range.
                        if (color == Board.White && testMove.rank > alpha)
                        {
                            testMove.rank = alpha;
                            return testMove;
                        }
                        if (color == Board.Black && testMove.rank < beta)
                        {
                            testMove.rank = beta;
                            return testMove;
                        }

                        // If this is the first move tested, assume it is the
                        // best for now.
                        if (bestMove.row < 0)
                            bestMove = testMove;

                        // Otherwise, compare the test move to the current
                        // best move and take the one that is better for this
                        // color.
                        else if (color * testMove.rank > color * bestMove.rank)
                            bestMove = testMove;
                    }
                }

            // Return the best move found.
            return bestMove;
        }
Esempio n. 15
0
 public void moveComputerPiece(ComputerMove move)
 {
     move.pieceMoved.ComputerMove(move);
 }
Esempio n. 16
0
        //
        // This function uses look ahead to evaluate all valid moves for a
        // given player color and returns the best move it can find.
        //
        private ComputerMove minimax(Board board, int color, int alpha, int beta, int depth = 1)
        {
            // Initialize the best move.
            ComputerMove bestMove = new ComputerMove(-1, -1);
            bestMove.rank = -color * int.MaxValue;

            // Start at a random position on the board. This way, if two or
            // more moves are equally good, we'll take one of them at random.
            Random random = new Random();
            int rowStart = random.Next(10);
            int colStart = random.Next(10);

            // Check every square on the board and try to perform
            // each and every move (up to the given depth)
            // to calculate best move for the current player.
            // We are certain that there are valid moves at this point
            // as we wouldn't be here if there weren't any
            // checks are performed in the StartTurn function.
            for (int i = 0; i < 10; ++i)
                for (int j = 0; j < 10; ++j)
                {
                    // Get the row and column.
                    int row = (rowStart + i) % 10;
                    int col = (colStart + j) % 10;

                    if (board.IsValidMove(color, row, col))
                    {
                        // We found a valid move now we copy the board
                        // and try to make that move on the new board
                        // to evaluate its weight.
                        Board tempBoard = new Board(board);
                        tempBoard.MakeMove(color, row, col);

                        // Holds the current move being tested.
                        ComputerMove moveBeingChecked = new ComputerMove(row, col);

                        // Holds the color ID of a player that has no mobility
                        // Initialized to 0 in case both are mobile.
                        int forfeit = 0;

                        // Holds the color ID of the next player.
                        int nextPlayer = -color;

                        // A flag that indicates whether either of
                        // the players is mobile or if game is over.
                        bool gameOver = false;

                        // Just like in StartTurn, after passing a turn
                        // to the next player due to no mobility for the other
                        // we need to check if the new player is mobile
                        // if not then neither can move and game is over.
                        int opponentMobility = tempBoard.GetValidMoveCount(nextPlayer);
                        if (opponentMobility == 0)
                        {
                            forfeit = nextPlayer;
                            nextPlayer = color;

                            if (!tempBoard.HasAnyValidMove(color))
                                gameOver = true;
                        }

                        if (depth >= lookAheadDepth || gameOver)
                        {
                            // Initialize AI Parameters.
                            if (this.currentColor == Board.White)
                            {
                                moveBeingChecked.rank = heuristicFunction1(tempBoard, forfeit, color, opponentMobility);
                                if (tempBoard.EmptyCount > 0 && Board.isCorner(row, col))
                                    moveBeingChecked.rank += 200;
                            }
                            else moveBeingChecked.rank = heuristicFunction2(tempBoard);
                        }
                        else
                        {
                            ComputerMove nextMove = minimax(tempBoard, nextPlayer, alpha, beta, ++depth);
                            moveBeingChecked.rank = nextMove.rank;

                            // Adjust the alpha and beta values, if necessary.
                            if (color == Board.White && moveBeingChecked.rank > beta)
                                beta = moveBeingChecked.rank;
                            if (color == Board.Black && moveBeingChecked.rank < alpha)
                                alpha = moveBeingChecked.rank;
                        }

                        // If the alpha-beta pruning is enabled
                        // perform a cut off if necessary.
                        if (alphaBeta)
                        {
                            if (color == Board.White && moveBeingChecked.rank > alpha)
                            {
                                moveBeingChecked.rank = alpha;
                                return moveBeingChecked;
                            }
                            if (color == Board.Black && moveBeingChecked.rank < beta)
                            {
                                moveBeingChecked.rank = beta;
                                return moveBeingChecked;
                            }
                        }

                        // If this is the first move tested, assume it is the
                        // best for now. otherwise, compare the test move
                        // to the current best move and take the one that
                        // is better for this color.
                        if (bestMove.row < 0)
                            bestMove = moveBeingChecked;
                        else if (color * moveBeingChecked.rank < color * bestMove.rank)
                            bestMove = moveBeingChecked;
                    }
                }

            // Return the best move found.
            return bestMove;
        }
Esempio n. 17
0
    int minMax(int depth, int option1, int option2, bool max)
    {
        if (depth == 0)
        {
            return(evaluation());
        }
        if (max)
        {
            int score = -10000000;
            List <ComputerMove> allMoves = getComputerMoves(new Color32(25, 25, 25, 255));
            foreach (ComputerMove move in allMoves)
            {
                moveStack.Push(move);

                fakeMove(move.firstPosition, move.secondPosition);

                score = minMax(depth - 1, option1, option2, false);

                undoFakeMove(move);

                if (score > option1)
                {
                    move.score = score;
                    if (move.score > bestMove.score && depth == 4)
                    {
                        bestMove = move;
                    }
                    option1 = score;
                }
                if (score >= option2)
                {
                    break;
                }
            }
            return(option1);
        }
        else
        {
            int score = 10000000;
            List <ComputerMove> allMoves = getComputerMoves(new Color32(247, 242, 220, 255));
            foreach (ComputerMove move in allMoves)
            {
                moveStack.Push(move);

                fakeMove(move.firstPosition, move.secondPosition);

                score = minMax(depth - 1, option1, option2, true);

                undoFakeMove(move);

                if (score < option2)
                {
                    move.score = score;
                    option2    = score;
                }
                if (score <= option1)
                {
                    break;
                }
            }
            return(option2);
        }
    }
Esempio n. 18
0
        //
        // This function uses look ahead to evaluate all valid moves for a
        // given player color and returns the best move it can find.
        //
        private ComputerMove GetBestMove(Board board, int color, int depth, int alpha, int beta)
        {
            // Initialize the best move.
            ComputerMove bestMove = new ComputerMove(-1, -1);

            bestMove.rank = -color * maxRank;

            // Find out how many valid moves we have so we can initialize the
            // mobility score.
            int validMoves = board.GetValidMoveCount(color);

            // Start at a random position on the board. This way, if two or
            // more moves are equally good, we'll take one of them at random.
            Random random   = new Random();
            int    rowStart = random.Next(8);
            int    colStart = random.Next(8);

            // Check all valid moves.
            int i,
                j;

            for (i = 0; i < 8; i++)
            {
                for (j = 0; j < 8; j++)
                {
                    // Get the row and column.
                    int row = (rowStart + i) % 8;
                    int col = (colStart + j) % 8;

                    if (board.IsValidMove(color, row, col))
                    {
                        // Make the move.
                        ComputerMove testMove  = new ComputerMove(row, col);
                        Board        testBoard = new Board(board);
                        testBoard.MakeMove(color, testMove.row, testMove.col);
                        int score = testBoard.WhiteCount - testBoard.BlackCount;

                        // Check the board.
                        int  nextColor          = -color;
                        int  forfeit            = 0;
                        bool isEndGame          = false;
                        int  opponentValidMoves = testBoard.GetValidMoveCount(nextColor);
                        if (opponentValidMoves == 0)
                        {
                            // The opponent cannot move, count the forfeit.
                            forfeit = color;

                            // Switch back to the original color.
                            nextColor = -nextColor;

                            // If that player cannot make a move either, the
                            // game is over.
                            if (!testBoard.HasAnyValidMove(nextColor))
                            {
                                isEndGame = true;
                            }
                        }

                        // If we reached the end of the look ahead (end game or
                        // max depth), evaluate the board and set the move
                        // rank.
                        if (isEndGame || depth == this.lookAheadDepth)
                        {
                            // For an end game, max the ranking and add on the
                            // final score.
                            if (isEndGame)
                            {
                                // Negative value for black win.
                                if (score < 0)
                                {
                                    testMove.rank = -maxRank + score;
                                }

                                // Positive value for white win.
                                else if (score > 0)
                                {
                                    testMove.rank = maxRank + score;
                                }

                                // Zero for a draw.
                                else
                                {
                                    testMove.rank = 0;
                                }
                            }

                            // It's not an end game so calculate the move rank.
                            else
                            {
                                testMove.rank = this.forfeitWeight * forfeit + this.frontierWeight * (testBoard.BlackFrontierCount - testBoard.WhiteFrontierCount) + this.mobilityWeight * color * (validMoves - opponentValidMoves) + this.stabilityWeight * (testBoard.WhiteSafeCount - testBoard.BlackSafeCount) + score;
                            }
                        }

                        // Otherwise, perform a look ahead.
                        else
                        {
                            ComputerMove nextMove = this.GetBestMove(testBoard, nextColor, depth + 1, alpha, beta);

                            // Pull up the rank.
                            testMove.rank = nextMove.rank;

                            // Forfeits are cumulative, so if the move did not
                            // result in an end game, add any current forfeit
                            // value to the rank.
                            if (forfeit != 0 && Math.Abs(testMove.rank) < maxRank)
                            {
                                testMove.rank += forfeitWeight * forfeit;
                            }

                            // Adjust the alpha and beta values, if necessary.
                            if (color == Board.White && testMove.rank > beta)
                            {
                                beta = testMove.rank;
                            }
                            if (color == Board.Black && testMove.rank < alpha)
                            {
                                alpha = testMove.rank;
                            }
                        }

                        // Perform a cutoff if the rank is outside tha alpha-beta range.
                        if (color == Board.White && testMove.rank > alpha)
                        {
                            testMove.rank = alpha;
                            return(testMove);
                        }
                        if (color == Board.Black && testMove.rank < beta)
                        {
                            testMove.rank = beta;
                            return(testMove);
                        }

                        // If this is the first move tested, assume it is the
                        // best for now.
                        if (bestMove.row < 0)
                        {
                            bestMove = testMove;
                        }

                        // Otherwise, compare the test move to the current
                        // best move and take the one that is better for this
                        // color.
                        else if (color * testMove.rank > color * bestMove.rank)
                        {
                            bestMove = testMove;
                        }
                    }
                }
            }

            // Return the best move found.
            return(bestMove);
        }
Esempio n. 19
0
        //
        // This function uses look ahead to evaluate all valid moves for a
        // given player color and returns the best move it can find. This
        // method will only be called if there is at least one valid move
        // for the player of the designated color.
        //
        private ComputerMove GetBestMove(int color, Board board, int depth)
        {
            //TODO: the lab
            List <ComputerMove> Moves    = new List <ComputerMove>();
            ComputerMove        bestMove = null;
            Board newState = new Board();

            //  generate valid Moves for player;
            for (int r = 0; r < Board.Height; r++)
            {
                for (int c = 0; c < Board.Width; c++)
                {
                    if (board.IsValidMove(color, r, c) == true)
                    {
                        ComputerMove move = new ComputerMove(r, c);
                        Moves.Add(move);
                    }
                }
            }

            foreach (ComputerMove move in Moves)
            {
                newState.Copy(board);
                newState.MakeMove(color, move.row, move.col);

                if (newState.IsTerminalState() || depth == 0)
                {
                    move.rank = Evaluate(newState); /*ExampleAI.MinimaxAFI.EvaluateTest(newState);*/
                }
                else
                {
                    if (newState.HasAnyValidMove(color * -1))
                    {
                        move.rank = GetBestMove(color * -1, newState, depth - 1).rank;
                    }
                    else
                    {
                        move.rank = GetBestMove(color, newState, depth - 1).rank;
                    }
                }

                if (color == 1)
                {
                    if (bestMove == null || move.rank > bestMove.rank)
                    {
                        bestMove = move;
                    }
                }
                else
                {
                    if (bestMove == null || move.rank < bestMove.rank)
                    {
                        bestMove = move;
                    }
                }
            }

            return(bestMove);

            throw new NotImplementedException();
        }