예제 #1
0
 public bool PawnMove(PictureBox[][] board, int y, int x, bool turn, int targetY, int targetX) // pawn move
 {
     if (turn)
     {
         // if white pawn can move one square forward (does not need to check if it can two squares forward as we just need to find if it can move without being checked)
         if (y - 1 >= 0)
         {
             if (board[y - 1][x] == null)                                                         // white pawn move forward one square and must be null
             {
                 if (IsMovable.IsAbleToMovePiece(board, y, x, y - 1, x, !turn, targetY, targetX)) // determine if white pawn can move without being checked
                 {
                     return(true);
                 }
             }
             if (x - 1 >= 0 && board[y - 1][x - 1] != null && !PieceDetails.IsPieceBlackorWhite(board[y - 1][x - 1].Name)) // white pawn eat another piece at north-west
             {
                 if (IsMovable.IsAbleToMovePiece(board, y, x, y - 1, x - 1, !turn, targetY, targetX))
                 {
                     return(true);
                 }
             }
             if (x + 1 < 8 && board[y - 1][x + 1] != null && !PieceDetails.IsPieceBlackorWhite(board[y - 1][x + 1].Name)) // white pawn eat another piece at north-east
             {
                 if (IsMovable.IsAbleToMovePiece(board, y, x, y - 1, x + 1, !turn, targetY, targetX))
                 {
                     return(true);
                 }
             }
         }
     }
     else if (!turn)
     {
         // if black pawn can move one square forward (does not need to check if it can two squares forward as we just need to find if it can move without being checked)
         if (y + 1 < 8)
         {
             if (board[y + 1][x] == null)                                                         // black pawn move forward one square and must be null
             {
                 if (IsMovable.IsAbleToMovePiece(board, y, x, y + 1, x, !turn, targetY, targetX)) // determine if white pawn can move without being checked
                 {
                     return(true);
                 }
             }
             else if (x - 1 >= 0 && board[y + 1][x - 1] != null && PieceDetails.IsPieceBlackorWhite(board[y + 1][x - 1].Name)) // black pawn eat another piece at south-west
             {
                 if (IsMovable.IsAbleToMovePiece(board, y, x, y + 1, x - 1, !turn, targetY, targetX))
                 {
                     return(true);
                 }
             }
             else if (x + 1 < 8 && board[y + 1][x + 1] != null && PieceDetails.IsPieceBlackorWhite(board[y + 1][x + 1].Name)) // black pawn eat another piece at south-west
             {
                 if (IsMovable.IsAbleToMovePiece(board, y, x, y + 1, x + 1, !turn, targetY, targetX))
                 {
                     return(true);
                 }
             }
         }
     }
     return(false);
 }
 private void PawnPossibleMoves(int Y, int X, PictureBox[][] board, List <PictureBox> PossiblePieceToTake, bool turn, ChessBoard.pieceName sourcePieceType)
 {
     if (turn)
     {
         if (Y - 1 >= 0)
         {
             if (board[Y - 1][X] == null)
             {
                 gObject.FillRectangle(brush, PieceDetails.ToCoordinate(X), PieceDetails.ToCoordinate(Y - 1), sizeOfBox, sizeOfBox);
             }
             if (X - 1 >= 0 && board[Y - 1][X - 1] != null && !PieceDetails.IsPieceBlackorWhite(board[Y - 1][X - 1].Name))
             {
                 PossiblePieceToTake.Add(board[Y - 1][X - 1]);
                 board[Y - 1][X - 1].BackColor = backcolor;
             }
             if (X + 1 < 8 && board[Y - 1][X + 1] != null && !PieceDetails.IsPieceBlackorWhite(board[Y - 1][X + 1].Name))
             {
                 PossiblePieceToTake.Add(board[Y - 1][X + 1]);
                 board[Y - 1][X + 1].BackColor = backcolor;
             }
         }
         if (Y == 6 && Y - 2 >= 0 && board[Y - 2][X] == null && board[Y - 1][X] == null)
         {
             gObject.FillRectangle(brush, PieceDetails.ToCoordinate(X), PieceDetails.ToCoordinate(Y - 2), sizeOfBox, sizeOfBox);
         }
     }
     else
     {
         if (Y + 1 < 8)
         {
             if (board[Y + 1][X] == null)
             {
                 gObject.FillRectangle(brush, PieceDetails.ToCoordinate(X), PieceDetails.ToCoordinate(Y + 1), sizeOfBox, sizeOfBox);
             }
             if (X - 1 >= 0 && board[Y + 1][X - 1] != null && PieceDetails.IsPieceBlackorWhite(board[Y + 1][X - 1].Name))
             {
                 PossiblePieceToTake.Add(board[Y + 1][X - 1]);
                 board[Y + 1][X - 1].BackColor = backcolor;
             }
             if (X + 1 < 8 && board[Y + 1][X + 1] != null && PieceDetails.IsPieceBlackorWhite(board[Y + 1][X + 1].Name))
             {
                 PossiblePieceToTake.Add(board[Y + 1][X + 1]);
                 board[Y + 1][X + 1].BackColor = backcolor;
             }
         }
         if (Y == 1 && Y + 2 < 8 && board[Y + 2][X] == null && board[Y + 1][X] == null)
         {
             gObject.FillRectangle(brush, PieceDetails.ToCoordinate(X), PieceDetails.ToCoordinate(Y + 2), sizeOfBox, sizeOfBox);
         }
     }
 }
