Ejemplo n.º 1
0
        private float Maximise(Board board, int depth, ref BoardPieceMoveScore maxBestMove, float beta, Player currentPlayer)
        {
            // If the depth limit is reached, don't go any deeper and return the score of the board
            if (depth >= _searchDepth)
            {
                return(ScoreTheBoard(board, currentPlayer));
            }

            HashSet <BoardPieceMove> validMoves = new HashSet <BoardPieceMove>();

            ValidMovesCalc.GetValidMovesForPlayer(board, board.PlayerTurn, validMoves);

            float alpha = -10000000; // Set alpha to low num
            BoardPieceMoveScore bestChildMove = null;

            // Iterate through every available move
            foreach (var move in validMoves)
            {
                // Create a copy of the board and then perform the current move
                Board newBoard = BoardHelpers.DuplicateBoard(board);
                newBoard.BoardPieces[move.From.X, move.From.Y].HasMoved = true;
                newBoard.BoardPieces[move.To.X, move.To.Y]     = newBoard.BoardPieces[move.From.X, move.From.Y];
                newBoard.BoardPieces[move.From.X, move.From.Y] = new BoardPiece();
                newBoard.PlayerTurn = BoardHelpers.GetOpponentPlayer(newBoard.PlayerTurn);

                // Go down a layer and find the minimum score available for the enemy (PLAYER). Set it to alpha if it is greater than a previous alpha.
                alpha = Math.Max(alpha, Minimise(newBoard, depth + 1, alpha, currentPlayer));

                // If the new alpha is greater than the previous best score (or hasn't been set yet)
                if (bestChildMove == null || alpha > bestChildMove.Score)
                {
                    bestChildMove = new BoardPieceMoveScore(move, alpha);
                }

                // If a move is found to be worse than the best score currently stored, return out of the tree early.
                if (alpha > beta)
                {
                    return(alpha);
                }
            }

            // If we're on the top layer, return the best move available
            if (depth == 0)
            {
                maxBestMove = bestChildMove;
            }

            return(alpha);
        }
Ejemplo n.º 2
0
        private float Minimise(Board board, int depth, float alpha, Player currentPlayer)
        {
            if (depth >= _searchDepth)
            {
                return(ScoreTheBoard(board, currentPlayer));
            }

            HashSet <BoardPieceMove> validMoves = new HashSet <BoardPieceMove>();

            ValidMovesCalc.GetValidMovesForPlayer(board, board.PlayerTurn, validMoves);

            float beta = 10000000;
            BoardPieceMoveScore bestChildMove = null;

            // Iterate through every available move
            foreach (var move in validMoves)
            {
                // Create a copy of the board and then perform the current move
                Board newBoard = BoardHelpers.DuplicateBoard(board);
                newBoard.BoardPieces[move.From.X, move.From.Y].HasMoved = true;
                newBoard.BoardPieces[move.To.X, move.To.Y]     = newBoard.BoardPieces[move.From.X, move.From.Y];
                newBoard.BoardPieces[move.From.X, move.From.Y] = new BoardPiece();
                newBoard.PlayerTurn = BoardHelpers.GetOpponentPlayer(newBoard.PlayerTurn);
                var newMove = new BoardPieceMoveScore(move, beta);

                beta = Math.Min(beta, Maximise(newBoard, depth + 1, ref newMove, beta, currentPlayer));

                if (bestChildMove == null || beta < bestChildMove.Score)
                {
                    bestChildMove = new BoardPieceMoveScore(move, beta);
                }

                if (beta < alpha)
                {
                    return(beta);
                }
            }

            return(beta);
        }