//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); } } WhiteAttackBoard = new bool[64]; BlackAttackBoard = new bool[64]; for (byte x = 0; x < 64; x++) { WhiteAttackBoard[x] = board.WhiteAttackBoard[x]; BlackAttackBoard[x] = board.BlackAttackBoard[x]; } EndGamePhase = board.EndGamePhase; HalfMoveClock = board.HalfMoveClock; RepeatedMove = board.RepeatedMove; WhiteCastled = board.WhiteCastled; BlackCastled = board.BlackCastled; WhiteCanCastle = board.WhiteCanCastle; BlackCanCastle = board.BlackCanCastle; WhiteKingPosition = board.WhiteKingPosition; BlackKingPosition = board.BlackKingPosition; BlackCheck = board.BlackCheck; WhiteCheck = board.WhiteCheck; StaleMate = board.StaleMate; WhiteMate = board.WhiteMate; BlackMate = board.BlackMate; WhoseMove = board.WhoseMove; EnPassantPosition = board.EnPassantPosition; EnPassantColor = board.EnPassantColor; Score = board.Score; LastMove = new MoveContent(board.LastMove); MoveCount = board.MoveCount; }
internal static void SaveCurrentGameMove(Board currentBoard, Board previousBoard, ICollection <OpeningMove> gameBook, MoveContent bestMove) { try { var move = new OpeningMove { StartingFEN = Board.Fen(true, previousBoard), EndingFEN = Board.Fen(true, currentBoard) }; move.Moves.Add(bestMove); gameBook.Add(move); foreach (var move1 in gameBook) { byte repeatedMoves = 0; foreach (var move2 in gameBook) { if (move1.EndingFEN == move2.EndingFEN) { repeatedMoves++; } } if (previousBoard.RepeatedMove >= repeatedMoves) { continue; } previousBoard.RepeatedMove = repeatedMoves; currentBoard.RepeatedMove = repeatedMoves; } if (currentBoard.RepeatedMove >= 3) { currentBoard.StaleMate = true; } } catch (Exception) { // ignored } }
public Board() { Squares = new Square[64]; for (byte i = 0; i < 64; i++) { Squares[i] = new Square(); } LastMove = new MoveContent(); BlackCanCastle = true; WhiteCanCastle = true; WhiteAttackBoard = new bool[64]; BlackAttackBoard = new bool[64]; }
public void AiPonderMove() { Thinking = true; ChessBoard.BlackMate = false; ChessBoard.WhiteMate = false; PieceValidMoves.GenerateValidMoves(ChessBoard); NodesSearched = 0; var resultBoards = new ResultBoards { Positions = new List <Board>() }; // First search if human move might have caused a mate if (CheckForMate(WhoseMove, ref ChessBoard)) { Thinking = false; return; } var bestMove = new MoveContent(); //If there is no playbook move search for the best move if (FindPlayBookMove(ref bestMove, ChessBoard, OpeningBook) == false || ChessBoard.HalfMoveClock > 90 || ChessBoard.RepeatedMove >= 2) { if (FindPlayBookMove(ref bestMove, ChessBoard, CurrentGameBook) == false || ChessBoard.HalfMoveClock > 90 || ChessBoard.RepeatedMove >= 2) { bestMove = Search.IterativeSearch( ChessBoard, PlyDepthSearched, ref NodesSearched, ref NodesQuiessence, ref pvLine, ref PlyDepthReached, ref RootMovesSearched, CurrentGameBook); } } //Make the move PreviousChessBoard = new Board(ChessBoard); RootMovesSearched = (byte)resultBoards.Positions.Count; Board.MovePiece(ChessBoard, 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++) { var sqr = ChessBoard.Squares[x]; if (sqr.Piece == null) { continue; } sqr.Piece.DefendedValue = 0; sqr.Piece.AttackedValue = 0; } PieceValidMoves.GenerateValidMoves(ChessBoard); Evaluation.EvaluateBoardScore(ChessBoard); PieceTakenAdd(ChessBoard.LastMove); MoveHistory.Push(ChessBoard.LastMove); //Second Call if computer move might have caused a mate if (CheckForMate(WhoseMove, ref ChessBoard)) { Thinking = false; if (ChessBoard.WhiteMate || ChessBoard.BlackMate) { LastMove.PgnMove += "#"; } return; } if (ChessBoard.WhiteCheck || ChessBoard.BlackCheck) { LastMove.PgnMove += "+"; } Thinking = false; }
// ReSharper disable IdentifierTypo internal static MoveContent IterativeSearch(Board examineBoard, byte depth, ref int nodesSearched, ref int nodesQuiessence, ref string pvLine, ref byte plyDepthReached, ref byte rootMovesSearched, List <OpeningMove> currentGameBook) { var pvChild = new List <Position>(); var alpha = -400000000; const int beta = 400000000; var bestMove = new MoveContent(); //We are going to store our result boards here var succ = GetSortValidMoves(examineBoard); rootMovesSearched = (byte)succ.Positions.Count; if (rootMovesSearched == 1) { return(succ.Positions[0].LastMove); } foreach (var pos in succ.Positions) { var value = -AlphaBeta(pos, 1, -beta, -alpha, ref nodesSearched, ref nodesQuiessence, ref pvChild, true); //Can I make an instant mate? if (value >= 32767) { return(pos.LastMove); } } var currentBoard = 0; alpha = -400000000; succ.Positions.Sort(Sort); depth--; plyDepthReached = ModifyDepth(depth, succ.Positions.Count); foreach (var pos in succ.Positions) { currentBoard++; progress = (int)(currentBoard / (decimal)succ.Positions.Count * 100); pvChild = new List <Position>(); var value = -AlphaBeta(pos, depth, -beta, -alpha, ref nodesSearched, ref nodesQuiessence, ref pvChild, false); if (value >= 32767) { return(pos.LastMove); } if (examineBoard.RepeatedMove == 2) { var fen = Board.Fen(true, pos); foreach (var move in currentGameBook) { if (move.EndingFEN == fen) { value = 0; break; } } } pos.Score = value; //If value is greater then alpha this is the best board // ReSharper disable once InvertIf if (value > alpha || alpha == -400000000) { pvLine = pos.LastMove.ToString(); foreach (var pvPos in pvChild) { pvLine += " " + pvPos.ToString(); } alpha = value; bestMove = pos.LastMove; } } plyDepthReached++; progress = 100; return(bestMove); }