Hello guys,

I (attempted to) incorporate the alpha-beta pruning functionality with Negamax in C# and was wondering if you could review my included code for any obvious errors?

Negamax Function:

public int NegaMax(int[,] board, int depth, int alpha, int beta)
        {
            Interlocked.Increment(ref _negaMaxCtr);
            if (depth == 0)
            {
                Interlocked.Increment(ref _zeroCtr);
                return EvaluateBoard(board);

            }

            int[,] legalMoves = GetLegalMoves(board);
            var possMoveList = new List<int[]>();

            int bestScore = -Int32.MaxValue;

            for (int r = 0; r < 8; r++)
                for (int c = 0; c < 8; c++)
                    if (legalMoves[r, c] == 1) possMoveList.Add(new [] { r, c });
            int n = possMoveList.Count;
            if (n == 0) return (EvaluateBoard(board));

            for (int z = 0; z < n; z++)
            {
                if (_parentForm.Bgw.CancellationPending) break;
                int[,] boardCopy = GetBoard(board);
                int[] theMove = possMoveList[z];
                MakeMove(theMove[0], theMove[1], boardCopy);
                int newScore = (-1) * NegaMax(board, depth - 1, Math.Max(alpha, bestScore), -beta);

                UnMakeMove(boardCopy);
                if (newScore >= bestScore)
                {
                    bestScore = newScore;
                }

                if (bestScore >= beta) return bestScore;
                if (newScore > alpha)
                    alpha = newScore;
            }
            return alpha;
        } 

Evaluate Board Method:

private int EvaluateBoard(int[,] board)
        {
            int boardValue = 0;
            const int edgePieceValue = 9;
            const int cornerPieceValue = 13;

            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    switch (board[i, j])
                    {
                        case 1:
                            boardValue++;
                            break;

                        case -1:
                            boardValue--;
                            break;
                    }
                }
            }

            //Corner piece evaluation
            if (board[0, 0] == -1)
                boardValue += cornerPieceValue;
            if (board[0, 0] == 1)
                boardValue -= cornerPieceValue;
            if (board[0, 7] == -1)
                boardValue += cornerPieceValue;
            if (board[0, 7] == 1)
                boardValue -= cornerPieceValue;
            if (board[7, 0] == -1)
                boardValue += cornerPieceValue;
            if (board[7, 0] == 1)
                boardValue -= cornerPieceValue;
            if (board[7, 7] == -1)
                boardValue += cornerPieceValue;
            if (board[7, 7] == 1)
                boardValue -= cornerPieceValue;

            //Edge piece evaluation
            for (int i = 0; i < 8; i++)
            {
                if (board[i, 0] == -1)
                    boardValue += edgePieceValue;
                if (board[i, 0] == 1)
                    boardValue -= edgePieceValue;
                if (board[i, 8 - 1] == -1)
                    boardValue += edgePieceValue;
                if (board[i, 8 - 1] == 1)
                    boardValue -= edgePieceValue;
            }

            for (int i = 0; i < 8; i++)
            {
                if (board[0, i] == -1)
                    boardValue += edgePieceValue;
                if (board[0, 0] == 1)
                    boardValue -= edgePieceValue;
                if (board[8 - 1, i] == -1)
                    boardValue += edgePieceValue;
                if (board[8 - 1, i] == 1)
                    boardValue -= edgePieceValue;
            }
            return boardValue;
        }

FindGoodMove Method:

public int[] FindGoodMove(int depth)
        {
            var x = new Stopwatch();
            x.Start();
            Debug.Print("Started");
            _zeroCtr = 0;
            _negaMaxCtr = 0;

            int[,] legalMoves = GetLegalMoves();
            var possMoveList = new List<int[]>();
            // Extract moves that are legal as a list of coordinates.
            for (int r = 0; r < 8; r++)
                for (int c = 0; c < 8; c++)
                    if (legalMoves[r, c] == 1) possMoveList.Add(new [] { r, c });
            int n = possMoveList.Count;
            if (n == 0) return new [] { -1, -1 }; // This shouldn't be possible!

            var moveValueList = new List<int>();

            for (int i = 0; i < n; i++)
            {
                if (_parentForm.Bgw.CancellationPending) break;
                // make copy of board position
                int[,] boardCopy = GetBoard();
                // make the move
                int[] theMove = possMoveList[i];
                MakeMove(theMove[0], theMove[1], boardCopy);
                moveValueList.Add(NegaMax(boardCopy, depth, -Int32.MaxValue, Int32.MaxValue));
                UnMakeMove(boardCopy);
            }
            // Find maximum value move

            x.Stop();
            Debug.Print("Ended: {0}ms. Zeroes: {1}. NegaMax Entered: {2}", x.ElapsedMilliseconds, _zeroCtr, _negaMaxCtr);

            var indexAtMax = moveValueList.IndexOf(moveValueList.Max());
            return possMoveList[indexAtMax];
        }

Please ignore the counters and debug outputs :)

Thanks for the assistance!

~ AWSLC