예제 #3
0
 private void PawnSquaresTaken(int Y, int X, PictureBox[][] board, bool turn)
 {
     if (turn)
     {
         if (Y - 1 >= 0)
         {
             if (board[Y - 1][X] == null)
             {
                 capturedIncrDecr(turn);
             }
             if (X - 1 >= 0 && board[Y - 1][X - 1] != null && !PieceDetails.IsPieceBlackorWhite(board[Y - 1][X - 1].Name))
             {
                 capturedIncrDecr(turn);
             }
             if (X + 1 < 8 && board[Y - 1][X + 1] != null && !PieceDetails.IsPieceBlackorWhite(board[Y - 1][X + 1].Name))
             {
                 capturedIncrDecr(turn);
             }
         }
         if (Y == 6 && Y - 2 >= 0 && board[Y - 2][X] == null && board[Y - 1][X] == null)
         {
             capturedIncrDecr(turn);
         }
     }
     else
     {
         if (Y + 1 < 8)
         {
             if (board[Y + 1][X] == null)
             {
                 capturedIncrDecr(turn);
             }
             if (X - 1 >= 0 && board[Y + 1][X - 1] != null && PieceDetails.IsPieceBlackorWhite(board[Y + 1][X - 1].Name))
             {
                 capturedIncrDecr(turn);
             }
             if (X + 1 < 8 && board[Y + 1][X + 1] != null && PieceDetails.IsPieceBlackorWhite(board[Y + 1][X + 1].Name))
             {
                 capturedIncrDecr(turn);
             }
         }
         if (Y == 1 && Y + 2 < 8 && board[Y + 2][X] == null && board[Y + 1][X] == null)
         {
             capturedIncrDecr(turn);
         }
     }
 }
