//Copy Constructor internal Board(Board board) { Squares = new Square[64]; for (byte x = 0; x < 64; x++) { if (board.Squares[x].Piece != null) { Squares[x] = new Square(board.Squares[x].Piece); } } EndGamePhase = board.EndGamePhase; FiftyMove = board.FiftyMove; RepeatedMove = board.RepeatedMove; WhiteCastled = board.WhiteCastled; BlackCastled = board.BlackCastled; BlackCheck = board.BlackCheck; WhiteCheck = board.WhiteCheck; StaleMate = board.StaleMate; WhiteMate = board.WhiteMate; BlackMate = board.BlackMate; WhoseMove = board.WhoseMove; EnPassantPosition = board.EnPassantPosition; EnPassantColor = board.EnPassantColor; ZobristHash = board.ZobristHash; Score = board.Score; LastMove = new MoveContent(board.LastMove); MoveCount = board.MoveCount; }
private Board(Square[] squares) { Squares = new Square[64]; for (byte x = 0; x < 64; x++) { if (squares[x].Piece != null) { Squares[x].Piece = new Piece(squares[x].Piece); } } }
public void AiPonderMove() { Thinking = true; NodesSearched = 0; var resultBoards = new ResultBoards(); resultBoards.Positions = new List <Board>(); if (CheckForMate(WhoseMove, ref ChessBoard)) { Thinking = false; return; } MoveContent bestMove = new MoveContent(); //If there is no playbook move search for the best move if (OpeningBook.TryGetMove(ChessBoard, ref bestMove) == false || ChessBoard.FiftyMove > 45 || ChessBoard.RepeatedMove >= 2) { if (CurrentGameBook.TryGetMove(ChessBoard, ref bestMove) == false || ChessBoard.FiftyMove > 45 || ChessBoard.RepeatedMove >= 2) { bestMove = ChessBoard.IterativeSearch(PlyDepthSearched, ref NodesSearched, ref NodesQuiescence, ref pvLine, ref PlyDepthReached, ref RootMovesSearched, CurrentGameBook.MoveList); } } //Make the move PreviousChessBoard = new Board(ChessBoard); RootMovesSearched = (byte)resultBoards.Positions.Count; ChessBoard.MovePiece(bestMove.MovingPiecePrimary.SrcPosition, bestMove.MovingPiecePrimary.DstPosition, ChessPieceType.Queen); ChessBoard.LastMove.GeneratePGNString(ChessBoard); FileIO.SaveCurrentGameMove(ChessBoard, PreviousChessBoard, CurrentGameBook, bestMove); for (byte x = 0; x < 64; x++) { Square sqr = ChessBoard.Squares[x]; if (sqr.Piece == null) { continue; } sqr.Piece.DefendedValue = 0; sqr.Piece.AttackedValue = 0; } ChessBoard.GenerateValidMoves(); ChessBoard.EvaluateBoardScore(); PieceTakenAdd(ChessBoard.LastMove); MoveHistory.Push(ChessBoard.LastMove); if (CheckForMate(WhoseMove, ref ChessBoard)) { Thinking = false; if (ChessBoard.WhiteMate || ChessBoard.BlackMate) { LastMove.PgnMove += "#"; } return; } if (ChessBoard.WhiteCheck || ChessBoard.BlackCheck) { LastMove.PgnMove += "+"; } Thinking = false; }
internal Board() { Squares = new Square[64]; for (byte i = 0; i < 64; i++) { Squares[i] = new Square(); } LastMove = new MoveContent(); }
internal string GeneratePGNString(Board board) { if (!String.IsNullOrEmpty(PgnMove)) { return(PgnMove); } bool doubleColumn = false; bool doubleRow = false; bool doubleDestination = false; var srcCol = (byte)(MovingPiecePrimary.SrcPosition % 8); var srcRow = (byte)(8 - (MovingPiecePrimary.SrcPosition / 8)); var dstCol = (byte)(MovingPiecePrimary.DstPosition % 8); var dstRow = (byte)(8 - (MovingPiecePrimary.DstPosition / 8)); PgnMove = ""; for (byte x = 0; x < 64; x++) { if (x == MovingPiecePrimary.DstPosition) { continue; } Square square = board.Squares[x]; if (square.Piece == null) { continue; } if (square.Piece.PieceType == MovingPiecePrimary.PieceType) { if (square.Piece.PieceColor == MovingPiecePrimary.PieceColor) { foreach (byte move in square.Piece.ValidMoves) { if (move == MovingPiecePrimary.DstPosition) { doubleDestination = true; byte col = (byte)(x % 8); byte row = (byte)(8 - (x / 8)); if (col == srcCol) { doubleColumn = true; } if (row == srcRow) { doubleRow = true; } break; } } } } } if (MovingPieceSecondary.PieceType == ChessPieceType.Rook) { if (MovingPieceSecondary.PieceColor == ChessPieceColor.Black) { if (MovingPieceSecondary.SrcPosition == 7) { PgnMove += "O-O"; } else if (MovingPieceSecondary.SrcPosition == 0) { PgnMove += "O-O-O"; } } else if (MovingPieceSecondary.PieceColor == ChessPieceColor.White) { if (MovingPieceSecondary.SrcPosition == 63) { PgnMove += "O-O"; } else if (MovingPieceSecondary.SrcPosition == 56) { PgnMove += "O-O-O"; } } } else { PgnMove += GetPgnMove(MovingPiecePrimary.PieceType); switch (MovingPiecePrimary.PieceType) { case ChessPieceType.Knight: { if (doubleDestination) { if (!doubleColumn) { PgnMove += GetColumnFromInt(srcCol); } else { if (doubleRow) { PgnMove += GetColumnFromInt(srcCol); } PgnMove += srcRow; } } break; } case ChessPieceType.Bishop: { if (doubleDestination) { if (!doubleColumn) { PgnMove += GetColumnFromInt(srcCol); } else { if (doubleRow) { PgnMove += GetColumnFromInt(srcCol); } PgnMove += srcRow; } } break; } case ChessPieceType.Rook: { if (doubleDestination) { if (!doubleColumn) { PgnMove += GetColumnFromInt(srcCol); } else { if (doubleRow) { PgnMove += GetColumnFromInt(srcCol); } PgnMove += srcRow; } } break; } case ChessPieceType.Queen: { if (doubleDestination) { if (!doubleColumn) { PgnMove += GetColumnFromInt(srcCol); } else { if (doubleRow) { PgnMove += GetColumnFromInt(srcCol); } PgnMove += srcRow; } } break; } case ChessPieceType.Pawn: { if (doubleDestination && srcCol != dstCol) { PgnMove += GetColumnFromInt(srcCol); } else if (TakenPiece.PieceType != ChessPieceType.None) { PgnMove += GetColumnFromInt(srcCol); } break; } } if (TakenPiece.PieceType != ChessPieceType.None) { PgnMove += "x"; } PgnMove += GetColumnFromInt(dstCol); PgnMove += dstRow; if (PawnPromotedTo == ChessPieceType.Queen) { PgnMove += "=Q"; } else if (PawnPromotedTo == ChessPieceType.Rook) { PgnMove += "=R"; } else if (PawnPromotedTo == ChessPieceType.Bishop) { PgnMove += "=B"; } else if (PawnPromotedTo == ChessPieceType.Knight) { PgnMove += "=N"; } } return(PgnMove); }
internal static MoveContent MovePiece(Board board, byte srcPosition, byte dstPosition, ChessPieceType promoteToPiece) { Piece piece = board.Squares[srcPosition].Piece; //Record my last move board.LastMove = new MoveContent(); if (piece.PieceColor == ChessPieceColor.Black) { board.MoveCount++; //Add One to FiftyMoveCount to check for tie. board.FiftyMove++; } //En Passant if (board.EnPassantPosition > 0) { board.LastMove.EnPassantOccured = SetEnpassantMove(board, srcPosition, dstPosition, piece.PieceColor); } if (!board.LastMove.EnPassantOccured) { Square sqr = board.Squares[dstPosition]; if (sqr.Piece != null) { board.LastMove.TakenPiece = new PieceTaken(sqr.Piece.PieceColor, sqr.Piece.PieceType, sqr.Piece.Moved, dstPosition); board.FiftyMove = 0; } else { board.LastMove.TakenPiece = new PieceTaken(ChessPieceColor.White, ChessPieceType.None, false, dstPosition); } } board.LastMove.MovingPiecePrimary = new PieceMoving(piece.PieceColor, piece.PieceType, piece.Moved, srcPosition, dstPosition); //Delete the piece in its source position board.Squares[srcPosition].Piece = null; //Add the piece to its new position piece.Moved = true; piece.Selected = false; board.Squares[dstPosition].Piece = piece; //Reset EnPassantPosition board.EnPassantPosition = 0; //Record En Passant if Pawn Moving if (piece.PieceType == ChessPieceType.Pawn) { board.FiftyMove = 0; RecordEnPassant(piece.PieceColor, piece.PieceType, board, srcPosition, dstPosition); } board.WhoseMove = board.WhoseMove == ChessPieceColor.White ? ChessPieceColor.Black : ChessPieceColor.White; KingCastle(board, piece, srcPosition, dstPosition); //Promote Pawns if (PromotePawns(board, piece, dstPosition, promoteToPiece)) { board.LastMove.PawnPromotedTo = promoteToPiece; } else { board.LastMove.PawnPromotedTo = ChessPieceType.None; } if (board.FiftyMove >= 50) { board.StaleMate = true; } return(board.LastMove); }
internal static bool SearchForMate(ChessPieceColor movingSide, Board examineBoard, ref bool blackMate, ref bool whiteMate, ref bool staleMate) { bool foundNonCheckBlack = false; bool foundNonCheckWhite = false; for (byte x = 0; x < 64; x++) { Square sqr = examineBoard.Squares[x]; //Make sure there is a piece on the square if (sqr.Piece == null) { continue; } //Make sure the color is the same color as the one we are moving. if (sqr.Piece.PieceColor != movingSide) { continue; } //For each valid move for this piece foreach (byte dst in sqr.Piece.ValidMoves) { //We make copies of the board and move so that we can move it without effecting the parent board Board board = examineBoard.FastCopy(); //Make move so we can examine it Board.MovePiece(board, x, dst, ChessPieceType.Queen); //We Generate Valid Moves for Board PieceValidMoves.GenerateValidMoves(board); if (board.BlackCheck == false) { foundNonCheckBlack = true; } else if (movingSide == ChessPieceColor.Black) { continue; } if (board.WhiteCheck == false) { foundNonCheckWhite = true; } else if (movingSide == ChessPieceColor.White) { continue; } } } if (foundNonCheckBlack == false) { if (examineBoard.BlackCheck) { blackMate = true; return(true); } if (!examineBoard.WhiteMate && movingSide != ChessPieceColor.White) { staleMate = true; return(true); } } if (foundNonCheckWhite == false) { if (examineBoard.WhiteCheck) { whiteMate = true; return(true); } if (!examineBoard.BlackMate && movingSide != ChessPieceColor.Black) { staleMate = true; return(true); } } return(false); }
private static ResultBoards GetSortValidMoves(Board examineBoard) { ResultBoards succ = new ResultBoards { Positions = new List <Board>(30) }; piecesRemaining = 0; for (byte x = 0; x < 64; x++) { Square sqr = examineBoard.Squares[x]; //Make sure there is a piece on the square if (sqr.Piece == null) { continue; } piecesRemaining++; //Make sure the color is the same color as the one we are moving. if (sqr.Piece.PieceColor != examineBoard.WhoseMove) { continue; } //For each valid move for this piece foreach (byte dst in sqr.Piece.ValidMoves) { //We make copies of the board and move so that we can move it without effecting the parent board Board board = examineBoard.FastCopy(); //Make move so we can examine it Board.MovePiece(board, x, dst, ChessPieceType.Queen); //We Generate Valid Moves for Board PieceValidMoves.GenerateValidMoves(board); //Invalid Move if (board.WhiteCheck && examineBoard.WhoseMove == ChessPieceColor.White) { continue; } //Invalid Move if (board.BlackCheck && 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); succ.Positions.Add(board); } } succ.Positions.Sort(Sort); return(succ); }
internal static void GenerateValidMoves(Board board) { // Reset Board board.BlackCheck = false; board.WhiteCheck = false; WhiteAttackBoard = new bool[64]; BlackAttackBoard = new bool[64]; //Generate Moves for (byte x = 0; x < 64; x++) { Square sqr = board.Squares[x]; if (sqr.Piece == null) { continue; } sqr.Piece.ValidMoves = new Stack <byte>(sqr.Piece.LastValidMoveCount); switch (sqr.Piece.PieceType) { case ChessPieceType.Pawn: { if (sqr.Piece.PieceColor == ChessPieceColor.White) { CheckValidMovesPawn(MoveArrays.WhitePawnMoves[x].Moves, sqr.Piece, x, board, MoveArrays.WhitePawnTotalMoves[x]); break; } if (sqr.Piece.PieceColor == ChessPieceColor.Black) { CheckValidMovesPawn(MoveArrays.BlackPawnMoves[x].Moves, sqr.Piece, x, board, MoveArrays.BlackPawnTotalMoves[x]); break; } break; } case ChessPieceType.Knight: { for (byte i = 0; i < MoveArrays.KnightTotalMoves[x]; i++) { AnalyzeMove(board, MoveArrays.KnightMoves[x].Moves[i], sqr.Piece); } break; } case ChessPieceType.Bishop: { for (byte i = 0; i < MoveArrays.BishopTotalMoves1[x]; i++) { if ( AnalyzeMove(board, MoveArrays.BishopMoves1[x].Moves[i], sqr.Piece) == false) { break; } } for (byte i = 0; i < MoveArrays.BishopTotalMoves2[x]; i++) { if ( AnalyzeMove(board, MoveArrays.BishopMoves2[x].Moves[i], sqr.Piece) == false) { break; } } for (byte i = 0; i < MoveArrays.BishopTotalMoves3[x]; i++) { if ( AnalyzeMove(board, MoveArrays.BishopMoves3[x].Moves[i], sqr.Piece) == false) { break; } } for (byte i = 0; i < MoveArrays.BishopTotalMoves4[x]; i++) { if ( AnalyzeMove(board, MoveArrays.BishopMoves4[x].Moves[i], sqr.Piece) == false) { break; } } break; } case ChessPieceType.Rook: { for (byte i = 0; i < MoveArrays.RookTotalMoves1[x]; i++) { if ( AnalyzeMove(board, MoveArrays.RookMoves1[x].Moves[i], sqr.Piece) == false) { break; } } for (byte i = 0; i < MoveArrays.RookTotalMoves2[x]; i++) { if ( AnalyzeMove(board, MoveArrays.RookMoves2[x].Moves[i], sqr.Piece) == false) { break; } } for (byte i = 0; i < MoveArrays.RookTotalMoves3[x]; i++) { if ( AnalyzeMove(board, MoveArrays.RookMoves3[x].Moves[i], sqr.Piece) == false) { break; } } for (byte i = 0; i < MoveArrays.RookTotalMoves4[x]; i++) { if ( AnalyzeMove(board, MoveArrays.RookMoves4[x].Moves[i], sqr.Piece) == false) { break; } } break; } case ChessPieceType.Queen: { for (byte i = 0; i < MoveArrays.QueenTotalMoves1[x]; i++) { if ( AnalyzeMove(board, MoveArrays.QueenMoves1[x].Moves[i], sqr.Piece) == false) { break; } } for (byte i = 0; i < MoveArrays.QueenTotalMoves2[x]; i++) { if ( AnalyzeMove(board, MoveArrays.QueenMoves2[x].Moves[i], sqr.Piece) == false) { break; } } for (byte i = 0; i < MoveArrays.QueenTotalMoves3[x]; i++) { if ( AnalyzeMove(board, MoveArrays.QueenMoves3[x].Moves[i], sqr.Piece) == false) { break; } } for (byte i = 0; i < MoveArrays.QueenTotalMoves4[x]; i++) { if ( AnalyzeMove(board, MoveArrays.QueenMoves4[x].Moves[i], sqr.Piece) == false) { break; } } for (byte i = 0; i < MoveArrays.QueenTotalMoves5[x]; i++) { if ( AnalyzeMove(board, MoveArrays.QueenMoves5[x].Moves[i], sqr.Piece) == false) { break; } } for (byte i = 0; i < MoveArrays.QueenTotalMoves6[x]; i++) { if ( AnalyzeMove(board, MoveArrays.QueenMoves6[x].Moves[i], sqr.Piece) == false) { break; } } for (byte i = 0; i < MoveArrays.QueenTotalMoves7[x]; i++) { if ( AnalyzeMove(board, MoveArrays.QueenMoves7[x].Moves[i], sqr.Piece) == false) { break; } } for (byte i = 0; i < MoveArrays.QueenTotalMoves8[x]; i++) { if ( AnalyzeMove(board, MoveArrays.QueenMoves8[x].Moves[i], sqr.Piece) == false) { break; } } break; } case ChessPieceType.King: { if (sqr.Piece.PieceColor == ChessPieceColor.White) { whiteKingPosition = x; } else { blackKingPosition = x; } break; } } } if (board.WhoseMove == ChessPieceColor.White) { GenerateValidMovesKing(board.Squares[blackKingPosition].Piece, board, blackKingPosition); GenerateValidMovesKing(board.Squares[whiteKingPosition].Piece, board, whiteKingPosition); } else { GenerateValidMovesKing(board.Squares[whiteKingPosition].Piece, board, whiteKingPosition); GenerateValidMovesKing(board.Squares[blackKingPosition].Piece, board, blackKingPosition); } //Now that all the pieces were examined we know if the king is in check GenerateValidMovesKingCastle(board, board.Squares[whiteKingPosition].Piece); GenerateValidMovesKingCastle(board, board.Squares[blackKingPosition].Piece); }