private static List <Move> ComputeUnRayedMoves(Board _board, Piece piece) { List <Move> moves = new List <Move>(); // Fetch the bitboard containing positions of these pieces ulong pieces; ulong friendBoard, oppBoard; Side side = (Side)((int)piece % 2); Position[, ][] pieceMoves; if (piece == Piece.BlackKnight || piece == Piece.WhiteKnight) { pieceMoves = KnightMoves; } else if (piece == Piece.BlackKing || piece == Piece.WhiteKing) { pieceMoves = KingMoves; } else { throw new Exception("illegal piece"); } pieces = _board.BitBoards[(int)piece]; // Check for pieces of type if (pieces == 0) { return(moves); } friendBoard = _board.BitBoards[(int)Piece.AllBlacks + ((int)piece % 2)]; oppBoard = _board.BitBoards[(int)Piece.AllBlacks + (((int)piece + 1) % 2)]; //lets roll over all pieces and examine possible moves (already stored) foreach (Position sourceSquare in Position.FindPositions(pieces)) { for (int k = 0; k < pieceMoves[sourceSquare.Row, sourceSquare.Col].Length; k++) { Position dest = pieceMoves[sourceSquare.Row, sourceSquare.Col][k]; //if dest is friendly, continue if ((friendBoard & dest.ToBitBoard()) != 0) { continue; } //add the move Move move = new Move() { SourceSquare = sourceSquare, DestinationSquare = dest, MovingPiece = piece }; //check for capture if ((oppBoard & dest.ToBitBoard()) != 0) { move.CapturedPiece = _board.FindPiece(dest); if (move.CapturedPiece == Piece.BlackKing) { //move is a checkmate, change board and return null ( so move generation will stop). move.MoveType = MoveType.Checkmate; _board.IsTerminal = (TerminalType)(TerminalType.BlackWon + (int)piece % 2); return(null); } else { move.MoveType = MoveType.Capture; } } else { move.MoveType = MoveType.Normal; } moves.Add(move); } } return(moves); }
private static List <Move> ComputePawnMoves(Board _board, Side _side) { List <Move> moves = new List <Move>(); Piece movingPiece = Piece.BlackPawn + (int)_side; ulong pawns = _board.BitBoards[(int)movingPiece]; ulong oppBoard = _board.BitBoards[(int)Piece.AllBlacks + ((int)_side + 1) % 2]; ulong emptyBoard = _board.BitBoards[(int)Piece.EmptySquare]; int directionSign = _side == Side.White ? -1 : +1; int startingPos = _side == Side.White ? 7 : 0; //check which pawns can move one step by moving all pawns one row forward and AND-ing with the empty squares ulong canOneStep, canTwoSteps, canCaptureLeft, canCaptureRight; if (_side == Side.White) { canOneStep = ((pawns >> 8) & emptyBoard) << 8; //to check two-steps moves ( 7th row) we first clear all other pawn pieces by shifting 6 rows then we shift back to the position //of two steps forward. If empty then that pawn can move there. canTwoSteps = (((canOneStep >> (8 * 6)) << 8 * 4) & emptyBoard) << 8 * 2; //look for capture moves canCaptureLeft = ((pawns >> 9) & oppBoard) << 9; canCaptureRight = ((pawns >> 7) & oppBoard) << 7; } else { canOneStep = ((pawns << 8) & emptyBoard) >> 8; canTwoSteps = (((canOneStep << (8 * 6)) >> 8 * 4) & emptyBoard) >> 8 * 2; canCaptureLeft = ((pawns << 9) & oppBoard) >> 9; canCaptureRight = ((pawns << 7) & oppBoard) >> 7; } //add normal one-step moves, (including promotion) foreach (Position sourceSquare in Position.FindPositions(canOneStep)) { if (sourceSquare.Row == 7 - startingPos + directionSign) { moves.Add(new Move { MovingPiece = movingPiece, MoveType = MoveType.PromotionQueen, SourceSquare = sourceSquare, DestinationSquare = new Position(sourceSquare.Row + directionSign, sourceSquare.Col) }); moves.Add(new Move { MovingPiece = movingPiece, MoveType = MoveType.PromotionBishop, SourceSquare = sourceSquare, DestinationSquare = new Position(sourceSquare.Row + directionSign, sourceSquare.Col) }); moves.Add(new Move { MovingPiece = movingPiece, MoveType = MoveType.PromotionKnight, SourceSquare = sourceSquare, DestinationSquare = new Position(sourceSquare.Row + directionSign, sourceSquare.Col) }); moves.Add(new Move { MovingPiece = movingPiece, MoveType = MoveType.PromotionRook, SourceSquare = sourceSquare, DestinationSquare = new Position(sourceSquare.Row + directionSign, sourceSquare.Col) }); } else { moves.Add(new Move { MovingPiece = movingPiece, MoveType = MoveType.Normal, SourceSquare = sourceSquare, DestinationSquare = new Position(sourceSquare.Row + directionSign, sourceSquare.Col) }); } } //add two-step moves foreach (Position sourceSquare in Position.FindPositions(canTwoSteps)) { moves.Add(new Move { MovingPiece = movingPiece, MoveType = MoveType.Normal, SourceSquare = sourceSquare, DestinationSquare = new Position(sourceSquare.Row + directionSign * 2, sourceSquare.Col) }); } //add capture moves //to the left foreach (Position sourceSquare in Position.FindPositions(canCaptureLeft)) { Position capturedPosition = new Position(sourceSquare.Row + directionSign, sourceSquare.Col + directionSign); //might happen when bitwise shifting if (capturedPosition.Col == -1 || capturedPosition.Col == 8) { continue; } Piece captured = _board.FindPiece(capturedPosition); if (captured == Piece.BlackKing) { //move is a checkmate, change board and return null ( so move generation will stop). _board.IsTerminal = (TerminalType)(TerminalType.BlackWon + (int)_side); return(null); } if (sourceSquare.Row == 7 - startingPos + directionSign) { moves.Add(new Move { MovingPiece = movingPiece, CapturedPiece = captured, MoveType = MoveType.Capture & MoveType.PromotionQueen, SourceSquare = sourceSquare, DestinationSquare = capturedPosition }); moves.Add(new Move { MovingPiece = movingPiece, CapturedPiece = captured, MoveType = MoveType.Capture & MoveType.PromotionBishop, SourceSquare = sourceSquare, DestinationSquare = capturedPosition }); moves.Add(new Move { MovingPiece = movingPiece, CapturedPiece = captured, MoveType = MoveType.Capture & MoveType.PromotionKnight, SourceSquare = sourceSquare, DestinationSquare = capturedPosition }); moves.Add(new Move { MovingPiece = movingPiece, CapturedPiece = captured, MoveType = MoveType.Capture & MoveType.PromotionRook, SourceSquare = sourceSquare, DestinationSquare = capturedPosition }); } else { moves.Add(new Move { MovingPiece = movingPiece, CapturedPiece = captured, MoveType = MoveType.Capture, SourceSquare = sourceSquare, DestinationSquare = capturedPosition }); } } //to the right foreach (Position sourceSquare in Position.FindPositions(canCaptureRight)) { Position capturedPosition = new Position(sourceSquare.Row + directionSign, sourceSquare.Col - directionSign); //might happen when bitwise shifting if (capturedPosition.Col == 8 || capturedPosition.Col == -1) { continue; } Piece captured = _board.FindPiece(capturedPosition); if (sourceSquare.Col == 7 - startingPos + directionSign) { moves.Add(new Move { MovingPiece = movingPiece, CapturedPiece = captured, MoveType = MoveType.Capture & MoveType.PromotionQueen, SourceSquare = sourceSquare, DestinationSquare = capturedPosition }); moves.Add(new Move { MovingPiece = movingPiece, CapturedPiece = captured, MoveType = MoveType.Capture & MoveType.PromotionBishop, SourceSquare = sourceSquare, DestinationSquare = capturedPosition }); moves.Add(new Move { MovingPiece = movingPiece, CapturedPiece = captured, MoveType = MoveType.Capture & MoveType.PromotionKnight, SourceSquare = sourceSquare, DestinationSquare = capturedPosition }); moves.Add(new Move { MovingPiece = movingPiece, CapturedPiece = captured, MoveType = MoveType.Capture & MoveType.PromotionRook, SourceSquare = sourceSquare, DestinationSquare = capturedPosition }); } else { moves.Add(new Move { MovingPiece = movingPiece, CapturedPiece = captured, MoveType = MoveType.Capture, SourceSquare = sourceSquare, DestinationSquare = capturedPosition }); } } //find EnPassant foreach (Position sourceSquare in Position.FindPositions(pawns)) { //check en-passant if (_board.EnPassantOptionColumn == sourceSquare.Col - 1 || _board.EnPassantOptionColumn == sourceSquare.Col + 1) { moves.Add(new Move { MovingPiece = movingPiece, MoveType = MoveType.EnPassant, CapturedPiece = movingPiece == Piece.BlackPawn ? Piece.WhitePawn : Piece.BlackPawn, SourceSquare = sourceSquare, DestinationSquare = new Position(sourceSquare.Row + directionSign, _board.EnPassantOptionColumn) }); } } return(moves); }
private static List <Move> ComputeRayedMoves_Internal(Board _board, Piece piece, Position[, ][][] pieceMoves) { List <Move> moves = new List <Move>(); // Fetch the bitboard containing positions of these pieces ulong pieces; ulong friendBoard, oppBoard; pieces = _board.BitBoards[(int)piece]; // Check for pieces of type if (pieces == 0) { return(moves); } friendBoard = _board.BitBoards[(int)Piece.AllBlacks + ((int)piece % 2)]; oppBoard = _board.BitBoards[(int)Piece.AllBlacks + (((int)piece + 1) % 2)]; foreach (Position sourceSquare in Position.FindPositions(pieces)) { //loop over all rays (initalized at engine start) for (int ray = 0; ray < pieceMoves[sourceSquare.Row, sourceSquare.Col].Length; ray++) { for (int k = 0; k < pieceMoves[sourceSquare.Row, sourceSquare.Col][ray].Length; k++) { // Get the destination square Position dest = pieceMoves[sourceSquare.Row, sourceSquare.Col][ray][k]; //if dest is friendly, continue if ((friendBoard & dest.ToBitBoard()) != 0) { break; } // Otherwise, the move is legal, so we must prepare to add it Move move = new Move() { SourceSquare = sourceSquare, DestinationSquare = dest, MovingPiece = piece }; // Is the destination occupied by an enemy? If so, we have a capture if ((oppBoard & dest.ToBitBoard()) != 0) { move.CapturedPiece = _board.FindPiece(dest); if (move.CapturedPiece == Piece.BlackKing) { //move is a checkmate, change board and return null ( so move generation will stop). move.MoveType = MoveType.Checkmate; _board.IsTerminal = (TerminalType)(TerminalType.BlackWon + (int)piece % 2); return(null); } else { move.MoveType = MoveType.Capture; } } // otherwise, it is a simple move else { move.MoveType = MoveType.Normal; } moves.Add(move); } } } return(moves); }