예제 #4
0
 private void KnightSquaresTaken(int Y, int X, PictureBox[][] board, bool turn)
 {
     foreach (int[] dir in PieceDetails.KnightDirection)
     {
         if ((dir[0] < 0 ? Y + dir[0] >= 0 : Y + dir[0] < 8) && (dir[1] < 0 ? X + dir[1] >= 0 : X + dir[1] < 8))
         {
             if (board[Y + dir[0]][X + dir[1]] == null)
             {
                 capturedIncrDecr(turn);
             }
             else if ((turn && !PieceDetails.IsPieceBlackorWhite(board[Y + dir[0]][X + dir[1]].Name)) || (!turn && PieceDetails.IsPieceBlackorWhite(board[Y + dir[0]][X + dir[1]].Name)))
             {
                 capturedIncrDecr(turn);
             }
         }
     }
 }
 private void KnightPossibleMoves(int Y, int X, PictureBox[][] board, List <PictureBox> PossiblePieceToTake, bool turn, ChessBoard.pieceName sourcePieceType)
 {
     foreach (int[] dir in PieceDetails.KnightDirection)
     {
         if ((dir[0] < 0 ? Y + dir[0] >= 0 : Y + dir[0] < 8) && (dir[1] < 0 ? X + dir[1] >= 0 : X + dir[1] < 8))
         {
             if (board[Y + dir[0]][X + dir[1]] == null)
             {
                 gObject.FillRectangle(brush, PieceDetails.ToCoordinate(X + dir[1]), PieceDetails.ToCoordinate(Y + dir[0]), sizeOfBox, sizeOfBox);
             }
             else if ((turn && !PieceDetails.IsPieceBlackorWhite(board[Y + dir[0]][X + dir[1]].Name)) || (!turn && PieceDetails.IsPieceBlackorWhite(board[Y + dir[0]][X + dir[1]].Name)))
             {
                 gObject.FillRectangle(brush, PieceDetails.ToCoordinate(X + dir[1]), PieceDetails.ToCoordinate(Y + dir[0]), sizeOfBox, sizeOfBox);
                 PossiblePieceToTake.Add(board[Y + dir[0]][X + dir[1]]);
                 board[Y + dir[0]][X + dir[1]].BackColor = backcolor;
             }
         }
     }
 }
예제 #6
0
        public int CaptureCount(PictureBox[][] board)
        {
            for (int i = 0; i < board.Length; i++)
            {
                for (int j = 0; j < board[i].Length; j++)
                {
                    if (board[i][j] == null)
                    {
                        continue;
                    }
                    bool turn = PieceDetails.IsPieceBlackorWhite(board[i][j].Name);
                    ChessBoard.pieceName selected = PieceDetails.selectedPiece(board[i][j].Name);
                    switch (selected)
                    {
                    case ChessBoard.pieceName.Pawn:
                        PawnSquaresTaken(i, j, board, turn);
                        break;

                    case ChessBoard.pieceName.Rook:
                        RookSquaresTaken(i, j, board, turn);
                        break;

                    case ChessBoard.pieceName.Knight:
                        KnightSquaresTaken(i, j, board, turn);
                        break;

                    case ChessBoard.pieceName.Bishop:
                        BishopSquaresTaken(i, j, board, turn);
                        break;

                    case ChessBoard.pieceName.Queen:
                        QueenSquaresTaken(i, j, board, turn);
                        break;

                    default:
                        KingSquaresTaken(i, j, board, turn);
                        break;
                    }
                }
            }
            return(capturedBoard);
        }
예제 #7
0
 public bool KnightMove(PictureBox[][] board, int y, int x, bool turn, int targetY, int targetX) // knight move
 {
     foreach (int[] dir in PieceDetails.KnightDirection)
     {
         int Y = y + dir[0];
         int X = x + dir[1];
         if (Y < 0 || X < 0 || Y > 7 || X > 7)
         {
             continue;                                   // knight cannot move out of bounds
         }
         if (board[Y][X] == null || (turn && !PieceDetails.IsPieceBlackorWhite(board[Y][X].Name)) || (!turn && PieceDetails.IsPieceBlackorWhite(board[Y][X].Name)))
         {
             if (IsMovable.IsAbleToMovePiece(board, y, x, Y, X, !turn, targetY, targetX)) // determine if knight can move without being checked
             {
                 return(true);
             }
         }
     }
     return(false);
 }
