private static void GenerateQuietMoves(this IPosition pos, MoveList moves, Emgf flags) { var currentSide = pos.State.SideToMove; var up = currentSide == PlayerExtensions.White ? EDirection.North : EDirection.South; var notOccupied = ~pos.Pieces(); var pushed = (pos.Pieces(EPieceType.Pawn, currentSide) & ~currentSide.Rank7()).Shift(up) & notOccupied; pos.AddPawnMoves(moves, pushed, currentSide.PawnPushDistance(), EMoveType.Quiet, flags); pushed &= currentSide.Rank3(); pos.AddPawnMoves(moves, pushed.Shift(up) & notOccupied, currentSide.PawnDoublePushDistance(), EMoveType.Doublepush, flags); pos.AddMoves(moves, notOccupied, flags); if (pos.InCheck) { return; } for (var castleType = ECastleling.Short; castleType < ECastleling.CastleNb; castleType++) { if (pos.CanCastle(castleType)) { pos.AddCastleMove(moves, pos.GetKingCastleFrom(currentSide, castleType), castleType.GetKingCastleTo(currentSide), flags); } } }
/// <summary> /// Iterates through the piece types and generates moves based on their attacks. /// It does not contain any checks for moves that are invalid, as the leaf methods /// contains implicit denial of move generation if the target bitboard is empty. /// </summary> /// <param name="moves">The move list to add potential moves to.</param> /// <param name="targetSquares">The target squares to move to</param> private static void AddMoves(this IPosition pos, MoveList moves, BitBoard targetSquares, Emgf flags) { var c = pos.State.SideToMove; var occupied = pos.Pieces(); for (var pt = EPieceType.Knight; pt <= EPieceType.King; ++pt) { var pc = pt.MakePiece(c); var pieces = pos.Pieces(pc); while (pieces) { var from = pieces.Lsb(); pos.AddMoves(moves, pc, from, from.GetAttacks(pt, occupied) & targetSquares, flags); BitBoards.ResetLsb(ref pieces); } } }
private static void GenerateCapturesAndPromotions(this IPosition pos, MoveList moves, Emgf flags) { var currentSide = pos.State.SideToMove; var them = ~currentSide; var occupiedByThem = pos.OccupiedBySide[them.Side]; var(northEast, northWest) = currentSide.GetPawnAttackDirections(); var pawns = pos.Pieces(EPieceType.Pawn, currentSide); pos.AddPawnMoves(moves, currentSide.PawnPush(pawns & currentSide.Rank7()) & ~pos.Pieces(), currentSide.PawnPushDistance(), EMoveType.Quiet, flags); pos.AddPawnMoves(moves, pawns.Shift(northEast) & occupiedByThem, currentSide.PawnWestAttackDistance(), EMoveType.Capture, flags); pos.AddPawnMoves(moves, pawns.Shift(northWest) & occupiedByThem, currentSide.PawnEastAttackDistance(), EMoveType.Capture, flags); if (pos.State.EnPassantSquare != ESquare.none) { pos.AddPawnMoves(moves, pawns.Shift(northEast) & pos.State.EnPassantSquare, currentSide.PawnWestAttackDistance(), EMoveType.Epcapture, flags); pos.AddPawnMoves(moves, pawns.Shift(northWest) & pos.State.EnPassantSquare, currentSide.PawnEastAttackDistance(), EMoveType.Epcapture, flags); } pos.AddMoves(moves, occupiedByThem, flags); }