public static void GenerateCastlingMoves(Board board, MovesList movesList) { int kingSideCastle = board.side == white ? whiteKingSideCastle : blackKingSideCastle; int queenSideCastle = board.side == white ? whiteQueenSideCastle : blackQueenSideCastle; int kingSquare = board.pieces[board.side + kingBits][0]; if ((board.castlePermission & kingSideCastle) > 0) { if (board[kingSquare + 1] == empty && board[kingSquare + 2] == empty) { if (!Attack.SquareAttacked(board, kingSquare, enemy) && !Attack.SquareAttacked(board, kingSquare + 1, enemy)) { AddMove.QuietMove(board, Move.Write(kingSquare, kingSquare + 2, 0, 0, false, false, true), movesList); } } } if ((board.castlePermission & queenSideCastle) > 0) { if (board[kingSquare - 1] == empty && board[kingSquare - 2] == empty && board[kingSquare - 3] == empty) { if (!Attack.SquareAttacked(board, kingSquare, enemy) && !Attack.SquareAttacked(board, kingSquare - 1, enemy)) { AddMove.QuietMove(board, Move.Write(kingSquare, kingSquare - 2, 0, 0, false, false, true), movesList); } } } }
public static void PromotionMove(Board board, int move, MovesList movesList) { movesList.Add(new Move(move + ((board.side += queenBit) << 22), 0)); movesList.Add(new Move(move + ((board.side += diagionalBit) << 22), 0)); movesList.Add(new Move(move + ((board.side += orthogonalBit) << 22), 0)); movesList.Add(new Move(move + ((board.side += knightBit) << 22), 0)); }
static void _Perft(int depth, Board board) { if (depth == 0) { leafNodes++; return; } MovesList movesList = new MovesList(); MoveGenerator.GenerateAllMoves(board, movesList); int MoveNum = 0; for (MoveNum = 0; MoveNum < movesList.Count; ++MoveNum) { if (!MakeMove.Make(board, movesList[MoveNum].move)) { continue; } _Perft(depth - 1, board); MakeMove.Take(board); } return; }
static public void PerftTest(int depth, Board board) { Stopwatch stopwatch = new Stopwatch(); Board.Draw(board); leafNodes = 0; stopwatch.Start(); MovesList movesList = new MovesList(); MoveGenerator.GenerateAllMoves(board, movesList); int move; int MoveNum = 0; for (MoveNum = 0; MoveNum < movesList.Count; ++MoveNum) { move = movesList[MoveNum].move; if (!MakeMove.Make(board, move)) { continue; } long cumnodes = leafNodes; _Perft(depth - 1, board); MakeMove.Take(board); long oldnodes = leafNodes - cumnodes; Console.Write($"move {MoveNum + 1} : { move} : {oldnodes}\n"); } Console.Write($"\nTest Complete : {leafNodes} nodes visited in {stopwatch.ElapsedMilliseconds}ms, speed = {leafNodes/stopwatch.ElapsedMilliseconds}kn/s\n"); return; }
public static void WriteDownAllMoves(MovesList movesList) { Console.WriteLine(movesList.Count + " moves"); for (int i = 0; i < movesList.Count; i++) { Console.WriteLine(); Console.WriteLine("From: " + Move.From(movesList[i].move)); Console.WriteLine("to: " + Move.To(movesList[i].move)); } }
static void Main(string[] args) { Init.All(); Board board = new Board(); MovesList movesList = new MovesList(); IO.ParseFen(board, "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10 "); Perft.PerftTest(5, board); Console.ReadKey(); }
public static void GenerateAllMoves(Board board, MovesList movesList) { enemy = board.side ^ border; GeneratePawnMoves(board, movesList); GenerateCastlingMoves(board, movesList); GenerateMovesForPiece(board, movesList, board.side + knightBit, false); GenerateMovesForPiece(board, movesList, board.side + kingBits, false); GenerateMovesForPiece(board, movesList, board.side + queenBit, true); GenerateMovesForPiece(board, movesList, board.side + orthogonalBit, true); GenerateMovesForPiece(board, movesList, board.side + diagionalBit, true); }
public static void GenerateMovesForPiece(Board board, MovesList movesList, int piece, bool slider) { for (int i = 0; i < board.pieces[piece].Count; i++) { int square = board.pieces[piece][i]; for (int j = 0; j < Directions[piece].Length; j++) { int toSquare = square + Directions[piece][j]; do { if ((board[toSquare] & border) > 0) { if ((board[toSquare] & border) == enemy) { AddMove.CaptureMove(board, Move.Write(square, toSquare, board[toSquare], 0, false, false, false), movesList); } break; } AddMove.QuietMove(board, Move.Write(square, toSquare, 0, 0, false, false, false), movesList); toSquare += Directions[piece][j]; } while (slider); } } }
public static void PawnCaptureMove(Board board, int move, MovesList movesList) => movesList.Add(new Move(move, 0));
public static void EnpassantMove(Board board, int move, MovesList movesList) => movesList.Add(new Move(move, 0));
public static void QuietPawnMove(Board board, int move, MovesList movesList) => movesList.Add(new Move(move, 0));
public static void GeneratePawnMoves(Board board, MovesList movesList) { int piece = board.side + pawnBit; int direction = board.side == white ? boardWidth : -boardWidth; Func <int, bool> promotionZone; Func <int, bool> pawnStartZone; if (board.side == white) { promotionZone = (int Square) => Square > (int)H6; pawnStartZone = (int square) => square < (int)A3; } else { pawnStartZone = (int Square) => Square > (int)H6; promotionZone = (int square) => square < (int)A3; } for (int i = 0; i < board.pieces[piece].Count; i++) { int square = board.pieces[piece][i]; int toSquare = square + direction; // promotions if (promotionZone(square)) { if (board[toSquare] == empty) { AddMove.PromotionMove(board, Move.Write(square, toSquare, 0, 0, false, false, false), movesList); } //captures if ((board[toSquare + 1] & border) == enemy) { AddMove.PromotionMove(board, Move.Write(square, toSquare + 1, board[toSquare + 1], 0, false, false, false), movesList); } if ((board[toSquare - 1] & border) == enemy) { AddMove.PromotionMove(board, Move.Write(square, toSquare - 1, board[toSquare - 1], 0, false, false, false), movesList); } } else { if (board[toSquare] == empty) { AddMove.QuietPawnMove(board, Move.Write(square, toSquare, 0, 0, false, false, false), movesList); //pawnstart if (pawnStartZone(square) && (board[toSquare + direction] == empty)) { AddMove.QuietPawnMove(board, Move.Write(square, toSquare + direction, 0, 0, false, true, false), movesList); } } //captures if ((board[toSquare + 1] & border) == enemy) { AddMove.PawnCaptureMove(board, Move.Write(square, toSquare + 1, board[toSquare + 1], 0, false, false, false), movesList); } if ((board[toSquare - 1] & border) == enemy) { AddMove.PawnCaptureMove(board, Move.Write(square, toSquare - 1, board[toSquare - 1], 0, false, false, false), movesList); } //enpassant if (toSquare + 1 == board.enpassantSquare) { AddMove.EnpassantMove(board, Move.Write(square, board.enpassantSquare, board[board.enpassantSquare], 0, true, false, false), movesList); } if (toSquare - 1 == board.enpassantSquare) { AddMove.EnpassantMove(board, Move.Write(square, board.enpassantSquare, board[board.enpassantSquare], 0, true, false, false), movesList); } } } }