예제 #8
0
 private void KingSquaresTaken(int Y, int X, PictureBox[][] board, bool turn)
 {
     for (int i = -1; i <= 1; i++)
     {
         for (int j = -1; j <= 1; j++)
         {
             if ((i == 0 && j == 0) || Y + i >= 8 || Y + i < 0 || X + j >= 8 || X + j < 0)
             {
                 continue;
             }
             if (board[Y + i][X + j] == null)
             {
                 capturedIncrDecr(turn);
             }
             else if ((turn && !PieceDetails.IsPieceBlackorWhite(board[Y + i][X + j].Name)) || (!turn && PieceDetails.IsPieceBlackorWhite(board[Y + i][X + j].Name)))
             {
                 capturedIncrDecr(turn);
             }
         }
     }
 }
예제 #9
0
 public bool RookMove(PictureBox[][] board, int y, int x, bool turn, int targetY, int targetX) // rook move
 {
     for (int i = 0; i < PieceDetails.RookDirection.Length; i++)                               // looks at each directions rook can travel: north, east, south, west
     {
         // only one square for each direction needs to be checked as it only needs to determine rook can be moved
         int Y = y + 1 * PieceDetails.RookDirection[i][0];
         int X = x + 1 * PieceDetails.RookDirection[i][1];
         if (Y < 0 || Y > 7 || X < 0 || X > 7)
         {
             continue;
         }
         if (board[Y][X] == null || (turn && !PieceDetails.IsPieceBlackorWhite(board[Y][X].Name)) || (!turn && PieceDetails.IsPieceBlackorWhite(board[Y][X].Name)))
         {
             if (IsMovable.IsAbleToMovePiece(board, y, x, Y, X, !turn, targetY, targetX)) // determine if rook can move without being checked
             {
                 return(true);
             }
         }
     }
     return(false);
 }
 private void BishopPossibleMoves(int y, int x, PictureBox[][] board, List <PictureBox> PossiblePieceToTake, bool turn, ChessBoard.pieceName sourcePieceType)
 {
     bool[] pieceDirection = new bool[4]; // this array represents northeast, southeast, southwest, northwest and will reduce the processing time
     for (int i = 1; i < 8; i++)
     {
         // bishop 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.BishopDirection.Length; j++)
         {
             if (pieceDirection[j])
             {
                 continue;
             }
             int Y = y + i * PieceDetails.BishopDirection[j][0];
             int X = x + i * PieceDetails.BishopDirection[j][1];
             if (Y < 0 || Y > 7 || X < 0 || X > 7)
             {
                 pieceDirection[j] = true;
             }
             else if (board[Y][X] == null)
             {
                 gObject.FillRectangle(brush, PieceDetails.ToCoordinate(X), PieceDetails.ToCoordinate(Y), sizeOfBox, sizeOfBox);
             }
             else if ((turn && !PieceDetails.IsPieceBlackorWhite(board[Y][X].Name)) || (!turn && PieceDetails.IsPieceBlackorWhite(board[Y][X].Name)))
             {
                 PossiblePieceToTake.Add(board[Y][X]);
                 board[Y][X].BackColor = backcolor;
                 pieceDirection[j]     = true;
             }
             else
             {
                 pieceDirection[j] = true;
             }
         }
     }
 }
 private void KingPossibleMoves(int Y, int X, PictureBox[][] board, List <PictureBox> PossiblePieceToTake, bool turn, ChessBoard.pieceName sourcePieceType)
 {
     for (int i = -1; i <= 1; i++)
     {
         for (int j = -1; j <= 1; j++)
         {
             if ((i == 0 && j == 0) || Y + i >= 8 || Y + i < 0 || X + j >= 8 || X + j < 0)
             {
                 continue;
             }
             if (board[Y + i][X + j] == null)
             {
                 gObject.FillRectangle(brush, PieceDetails.ToCoordinate(X + j), PieceDetails.ToCoordinate(Y + i), sizeOfBox, sizeOfBox);
             }
             else if ((turn && !PieceDetails.IsPieceBlackorWhite(board[Y + i][X + j].Name)) || (!turn && PieceDetails.IsPieceBlackorWhite(board[Y + i][X + j].Name)))
             {
                 PossiblePieceToTake.Add(board[Y + i][X + j]);
                 board[Y + i][X + j].BackColor = backcolor;
             }
         }
     }
 }
