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);
        }
Example #2
0
        // this will be subtracted or added to the current board state depending on who's turn it is (if it is black's turn it will subtract and if it is white's turn it will add)
        public int PieceValue(ChessBoard.pieceName piece)
        {
            switch (piece)
            {
            case ChessBoard.pieceName.Pawn:
                return(10);

            case ChessBoard.pieceName.Rook:
                return(50);

            case ChessBoard.pieceName.Knight:
                return(30);

            case ChessBoard.pieceName.Bishop:
                return(30);

            case ChessBoard.pieceName.Queen:
                return(90);

            default:
                return(kingvalue);
            }
        }
Example #3
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);
        }
 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 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;
             }
         }
     }
 }
        public void DisplayMoves(int Y, int X, PictureBox[][] board, List <PictureBox> PossiblePieceToTake, bool turn, ChessBoard.pieceName sourcePieceType)
        {
            switch (sourcePieceType)
            {
            case ChessBoard.pieceName.Pawn:
                PawnPossibleMoves(Y, X, board, PossiblePieceToTake, turn, sourcePieceType);
                return;

            case ChessBoard.pieceName.Rook:
                RookPossibleMoves(Y, X, board, PossiblePieceToTake, turn, sourcePieceType);
                return;

            case ChessBoard.pieceName.Knight:
                KnightPossibleMoves(Y, X, board, PossiblePieceToTake, turn, sourcePieceType);
                return;

            case ChessBoard.pieceName.Bishop:
                BishopPossibleMoves(Y, X, board, PossiblePieceToTake, turn, sourcePieceType);
                return;

            case ChessBoard.pieceName.Queen:
                QueenPossibleMoves(Y, X, board, PossiblePieceToTake, turn, sourcePieceType);
                return;

            default:
                KingPossibleMoves(Y, X, board, PossiblePieceToTake, turn, sourcePieceType);
                return;
            }
        }
 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);
         }
     }
 }
 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;
             }
         }
     }
 }
Example #9
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);
        }