private static ResultBoards GetSortValidMoves(Board examineBoard) { ResultBoards resultBoards = new ResultBoards() { Positions = new List <Board>(30) }; Search.piecesRemaining = 0; for (byte srcPosition = 0; (int)srcPosition < 64; ++srcPosition) { Square square = examineBoard.Squares[(int)srcPosition]; if (square.Piece != null) { ++Search.piecesRemaining; if (square.Piece.PieceColor == examineBoard.WhoseMove) { foreach (byte validMove in square.Piece.ValidMoves) { Board board = examineBoard.FastCopy(); Board.MovePiece(board, srcPosition, validMove, ChessPieceType.Queen); PieceValidMoves.GenerateValidMoves(board); if ((!board.WhiteCheck || examineBoard.WhoseMove != ChessPieceColor.White) && (!board.BlackCheck || examineBoard.WhoseMove != ChessPieceColor.Black)) { Evaluation.EvaluateBoardScore(board); board.Score = Search.SideToMoveScore(board.Score, board.WhoseMove); resultBoards.Positions.Add(board); } } } } } resultBoards.Positions.Sort(new Comparison <Board>(Search.Sort)); return(resultBoards); }
private static ResultBoards GetPossibleBoards(ChessPieceColor movingSide, Board examineBoard) { //We are going to store our result boards here resultBoards = new ResultBoards { Positions = new List <Board>() }; 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 && movingSide == ChessPieceColor.Black) { continue; } if (board.WhiteCheck && movingSide == ChessPieceColor.White) { continue; } //We calculate the board score Evaluation.EvaluateBoardScore(board); //Invert Score to support Negamax board.Score = SideToMoveScore(board.Score, GetOppositeColor(movingSide)); resultBoards.Positions.Add(board); } } return(resultBoards); }
internal static bool SearchForMate(ChessPieceColor movingSide, Board examineBoard, ref bool blackMate, ref bool whiteMate, ref bool staleMate) { bool flag1 = false; bool flag2 = false; for (byte srcPosition = 0; (int)srcPosition < 64; ++srcPosition) { Square square = examineBoard.Squares[(int)srcPosition]; if (square.Piece != null && square.Piece.PieceColor == movingSide) { foreach (byte validMove in square.Piece.ValidMoves) { Board board = examineBoard.FastCopy(); Board.MovePiece(board, srcPosition, validMove, ChessPieceType.Queen); PieceValidMoves.GenerateValidMoves(board); if (!board.BlackCheck) { flag1 = true; } else if (movingSide == ChessPieceColor.Black) { continue; } if (!board.WhiteCheck) { flag2 = true; } } } } if (!flag1) { if (examineBoard.BlackCheck) { blackMate = true; return(true); } if (!examineBoard.WhiteMate && movingSide != ChessPieceColor.White) { staleMate = true; return(true); } } if (!flag2) { if (examineBoard.WhiteCheck) { whiteMate = true; return(true); } if (!examineBoard.BlackMate && movingSide != ChessPieceColor.Black) { staleMate = true; return(true); } } return(false); }
private static int Quiescence(Board examineBoard, int alpha, int beta, ref int nodesSearched) { nodesSearched = nodesSearched + 1; Evaluation.EvaluateBoardScore(examineBoard); examineBoard.Score = Search.SideToMoveScore(examineBoard.Score, examineBoard.WhoseMove); if (examineBoard.Score >= beta) { return(beta); } if (examineBoard.Score > alpha) { alpha = examineBoard.Score; } List <Search.Position> positionList = examineBoard.WhiteCheck || examineBoard.BlackCheck ? Search.EvaluateMoves(examineBoard, (byte)0) : Search.EvaluateMovesQ(examineBoard); if (positionList.Count == 0) { return(examineBoard.Score); } positionList.Sort(new Comparison <Search.Position>(Search.Sort)); foreach (Search.Position position in positionList) { if (Search.StaticExchangeEvaluation(examineBoard.Squares[(int)position.DstPosition]) < 0) { Board board = examineBoard.FastCopy(); Board.MovePiece(board, position.SrcPosition, position.DstPosition, ChessPieceType.Queen); PieceValidMoves.GenerateValidMoves(board); if ((!board.BlackCheck || examineBoard.WhoseMove != ChessPieceColor.Black) && (!board.WhiteCheck || examineBoard.WhoseMove != ChessPieceColor.White)) { int num = -Search.Quiescence(board, -beta, -alpha, ref nodesSearched); if (num >= beta) { Search.KillerMove[2, 0].SrcPosition = position.SrcPosition; Search.KillerMove[2, 0].DstPosition = position.DstPosition; return(beta); } if (num > alpha) { alpha = num; } } } } return(alpha); }
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 int Quiescence(Board examineBoard, int alpha, int beta, ref int nodesSearched) { nodesSearched++; //Evaluate Score Evaluation.EvaluateBoardScore(examineBoard); //Invert Score to support Negamax examineBoard.Score = SideToMoveScore(examineBoard.Score, examineBoard.WhoseMove); if (examineBoard.Score >= beta) { return(beta); } if (examineBoard.Score > alpha) { alpha = examineBoard.Score; } List <Position> positions; if (examineBoard.WhiteCheck || examineBoard.BlackCheck) { positions = EvaluateMoves(examineBoard, 0); } else { positions = EvaluateMovesQ(examineBoard); } if (positions.Count == 0) { return(examineBoard.Score); } positions.Sort(Sort); foreach (Position move in positions) { if (StaticExchangeEvaluation(examineBoard.Squares[move.DstPosition]) >= 0) { continue; } //Make a copy Board board = examineBoard.FastCopy(); //Move Piece Board.MovePiece(board, move.SrcPosition, move.DstPosition, ChessPieceType.Queen); //We Generate Valid Moves for Board PieceValidMoves.GenerateValidMoves(board); if (board.BlackCheck) { if (examineBoard.WhoseMove == ChessPieceColor.Black) { //Invalid Move continue; } } if (board.WhiteCheck) { if (examineBoard.WhoseMove == ChessPieceColor.White) { //Invalid Move continue; } } int value = -Quiescence(board, -beta, -alpha, ref nodesSearched); if (value >= beta) { KillerMove[2, 0].SrcPosition = move.SrcPosition; KillerMove[2, 0].DstPosition = move.DstPosition; return(beta); } if (value > alpha) { alpha = value; } } return(alpha); }
private static int AlphaBeta(Board examineBoard, byte depth, int alpha, int beta, ref int nodesSearched, ref int nodesQuiessence, ref List <Position> pvLine, bool extended) { nodesSearched++; if (examineBoard.FiftyMove >= 50 || examineBoard.RepeatedMove >= 3) { return(0); } //End Main Search with Quiescence if (depth == 0) { if (!extended && examineBoard.BlackCheck || examineBoard.WhiteCheck) { depth++; extended = true; } else { //Perform a Quiessence Search return(Quiescence(examineBoard, alpha, beta, ref nodesQuiessence)); } } List <Position> positions = EvaluateMoves(examineBoard, depth); if (examineBoard.WhiteCheck || examineBoard.BlackCheck || positions.Count == 0) { if (SearchForMate(examineBoard.WhoseMove, examineBoard, ref examineBoard.BlackMate, ref examineBoard.WhiteMate, ref examineBoard.StaleMate)) { if (examineBoard.BlackMate) { if (examineBoard.WhoseMove == ChessPieceColor.Black) { return(-32767 - depth); } return(32767 + depth); } if (examineBoard.WhiteMate) { if (examineBoard.WhoseMove == ChessPieceColor.Black) { return(32767 + depth); } return(-32767 - depth); } //If Not Mate then StaleMate return(0); } } positions.Sort(Sort); foreach (Position move in positions) { List <Position> pvChild = new List <Position>(); //Make a copy Board board = examineBoard.FastCopy(); //Move Piece Board.MovePiece(board, move.SrcPosition, move.DstPosition, ChessPieceType.Queen); //We Generate Valid Moves for Board PieceValidMoves.GenerateValidMoves(board); if (board.BlackCheck) { if (examineBoard.WhoseMove == ChessPieceColor.Black) { //Invalid Move continue; } } if (board.WhiteCheck) { if (examineBoard.WhoseMove == ChessPieceColor.White) { //Invalid Move continue; } } int value = -AlphaBeta(board, (byte)(depth - 1), -beta, -alpha, ref nodesSearched, ref nodesQuiessence, ref pvChild, extended); if (value >= beta) { KillerMove[kIndex, depth].SrcPosition = move.SrcPosition; KillerMove[kIndex, depth].DstPosition = move.DstPosition; kIndex = ((kIndex + 1) % 2); return(beta); } if (value > alpha) { Position pvPos = new Position(); pvPos.SrcPosition = board.LastMove.MovingPiecePrimary.SrcPosition; pvPos.DstPosition = board.LastMove.MovingPiecePrimary.DstPosition; pvPos.Move = board.LastMove.ToString(); pvChild.Insert(0, pvPos); pvLine = pvChild; alpha = (int)value; } } return(alpha); }
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); }
private static int AlphaBeta(Board examineBoard, byte depth, int alpha, int beta, ref int nodesSearched, ref int nodesQuiessence, ref List <Search.Position> pvLine, bool extended) { nodesSearched = nodesSearched + 1; if ((int)examineBoard.FiftyMove >= 50 || (int)examineBoard.RepeatedMove >= 3) { return(0); } int?nullable1 = Zobrist.Search(examineBoard.ZobristHash, depth, alpha, beta); if (nullable1.HasValue) { return(nullable1.Value); } if ((int)depth == 0) { if (!extended && examineBoard.BlackCheck || examineBoard.WhiteCheck) { ++depth; extended = true; } else { int score = Search.Quiescence(examineBoard, alpha, beta, ref nodesQuiessence); if (score >= beta) { Zobrist.AddEntry(examineBoard.ZobristHash, depth, score, Zobrist.NodeType.Beta); } else if (score <= alpha) { Zobrist.AddEntry(examineBoard.ZobristHash, depth, score, Zobrist.NodeType.Alpha); } else { Zobrist.AddEntry(examineBoard.ZobristHash, depth, score, Zobrist.NodeType.Exact); } return(score); } } Zobrist.NodeType nodeType = Zobrist.NodeType.Alpha; List <Search.Position> moves = Search.EvaluateMoves(examineBoard, depth); if ((examineBoard.WhiteCheck || examineBoard.BlackCheck || moves.Count == 0) && Search.SearchForMate(examineBoard.WhoseMove, examineBoard, ref examineBoard.BlackMate, ref examineBoard.WhiteMate, ref examineBoard.StaleMate)) { if (examineBoard.BlackMate) { if (examineBoard.WhoseMove == ChessPieceColor.Black) { return(-32767 - (int)depth); } return((int)short.MaxValue + (int)depth); } if (!examineBoard.WhiteMate) { return(0); } if (examineBoard.WhoseMove == ChessPieceColor.Black) { return((int)short.MaxValue + (int)depth); } return(-32767 - (int)depth); } moves.Sort(new Comparison <Search.Position>(Search.Sort)); foreach (Search.Position position in moves) { List <Search.Position> pvLine1 = new List <Search.Position>(); Board board = examineBoard.FastCopy(); Board.MovePiece(board, position.SrcPosition, position.DstPosition, ChessPieceType.Queen); PieceValidMoves.GenerateValidMoves(board); if ((!board.BlackCheck || examineBoard.WhoseMove != ChessPieceColor.Black) && (!board.WhiteCheck || examineBoard.WhoseMove != ChessPieceColor.White)) { int?nullable2 = new int?(-Search.AlphaBeta(board, (byte)((uint)depth - 1U), -beta, -alpha, ref nodesSearched, ref nodesQuiessence, ref pvLine1, extended)); int?nullable3 = nullable2; int num1 = beta; if ((nullable3.GetValueOrDefault() >= num1 ? (nullable3.HasValue ? 1 : 0) : 0) != 0) { Search.KillerMove[Search.kIndex, (int)depth].SrcPosition = position.SrcPosition; Search.KillerMove[Search.kIndex, (int)depth].DstPosition = position.DstPosition; Search.kIndex = (Search.kIndex + 1) % 2; Zobrist.AddEntry(examineBoard.ZobristHash, depth, nullable2.Value, Zobrist.NodeType.Beta); return(beta); } nullable3 = nullable2; int num2 = alpha; if ((nullable3.GetValueOrDefault() > num2 ? (nullable3.HasValue ? 1 : 0) : 0) != 0) { pvLine1.Insert(0, new Search.Position() { SrcPosition = board.LastMove.MovingPiecePrimary.SrcPosition, DstPosition = board.LastMove.MovingPiecePrimary.DstPosition, Move = board.LastMove.ToString() }); pvLine = pvLine1; alpha = nullable2.Value; nodeType = Zobrist.NodeType.Exact; } } } Zobrist.AddEntry(examineBoard.ZobristHash, depth, alpha, nodeType); return(alpha); }