예제 #12
0
 private void RookSquaresTaken(int y, int x, PictureBox[][] board, bool turn)
 {
     bool[] pieceDirection = new bool[4]; // this array represents north, east, south, west and will reduce the processing time
     for (int i = 1; i < 8; i++)
     {
         // rook 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.RookDirection.Length; j++)
         {
             if (pieceDirection[j])
             {
                 continue;
             }
             int Y = y + i * PieceDetails.RookDirection[j][0];
             int X = x + i * PieceDetails.RookDirection[j][1];
             if (Y < 0 || Y > 7 || X < 0 || X > 7)
             {
                 pieceDirection[j] = true;
             }
             else if (board[Y][X] == null)
             {
                 capturedIncrDecr(turn);
             }
             else if ((turn && !PieceDetails.IsPieceBlackorWhite(board[Y][X].Name)) || (!turn && PieceDetails.IsPieceBlackorWhite(board[Y][X].Name)))
             {
                 capturedIncrDecr(turn);
                 pieceDirection[j] = true;
             }
             else
             {
                 pieceDirection[j] = true;
             }
         }
     }
 }
예제 #13
0
 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();
     }
 }
예제 #14
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);
        }
예제 #15
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);
 }
예제 #16
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);
 }
예제 #17
0
        // store all the possible ways king can be checked in the current board
        public void CheckForMultipleChecks(PictureBox[][] board, int targetY, int targetX, bool turn, List <int[]> checks)
        {
            // loop through board to look if king has being checked
            for (int y = 0; y < board.Length; y++)
            {
                for (int x = 0; x < board[y].Length; x++)
                {
                    if (checks.Count > 1)
                    {
                        return;
                    }
                    if (board[y][x] == null)
                    {
                        continue;
                    }
                    ChessBoard.pieceName selected;
                    if (turn && PieceDetails.IsPieceBlackorWhite(board[y][x].Name))
                    {
                        selected = PieceDetails.selectedWhitePiece(board[y][x].Name);
                    }
                    else if (!turn && !PieceDetails.IsPieceBlackorWhite(board[y][x].Name))
                    {
                        selected = PieceDetails.selectedBlackPiece(board[y][x].Name);
                    }
                    else
                    {
                        continue;
                    }
                    switch (selected) // select a piece that will be moved that may result in a check where results are stored as coordinates in an array
                    {
                    case ChessBoard.pieceName.Pawn:
                        if (PawnCheck(y, x, turn, targetY, targetX))
                        {
                            checks.Add(new int[] { y, x });
                        }
                        break;

                    case ChessBoard.pieceName.Rook:
                        if (RookCheck(board, y, x, targetY, targetX))
                        {
                            checks.Add(new int[] { y, x });
                        }
                        break;

                    case ChessBoard.pieceName.Knight:
                        if (KnightCheck(y, x, targetY, targetX))
                        {
                            checks.Add(new int[] { y, x });
                        }
                        break;

                    case ChessBoard.pieceName.Bishop:
                        if (BishopCheck(board, y, x, targetY, targetX))
                        {
                            checks.Add(new int[] { y, x });
                        }
                        break;

                    case ChessBoard.pieceName.Queen:
                        if (QueenCheck(board, y, x, targetY, targetX))
                        {
                            checks.Add(new int[] { y, x });
                        }
                        break;

                    case ChessBoard.pieceName.King:
                        if (KingCheck(y, x, targetY, targetX))
                        {
                            checks.Add(new int[] { y, x });
                        }
                        break;
                    }
                }
            }
        }
