// determine if move been made by the AI is illegal or not private bool IsValidMove(PictureBox[][] board, bool turn) { if (movesCount == 0) { Check check = new Check(); int[] kingCoord = PieceDetails.FindKing(board, turn); if (check.IsChecked(board, kingCoord[0], kingCoord[1], !turn)) // determine if this is an illegal move by check { return(true); } } return(false); }
protected bool GameState(PictureBox[][] board) // determine the game state whether its check, checkmate, stalemate or normal { Check check = new Check(); board[sourceY][sourceX] = null; board[destinationY][destinationX] = source; int[] kingCoord = PieceDetails.FindKing(board, turn); if (check.IsChecked(board, kingCoord[0], kingCoord[1], !turn)) // determine if this is an illegal move by check { board[sourceY][sourceX] = source; board[destinationY][destinationX] = destination; return(false); } else { CurrentStatus status = new CurrentStatus(); ChessBoard.gameState state = status.TurnResult(board, turn); if (state == ChessBoard.gameState.Check) { setHistory(ChessBoard.gameState.Check); } else if (state == ChessBoard.gameState.Checkmate) { setHistory(ChessBoard.gameState.Checkmate); } else if (state == ChessBoard.gameState.Stalemate) { setHistory(ChessBoard.gameState.Stalemate); } else { setHistory(ChessBoard.gameState.Normal); } } return(true); }
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); }