コード例 #1
0
ファイル: ChessBoard.cs プロジェクト: banfstory/Chess-with-AI
 private void AIMove() // determine how the AI will move and swap back to players turn after AI makes its move
 {
     if (PvE && (currentState == gameState.Normal || currentState == gameState.Check) && ((turn && AIColor) || (!turn && !AIColor)))
     {
         int      currentBoardState = 0;
         AIResult aiResult          = new AIResult();
         AI       ai = new AI(0);
         for (int y = 0; y < board.Length; y++)
         {
             for (int x = 0; x < board[y].Length; x++)
             {
                 if (board[y][x] == null)
                 {
                     continue;
                 }
                 if (PieceDetails.IsPieceBlackorWhite(board[y][x].Name))
                 {
                     currentBoardState += ai.PieceValue(PieceDetails.selectedPiece(board[y][x].Name));
                 }
                 else
                 {
                     currentBoardState -= ai.PieceValue(PieceDetails.selectedPiece(board[y][x].Name));
                 }
             }
         }
         ai.MiniMax(board, turn, AIComplexity, currentBoardState, aiResult);
         selectedpiece = board[aiResult.SourceY][aiResult.SourceX];
         if (!IsValidMove(PieceDetails.selectedPiece(board[aiResult.SourceY][aiResult.SourceX].Name), aiResult.DestinationY, aiResult.DestinationX))
         {
             MessageBox.Show("AI ERROR");
             undo();
             return;
         }
         completeTurn();
     }
 }
コード例 #2
0
 private bool KingAI(PictureBox[][] board, int y, int x, bool turn, int movesCount, int movesLimit, int currentBoardState, AIResult finalResult)
 {
     // loop through all directions king can move by one square
     for (int i = -1; i <= 1; i++)
     {
         for (int j = -1; j <= 1; j++)
         {
             int Y = y + i;
             int X = x + j;
             if ((i == 0 && j == 0) || Y < 0 || Y > 7 || X < 0 || X > 7)
             {
                 continue;
             }
             PictureBox[][] newBoard = new PictureBox[8][];
             if (board[Y][X] == null) // if king moves to empty square
             {
                 setNewBoard(board, newBoard, y, x, Y, X);
                 if (IsValidMove(newBoard, turn))
                 {
                     continue;
                 }
                 AI  newAI          = new AI(movesCount + 1);
                 int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult);
                 if (movesCount == 0)
                 {
                     CapturedSquares capture = new CapturedSquares();
                     setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard));
                 }
                 else
                 {
                     setResult(turn, bestBoardState, y, x, Y, X, 0);
                 }
                 continue;
             }
             int  value      = PieceValue(PieceDetails.selectedPiece(board[Y][X].Name));
             bool pieceColor = PieceDetails.IsPieceBlackorWhite(board[Y][X].Name);
             if (turn && !pieceColor)    // white king eats black piece
             {
                 if (value == kingvalue) // if king is eatten prune this path completely
                 {
                     return(true);
                 }
                 if (bestPath <= currentBoardState + value) // prune path that are smaller than the current board state
                 {
                     setNewBoard(board, newBoard, y, x, Y, X);
                     if (IsValidMove(newBoard, turn))
                     {
                         continue;
                     }
                     bestPath = currentBoardState + value;
                     AI  newAI          = new AI(movesCount + 1);
                     int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState + value, finalResult);
                     if (movesCount == 0)
                     {
                         CapturedSquares capture = new CapturedSquares();
                         setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard));
                     }
                     else
                     {
                         setResult(turn, bestBoardState, y, x, Y, X, 0);
                     }
                 }
             }
             else if (!turn && pieceColor) // black king eats white piece
             {
                 if (value == kingvalue)
                 {
                     return(true);
                 }
                 if (bestPath >= currentBoardState - value) // prune path that are larger than the current board state
                 {
                     setNewBoard(board, newBoard, y, x, Y, X);
                     if (IsValidMove(newBoard, turn))
                     {
                         continue;
                     }
                     bestPath = currentBoardState - value;
                     AI  newAI          = new AI(movesCount + 1);
                     int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState - value, finalResult);
                     if (movesCount == 0)
                     {
                         CapturedSquares capture = new CapturedSquares();
                         setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard));
                     }
                     else
                     {
                         setResult(turn, bestBoardState, y, x, Y, X, 0);
                     }
                 }
             }
         }
     }
     return(false);
 }