예제 #18
0
        public ChessBoard.gameState TurnResult(PictureBox[][] board, bool turn)                // turn will be represented as the current player that is making the move
        {
            Dictionary <int, HashSet <int> > targets = new Dictionary <int, HashSet <int> >(); // different places king can move are stored in a hash table

            int[] kingCoord = PieceDetails.FindKing(board, !turn);                             // represent the opposite king to determine status of game through "!turn"

            for (int i = -1; i <= 1; i++)                                                      // look for all the different places the king can move
            {
                for (int j = -1; j <= 1; j++)
                {
                    int y = kingCoord[0] + i;
                    int x = kingCoord[1] + j;
                    if ((i == 0 && j == 0) || y >= 8 || y < 0 || x >= 8 || x < 0)
                    {
                        continue;
                    }
                    // check if selected king in the kingCoord can move to empty square or eat the opposite piece
                    if (board[y][x] == null || (turn && PieceDetails.IsPieceBlackorWhite(board[y][x].Name)) ||
                        (!turn && !PieceDetails.IsPieceBlackorWhite(board[y][x].Name)))
                    {
                        if (!targets.ContainsKey(y))
                        {
                            targets.Add(y, new HashSet <int>());
                        }
                        targets[y].Add(x);
                    }
                }
            }

            PictureBox originalPosition = board[kingCoord[0]][kingCoord[1]];

            board[kingCoord[0]][kingCoord[1]] = null;
            for (int y = 0; y < board.Length; y++) // determine if the king can move at any of these places without being checked by removing all invalid moves in target array
            {
                if (targets.Count == 0)            // break out if no targets are left
                {
                    break;
                }
                for (int x = 0; x < board[y].Length; x++)
                {
                    if (targets.Count == 0) // break out if no targets are left
                    {
                        break;
                    }
                    if (board[y][x] == null)
                    {
                        continue;
                    }
                    ChessBoard.pieceName selected = ChessBoard.pieceName.None;
                    // piece being selected must be based on the current turn piece
                    if (turn && PieceDetails.IsPieceBlackorWhite(board[y][x].Name))
                    {
                        selected = PieceDetails.selectedWhitePiece(board[y][x].Name);
                    }
                    else if (!turn && !PieceDetails.IsPieceBlackorWhite(board[y][x].Name))
                    {
                        selected = PieceDetails.selectedBlackPiece(board[y][x].Name);
                    }
                    else
                    {
                        continue;
                    }
                    switch (selected)
                    {
                    case ChessBoard.pieceName.Pawn:
                        PawnCheck(y, x, turn, targets);
                        break;

                    case ChessBoard.pieceName.Rook:
                        RookCheck(board, y, x, targets);
                        break;

                    case ChessBoard.pieceName.Knight:
                        KnightCheck(y, x, targets);
                        break;

                    case ChessBoard.pieceName.Bishop:
                        BishopCheck(board, y, x, targets);
                        break;

                    case ChessBoard.pieceName.Queen:
                        QueenCheck(board, y, x, targets);
                        break;

                    case ChessBoard.pieceName.King:
                        KingCheck(y, x, targets);
                        break;
                    }
                }
            }
            board[kingCoord[0]][kingCoord[1]] = originalPosition;
            List <int[]> checks    = new List <int[]>(); // determine how many pieces are checking king
            Check        IsChecked = new Check();

            IsChecked.CheckForMultipleChecks(board, kingCoord[0], kingCoord[1], turn, checks); // determine if king is checked

            /*
             *  Checkmate Conditions:
             *  1. King must be checked
             *  2. King cannot move to any other squares without being checked again or an ally piece blocking it
             *  3. The piece checking the king cannot be blocked or eatten by another piece
             *
             *  Stalemate Conditions:
             *  1. King must not be checked
             *  2. King cannot move to any other squares without being checked again or an ally piece blocking it
             *  3. No piece cannot be moved due to being checked if moved or blocked
             *
             *  Check Conditions:
             *  1. King must be checked
             *  2. a) King can move to any other squares without being checked again or an ally piece blocking it
             *     b) The piece checking the king can be blocked or eatten by another piece
             *
             *  Normal Conditions:
             *  1. King must not be checked
             *  2. a) King can move to other squares without being checked or blocked
             *     b) Other pieces can be moved without being blocked or king being checked
             */

            if (checks.Count > 1 && targets.Count == 0) // this is checkmate
            {
                return(ChessBoard.gameState.Checkmate);
            }
            else if (checks.Count == 0 && targets.Count == 0) // determine if stalemate
            {
                // determine if any other pieces can move aside from the king
                Movable canMove = new Movable();
                Check   IsCheck = new Check();

                // determine if opposite player can move any piece to determine if its stalemate (for example, if it is currently the white's turn look for all the black pieces)
                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 piece = ChessBoard.pieceName.None;
                        if (!turn && PieceDetails.IsPieceBlackorWhite(board[y][x].Name))
                        {
                            piece = PieceDetails.selectedWhitePiece(board[y][x].Name);
                        }
                        else if (turn && !PieceDetails.IsPieceBlackorWhite(board[y][x].Name))
                        {
                            piece = PieceDetails.selectedBlackPiece(board[y][x].Name);
                        }
                        else
                        {
                            continue;
                        }
                        switch (piece) // if opposite piece can be moved than it is not a stalemate without being checked
                        {
                        case ChessBoard.pieceName.Pawn:
                            if (canMove.PawnMove(board, y, x, !turn, kingCoord[0], kingCoord[1]))
                            {
                                return(ChessBoard.gameState.Normal);
                            }
                            break;

                        case ChessBoard.pieceName.Rook:
                            if (canMove.RookMove(board, y, x, !turn, kingCoord[0], kingCoord[1]))
                            {
                                return(ChessBoard.gameState.Normal);
                            }
                            break;

                        case ChessBoard.pieceName.Knight:
                            if (canMove.KnightMove(board, y, x, !turn, kingCoord[0], kingCoord[1]))
                            {
                                return(ChessBoard.gameState.Normal);
                            }
                            break;

                        case ChessBoard.pieceName.Bishop:
                            if (canMove.BishopMove(board, y, x, !turn, kingCoord[0], kingCoord[1]))
                            {
                                return(ChessBoard.gameState.Normal);
                            }
                            break;

                        case ChessBoard.pieceName.Queen:
                            if (canMove.QueenMove(board, y, x, !turn, kingCoord[0], kingCoord[1]))
                            {
                                return(ChessBoard.gameState.Normal);
                            }
                            break;

                        default:
                            break;
                        }
                    }
                }
                return(ChessBoard.gameState.Stalemate);
            }
            else if (checks.Count == 1 && targets.Count == 0) // determine if checkmate
            {
                // check.Count must be 1 and not larger than 1 as two piece cannot be blocked at the same time to protect the king
                int        Y        = checks[0][0];
                int        X        = checks[0][1];
                PieceReach maxReach = new PieceReach();
                Dictionary <int, HashSet <int> > reach    = new Dictionary <int, HashSet <int> >(); // the reach will determine how many different squares can be blocked to protect the king
                ChessBoard.pieceName             selected = ChessBoard.pieceName.None;
                if (turn && PieceDetails.IsPieceBlackorWhite(board[Y][X].Name))
                {
                    selected = PieceDetails.selectedWhitePiece(board[Y][X].Name);
                }
                else if (!turn && !PieceDetails.IsPieceBlackorWhite(board[Y][X].Name))
                {
                    selected = PieceDetails.selectedBlackPiece(board[Y][X].Name);
                }
                reach.Add(Y, new HashSet <int>());
                reach[Y].Add(X); // this represents that piece being eaten rather than blocked
                switch (selected)
                {
                case ChessBoard.pieceName.Rook:
                    maxReach.RookReach(Y, X, kingCoord[0], kingCoord[1], turn, reach);
                    break;

                case ChessBoard.pieceName.Bishop:
                    maxReach.BishopReach(Y, X, kingCoord[0], kingCoord[1], turn, reach);
                    break;

                case ChessBoard.pieceName.Queen:
                    maxReach.QueenReach(Y, X, kingCoord[0], kingCoord[1], turn, reach);
                    break;
                }
                BlockPiece block = new BlockPiece();
                if (!block.BlockMultipleTargets(board, !turn, reach)) // determine if piece checking king can be blocked or eaten
                {
                    return(ChessBoard.gameState.Checkmate);
                }
            }
            return(checks.Count > 0 ? ChessBoard.gameState.Check : ChessBoard.gameState.Normal);
        }
