private static List <ChessBoard> getValidBoards(ChessBoard examineBoard) { List <ChessBoard> validBoards = new List <ChessBoard>(); for (byte x = 0; x < 64; ++x) { ChessPiece piece = examineBoard.pieces[x]; //Make sure there is a piece on the square //Make sure the color is the same color as the one we are moving. if (piece == null || piece.PieceColor != examineBoard.WhoseMove) { continue; } //For each valid move for this piece foreach (byte dst in piece.ValidMoves) { //We make copies of the board and move so that we can move it without effecting the parent board ChessBoard board = new ChessBoard(examineBoard); //Make move so we can examine it ChessEngine.MoveContent(board, x, dst, ChessPieceType.Queen); //We Generate Valid Moves for Board PieceValidMoves.GenerateValidMoves(board); //Invalid Move if (board.whiteInCheck && examineBoard.WhoseMove == ChessPieceColor.White) { continue; } //Invalid Move if (board.blackInCheck && examineBoard.WhoseMove == ChessPieceColor.Black) { continue; } //We calculate the board score Evaluation.EvaluateBoardScore(board); //Invert Score to support Negamax board.Score = SideToMoveScore(board.Score, board.WhoseMove); validBoards.Add(board); } } return(validBoards); }
internal static bool SearchForMate(ChessPieceColor movingSide, ChessBoard examineBoard, ref bool blackMate, ref bool whiteMate, ref bool staleMate) { bool foundNonCheckBlack = false; bool foundNonCheckWhite = false; for (byte x = 0; x < 64; ++x) { ChessPiece piece = examineBoard.pieces[x]; //Make sure there is a piece on the square //Make sure the color is the same color as the one we are moving. if (piece == null || piece.PieceColor != movingSide) { continue; } //For each valid move for this piece foreach (byte dst in piece.ValidMoves) { //We make copies of the board and move so we don't change the original ChessBoard board = new ChessBoard(examineBoard); //Make move so we can examine it ChessEngine.MoveContent(board, x, dst, ChessPieceType.Queen); //We Generate Valid Moves for Board PieceValidMoves.GenerateValidMoves(board); if (!board.blackInCheck) { foundNonCheckBlack = true; } else if (movingSide == ChessPieceColor.Black) { continue; } if (!board.whiteInCheck) { foundNonCheckWhite = true; } else if (movingSide == ChessPieceColor.White) { continue; } } } if (!foundNonCheckBlack) { if (examineBoard.blackInCheck) { blackMate = true; return(true); } if (!examineBoard.whiteInMate && movingSide != ChessPieceColor.White) { staleMate = true; return(true); } } if (!foundNonCheckWhite) { if (examineBoard.whiteInCheck) { whiteMate = true; return(true); } if (!examineBoard.blackInMate && movingSide != ChessPieceColor.Black) { staleMate = true; return(true); } } return(false); }
private static int AlphaBeta(ChessBoard examineBoard, byte depth, int alpha, int beta) { if (examineBoard == null || examineBoard.pieces == null) { return(0); } ++nodesSearched; if (examineBoard.FiftyMove >= 50 || examineBoard.RepeatedMove >= 3) { return(0); } if (depth == 0) { //Evaluate Score Evaluation.EvaluateBoardScore(examineBoard); //Invert Score to support Negamax return(SideToMoveScore(examineBoard.Score, examineBoard.WhoseMove)); } List <Position> positions = EvaluateMoves(examineBoard, depth); int length = positions.Count; if (examineBoard.whiteInCheck || examineBoard.blackInCheck || length == 0) { if (SearchForMate(examineBoard.WhoseMove, examineBoard, ref examineBoard.blackInMate, ref examineBoard.whiteInMate, ref examineBoard.staleMate)) { if (examineBoard.blackInMate) { if (examineBoard.WhoseMove == ChessPieceColor.Black) { return(-Constants.GameOverValue - depth); } else { return(Constants.GameOverValue + depth); } } if (examineBoard.whiteInMate) { if (examineBoard.WhoseMove == ChessPieceColor.Black) { return(Constants.GameOverValue + depth); } else { return(-Constants.GameOverValue - depth); } } //If Not Mate then StaleMate return(0); } } // Sort by score, this increases te chance we can prune moves early on positions.Sort(Sort); for (int i = 0; i < length; ++i) { Position move = positions[i]; //Make a copy ChessBoard board = new ChessBoard(examineBoard); //Move Piece ChessEngine.MoveContent(board, move.SrcPosition, move.DstPosition, ChessPieceType.Queen); //We Generate Valid Moves for Board PieceValidMoves.GenerateValidMoves(board); if (board.blackInCheck && examineBoard.WhoseMove == ChessPieceColor.Black) { //Invalid Move continue; } if (board.whiteInCheck && examineBoard.WhoseMove == ChessPieceColor.White) { //Invalid Move continue; } int value = -AlphaBeta(board, (byte)(depth - 1), -beta, -alpha); if (value >= beta) { // Beta cut-off return(beta); } if (value > alpha) { alpha = value; } } return(alpha); }