コード例 #3
0
        private bool QueenAI(PictureBox[][] board, int y, int x, bool turn, int movesCount, int movesLimit, int currentBoardState, AIResult finalResult)
        {
            bool[] pieceDirection = new bool[8]; // this array represents north, east, south, west, northeast, southeast, southwest, northwest and will reduce the processing time

            for (int i = 1; i < 8; i++)          // represents the distance to be moved
            {
                // queen cannot move anymore as it is either out of bound or there is another piece blocking it from its target
                if (PieceDetails.checkedAllDirections(pieceDirection))
                {
                    break;
                }
                for (int j = 0; j < PieceDetails.QueenDirection.Length; j++) // represents the array to define the direction of the move
                {
                    if (pieceDirection[j])
                    {
                        continue;
                    }
                    int Y = y + i * PieceDetails.QueenDirection[j][0];
                    int X = x + i * PieceDetails.QueenDirection[j][1];
                    if (Y >= 0 && Y < 8 && X >= 0 && X < 8)
                    {
                        PictureBox[][] newBoard = new PictureBox[8][];
                        if (board[Y][X] == null)                      // if queen moves to an empty square
                        {
                            setNewBoard(board, newBoard, y, x, Y, X); // create new board object to be used as parameter to call minimax function
                            if (IsValidMove(newBoard, turn))
                            {
                                continue;
                            }
                            AI  newAI          = new AI(movesCount + 1);
                            int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult);
                            if (movesCount == 0)
                            {
                                CapturedSquares capture = new CapturedSquares();
                                setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard));
                            }
                            else
                            {
                                setResult(turn, bestBoardState, y, x, Y, X, 0);
                            }
                        }
                        else
                        {
                            bool pieceColor = PieceDetails.IsPieceBlackorWhite(board[Y][X].Name);
                            int  value      = PieceValue(PieceDetails.selectedPiece(board[Y][X].Name));
                            if (turn && !pieceColor)    // if white queen eats a black piece
                            {
                                if (value == kingvalue) // if king is eatten prune this path completely
                                {
                                    return(true);
                                }
                                if (bestPath <= currentBoardState + value) // prune path that are smaller than the current board state
                                {
                                    setNewBoard(board, newBoard, y, x, Y, X);
                                    if (IsValidMove(newBoard, turn))
                                    {
                                        pieceDirection[j] = true;
                                        continue;
                                    }
                                    bestPath = currentBoardState + value;
                                    AI  newAI          = new AI(movesCount + 1);
                                    int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState + value, finalResult);
                                    if (movesCount == 0)
                                    {
                                        CapturedSquares capture = new CapturedSquares();
                                        setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard));
                                    }
                                    else
                                    {
                                        setResult(turn, bestBoardState, y, x, Y, X, 0);
                                    }
                                }
                                pieceDirection[j] = true;
                            }
                            else if (!turn && pieceColor) // if black queen eats a white piece
                            {
                                if (value == kingvalue)
                                {
                                    return(true);
                                }
                                if (bestPath >= currentBoardState - value) // prune path that are larger than the current board state
                                {
                                    setNewBoard(board, newBoard, y, x, Y, X);
                                    if (IsValidMove(newBoard, turn))
                                    {
                                        pieceDirection[j] = true;
                                        continue;
                                    }
                                    bestPath = currentBoardState - value;
                                    AI  newAI          = new AI(movesCount + 1);
                                    int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState - value, finalResult);
                                    if (movesCount == 0)
                                    {
                                        CapturedSquares capture = new CapturedSquares();
                                        setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard));
                                    }
                                    else
                                    {
                                        setResult(turn, bestBoardState, y, x, Y, X, 0);
                                    }
                                }
                                pieceDirection[j] = true;
                            }
                            else
                            {
                                pieceDirection[j] = true; // if bishop lands on the its same color piece
                            }
                        }
                    }
                    else
                    {
                        pieceDirection[j] = true; // if bishop lands out of bounds
                    }
                }
            }
            return(false);
        }