예제 #19
0
        public bool IsChecked(PictureBox[][] board, int targetY, int targetX, bool turn) // Determine if king is checked
        {
            for (int y = 0; y < board.Length; y++)                                       // loop board to determine if move is valid
            {
                for (int x = 0; x < board[y].Length; x++)
                {
                    // only select pieces based on black or white's turn
                    if (board[y][x] == null || (y == targetY && x == targetX))
                    {
                        continue;
                    }
                    ChessBoard.pieceName selected;
                    if (turn && PieceDetails.IsPieceBlackorWhite(board[y][x].Name))
                    {
                        selected = PieceDetails.selectedWhitePiece(board[y][x].Name);
                    }
                    else if (!turn && !PieceDetails.IsPieceBlackorWhite(board[y][x].Name))
                    {
                        selected = PieceDetails.selectedBlackPiece(board[y][x].Name);
                    }
                    else
                    {
                        continue;
                    }
                    switch (selected) // select a piece that will be moved that may result in a check
                    {
                    case ChessBoard.pieceName.Pawn:
                        if (PawnCheck(y, x, turn, targetY, targetX))
                        {
                            return(true);
                        }
                        break;

                    case ChessBoard.pieceName.Rook:
                        if (RookCheck(board, y, x, targetY, targetX))
                        {
                            return(true);
                        }
                        break;

                    case ChessBoard.pieceName.Knight:
                        if (KnightCheck(y, x, targetY, targetX))
                        {
                            return(true);
                        }
                        break;

                    case ChessBoard.pieceName.Bishop:
                        if (BishopCheck(board, y, x, targetY, targetX))
                        {
                            return(true);
                        }
                        break;

                    case ChessBoard.pieceName.Queen:
                        if (QueenCheck(board, y, x, targetY, targetX))
                        {
                            return(true);
                        }
                        break;

                    case ChessBoard.pieceName.King:
                        if (KingCheck(y, x, targetY, targetX))
                        {
                            return(true);
                        }
                        break;
                    }
                }
            }
            return(false);
        }
예제 #20
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);
 }
예제 #21
0
        public bool BlockMultipleTargets(PictureBox[][] board, bool turn, Dictionary <int, HashSet <int> > reach)
        {
            // loop through board to look for whether a piece can block the piece checking the king represented as reach (hashset)
            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 selected;
                    if (turn && PieceDetails.IsPieceBlackorWhite(board[y][x].Name))
                    {
                        selected = PieceDetails.selectedWhitePiece(board[y][x].Name);
                    }
                    else if (!turn && !PieceDetails.IsPieceBlackorWhite(board[y][x].Name))
                    {
                        selected = PieceDetails.selectedBlackPiece(board[y][x].Name);
                    }
                    else
                    {
                        continue;
                    }
                    // determine if selected piece can block the piece checking the king
                    switch (selected)
                    {
                    case ChessBoard.pieceName.Pawn:
                        if (PawnBlock(board, y, x, turn, reach))
                        {
                            return(true);
                        }
                        break;

                    case ChessBoard.pieceName.Rook:
                        if (RookBlock(board, y, x, reach))
                        {
                            return(true);
                        }
                        break;

                    case ChessBoard.pieceName.Knight:
                        if (KnightBlock(y, x, reach))
                        {
                            return(true);
                        }
                        break;

                    case ChessBoard.pieceName.Bishop:
                        if (BishopBlock(board, y, x, reach))
                        {
                            return(true);
                        }
                        break;

                    case ChessBoard.pieceName.Queen:
                        if (QueenBlock(board, y, x, reach))
                        {
                            return(true);
                        }
                        break;
                    }
                }
            }
            return(false);
        }
예제 #22
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);
        }