コード例 #4
0
 private bool KnightAI(PictureBox[][] board, int y, int x, bool turn, int movesCount, int movesLimit, int currentBoardState, AIResult finalResult)
 {
     foreach (int[] dir in PieceDetails.KnightDirection)
     {
         int Y = y + dir[0];
         int X = x + dir[1];
         if (Y < 0 || Y > 7 || X < 0 || X > 7)
         {
             continue;
         }
         PictureBox[][] newBoard = new PictureBox[8][];
         if (board[Y][X] == null)                      // knight moving to empty square
         {
             setNewBoard(board, newBoard, y, x, Y, X); // create new board object to be used as parameter to call minimax function
             if (IsValidMove(newBoard, turn))
             {
                 continue;
             }
             AI  newAI          = new AI(movesCount + 1);
             int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult);
             if (movesCount == 0)
             {
                 CapturedSquares capture = new CapturedSquares();
                 setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard));
             }
             else
             {
                 setResult(turn, bestBoardState, y, x, Y, X, 0);
             }
             continue;
         }
         int  value      = PieceValue(PieceDetails.selectedPiece(board[Y][X].Name));
         bool pieceColor = PieceDetails.IsPieceBlackorWhite(board[Y][X].Name);
         if (turn && !pieceColor) // white knight eatting black piece
         {
             setNewBoard(board, newBoard, y, x, Y, X);
             if (value == kingvalue)  // if king is eatten prune this path completely
             {
                 return(true);
             }
             if (bestPath <= currentBoardState + value) // prune path that are smaller than the current board state
             {
                 if (IsValidMove(newBoard, turn))
                 {
                     continue;
                 }
                 bestPath = currentBoardState + value;
                 AI  newAI          = new AI(movesCount + 1);
                 int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState + value, finalResult);
                 if (movesCount == 0)
                 {
                     CapturedSquares capture = new CapturedSquares();
                     setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard));
                 }
                 else
                 {
                     setResult(turn, bestBoardState, y, x, Y, X, 0);
                 }
             }
         }
         else if (!turn && pieceColor) // black knight eatting white piece
         {
             setNewBoard(board, newBoard, y, x, Y, X);
             if (value == kingvalue)
             {
                 return(true);
             }
             if (bestPath >= currentBoardState - value) // prune path that are larger than the current board state
             {
                 if (IsValidMove(newBoard, turn))
                 {
                     continue;
                 }
                 bestPath = currentBoardState - value;
                 AI  newAI          = new AI(movesCount + 1);
                 int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState - value, finalResult);
                 if (movesCount == 0)
                 {
                     CapturedSquares capture = new CapturedSquares();
                     setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard));
                 }
                 else
                 {
                     setResult(turn, bestBoardState, y, x, Y, X, 0);
                 }
             }
         }
     }
     return(false);
 }
コード例 #5
0
        // if it is currently at white's turn, it will try to look for the maximum boardstate value but if it is at black's turn, it will look for the minimum boardstate
        public int MiniMax(PictureBox[][] board, bool turn, int movesLimit, int currentBoardState, AIResult finalResult)
        {
            if (movesCount == movesLimit) // this will be the base case which is an end point where this end value will be compared with other end values
            {
                return(currentBoardState);
            }
            BoardState  = turn ? int.MinValue : int.MaxValue; // boardstate looks at the materials represented in the current board (white looks for the maximum board state and black looks for the minimum board state)
            squareCount = turn ? int.MinValue : int.MaxValue; // squarecount looks at the number of spaces that can be moved represented in the current board (white looks for the maximum squarecount and black looks for the minimum squarecount - only compares when movecount is 0)
            bestPath    = currentBoardState;
            for (int y = 0; y < board.Length; y++)
            {
                for (int x = 0; x < board[y].Length; x++)
                {
                    if (board[y][x] == null)
                    {
                        continue;
                    }
                    ChessBoard.pieceName name = ChessBoard.pieceName.None;
                    // look for the piece that corresponds with its own selected piece (black must select a black piece and white must select a white piece)
                    if (turn && PieceDetails.IsPieceBlackorWhite(board[y][x].Name))
                    {
                        name = PieceDetails.selectedWhitePiece(board[y][x].Name);
                    }
                    else if (!turn && !PieceDetails.IsPieceBlackorWhite(board[y][x].Name))
                    {
                        name = PieceDetails.selectedBlackPiece(board[y][x].Name);
                    }
                    else
                    {
                        continue;
                    }
                    switch (name)
                    {
                    case ChessBoard.pieceName.Pawn:
                        if (PawnAI(board, y, x, turn, movesCount, movesLimit, currentBoardState, finalResult))     // if these return true than stop perform best path calculation and break out of this path
                        {
                            return(turn ? int.MaxValue : int.MinValue);
                        }
                        break;

                    case ChessBoard.pieceName.Rook:
                        if (RookAI(board, y, x, turn, movesCount, movesLimit, currentBoardState, finalResult))
                        {
                            return(turn ? int.MaxValue : int.MinValue);
                        }
                        break;

                    case ChessBoard.pieceName.Knight:
                        if (KnightAI(board, y, x, turn, movesCount, movesLimit, currentBoardState, finalResult))
                        {
                            return(turn ? int.MaxValue : int.MinValue);
                        }
                        break;

                    case ChessBoard.pieceName.Bishop:
                        if (BishopAI(board, y, x, turn, movesCount, movesLimit, currentBoardState, finalResult))
                        {
                            return(turn ? int.MaxValue : int.MinValue);
                        }
                        break;

                    case ChessBoard.pieceName.Queen:
                        if (QueenAI(board, y, x, turn, movesCount, movesLimit, currentBoardState, finalResult))
                        {
                            return(turn ? int.MaxValue : int.MinValue);
                        }
                        break;

                    case ChessBoard.pieceName.King:
                        if (KingAI(board, y, x, turn, movesCount, movesLimit, currentBoardState, finalResult))
                        {
                            return(turn ? int.MaxValue : int.MinValue);
                        }
                        break;
                    }
                }
            }
            if (movesCount == 0) // this will store the beginning point of the best path which will allow AI to make that specific move
            {
                finalResult.SourceY      = SourceY;
                finalResult.SourceX      = SourceX;
                finalResult.DestinationY = DestinationY;
                finalResult.DestinationX = DestinationX;
            }
            return(BoardState);
        }
コード例 #6
0
 private bool PawnAI(PictureBox[][] board, int y, int x, bool turn, int movesCount, int movesLimit, int currentBoardState, AIResult finalResult)
 {
     if (turn) // white pawn move
     {
         if (y - 1 >= 0)
         {
             if (board[y - 1][x] == null) // white pawn moving 1 square north to empty square
             {
                 PictureBox[][] newBoard = new PictureBox[8][];
                 setNewBoard(board, newBoard, y, x, y - 1, x); // create new board object to be used as parameter to call minimax function
                 if (!IsValidMove(newBoard, turn))
                 {
                     AI  newAI          = new AI(movesCount + 1);
                     int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult); // find best path
                     if (movesCount == 0)
                     {
                         CapturedSquares capture = new CapturedSquares();
                         setResult(turn, bestBoardState, y, x, y - 1, x, capture.CaptureCount(newBoard));
                     }
                     else
                     {
                         setResult(turn, bestBoardState, y, x, y - 1, x, 0);
                     }
                 }
             }
             if (x - 1 >= 0 && board[y - 1][x - 1] != null && !PieceDetails.IsPieceBlackorWhite(board[y - 1][x - 1].Name)) // white pawn eat black piece at north-west
             {
                 int value = PieceValue(PieceDetails.selectedBlackPiece(board[y - 1][x - 1].Name));
                 if (value == kingvalue) // if king is eatten prune this path completely
                 {
                     return(true);
                 }
                 if (bestPath <= currentBoardState + value) // prune path that are smaller than the current board state
                 {
                     PictureBox[][] newBoard = new PictureBox[8][];
                     setNewBoard(board, newBoard, y, x, y - 1, x - 1);
                     if (!IsValidMove(newBoard, turn))
                     {
                         bestPath = currentBoardState + value;
                         AI  newAI          = new AI(movesCount + 1);
                         int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState + value, finalResult);
                         if (movesCount == 0)
                         {
                             CapturedSquares capture = new CapturedSquares();
                             setResult(turn, bestBoardState, y, x, y - 1, x - 1, capture.CaptureCount(newBoard));
                         }
                         else
                         {
                             setResult(turn, bestBoardState, y, x, y - 1, x - 1, 0);
                         }
                     }
                 }
             }
             if (x + 1 < 8 && board[y - 1][x + 1] != null && !PieceDetails.IsPieceBlackorWhite(board[y - 1][x + 1].Name)) // white pawn eat black piece at north-east
             {
                 int value = PieceValue(PieceDetails.selectedBlackPiece(board[y - 1][x + 1].Name));
                 if (value == kingvalue)
                 {
                     return(true);
                 }
                 if (bestPath <= currentBoardState + value)
                 {
                     PictureBox[][] newBoard = new PictureBox[8][];
                     setNewBoard(board, newBoard, y, x, y - 1, x + 1);
                     if (!IsValidMove(newBoard, turn))
                     {
                         bestPath = currentBoardState + value;
                         AI  newAI          = new AI(movesCount + 1);
                         int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState + value, finalResult);
                         if (movesCount == 0)
                         {
                             CapturedSquares capture = new CapturedSquares();
                             setResult(turn, bestBoardState, y, x, y - 1, x + 1, capture.CaptureCount(newBoard));
                         }
                         else
                         {
                             setResult(turn, bestBoardState, y, x, y - 1, x + 1, 0);
                         }
                     }
                 }
             }
         }
         if (y - 2 >= 0 && y == 6 && board[y - 1][x] == null && board[y - 2][x] == null) // white pawn moves 2 squares north to empty square
         {
             PictureBox[][] newBoard = new PictureBox[8][];
             setNewBoard(board, newBoard, y, x, y - 2, x);
             if (!IsValidMove(newBoard, turn))
             {
                 AI  newAI          = new AI(movesCount + 1);
                 int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult);
                 if (movesCount == 0)
                 {
                     CapturedSquares capture = new CapturedSquares();
                     setResult(turn, bestBoardState, y, x, y - 2, x, capture.CaptureCount(newBoard));
                 }
                 else
                 {
                     setResult(turn, bestBoardState, y, x, y - 2, x, 0);
                 }
             }
         }
     }
     else // black pawn move
     {
         if (y + 1 < 8)
         {
             if (board[y + 1][x] == null) // black pawn moving 1 square south to empty square
             {
                 PictureBox[][] newBoard = new PictureBox[8][];
                 setNewBoard(board, newBoard, y, x, y + 1, x); // create new board object to be used as parameter to call minimax function
                 if (!IsValidMove(newBoard, turn))
                 {
                     AI  newAI          = new AI(movesCount + 1);
                     int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult);
                     if (movesCount == 0)
                     {
                         CapturedSquares capture = new CapturedSquares();
                         setResult(turn, bestBoardState, y, x, y + 1, x, capture.CaptureCount(newBoard));
                     }
                     else
                     {
                         setResult(turn, bestBoardState, y, x, y + 1, x, 0);
                     }
                 }
             }
             if (x - 1 >= 0 && board[y + 1][x - 1] != null && PieceDetails.IsPieceBlackorWhite(board[y + 1][x - 1].Name)) // black pawn eat white piece at south-west
             {
                 int value = PieceValue(PieceDetails.selectedWhitePiece(board[y + 1][x - 1].Name));
                 if (value == kingvalue) // if king is eatten prune this path completely
                 {
                     return(true);
                 }
                 if (bestPath >= currentBoardState - value) // prune path that are larger than the current board state
                 {
                     PictureBox[][] newBoard = new PictureBox[8][];
                     setNewBoard(board, newBoard, y, x, y + 1, x - 1);
                     if (!IsValidMove(newBoard, turn))
                     {
                         bestPath = currentBoardState - value;
                         AI  newAI          = new AI(movesCount + 1);
                         int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState - value, finalResult);
                         if (movesCount == 0)
                         {
                             CapturedSquares capture = new CapturedSquares();
                             setResult(turn, bestBoardState, y, x, y + 1, x - 1, capture.CaptureCount(newBoard));
                         }
                         else
                         {
                             setResult(turn, bestBoardState, y, x, y + 1, x - 1, 0);
                         }
                     }
                 }
             }
             if (x + 1 < 8 && board[y + 1][x + 1] != null && PieceDetails.IsPieceBlackorWhite(board[y + 1][x + 1].Name)) // black pawn eat white piece at south-east
             {
                 int value = PieceValue(PieceDetails.selectedWhitePiece(board[y + 1][x + 1].Name));
                 if (value == kingvalue)
                 {
                     return(true);
                 }
                 if (bestPath >= currentBoardState - value)
                 {
                     PictureBox[][] newBoard = new PictureBox[8][];
                     setNewBoard(board, newBoard, y, x, y + 1, x + 1);
                     if (!IsValidMove(newBoard, turn))
                     {
                         bestPath = currentBoardState - value;
                         AI  newAI          = new AI(movesCount + 1);
                         int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState - value, finalResult);
                         if (movesCount == 0)
                         {
                             CapturedSquares capture = new CapturedSquares();
                             setResult(turn, bestBoardState, y, x, y + 1, x + 1, capture.CaptureCount(newBoard));
                         }
                         else
                         {
                             setResult(turn, bestBoardState, y, x, y + 1, x + 1, 0);
                         }
                     }
                 }
             }
         }
         if (y + 2 < 8 && y == 1 && board[y + 1][x] == null && board[y + 2][x] == null) // white pawn moves 2 squares south to empty square
         {
             PictureBox[][] newBoard = new PictureBox[8][];
             setNewBoard(board, newBoard, y, x, y + 2, x);
             if (!IsValidMove(newBoard, turn))
             {
                 AI  newAI          = new AI(movesCount + 1);
                 int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult);
                 if (movesCount == 0)
                 {
                     CapturedSquares capture = new CapturedSquares();
                     setResult(turn, bestBoardState, y, x, y + 2, x, capture.CaptureCount(newBoard));
                 }
                 else
                 {
                     setResult(turn, bestBoardState, y, x, y + 2, x, 0);
                 }
             }
         }
     }
     return(false);
 }