fn castlingMoves(self: @This()) void {
const king_side = switch (self.side) {
.white => [_]Square{ .f1, .g1 },
.black => [_]Square{ .f8, .g8 },
};
const queen_side = switch (self.side) {
.white => [_]Square{ .d1, .c1, .b1 },
.black => [_]Square{ .d8, .c8, .b8 },
};
const attacked_king = switch (self.side) {
.white => [_]Square{ .e1, .f1 },
.black => [_]Square{ .e8, .f8 },
};
const attacked_queen = switch (self.side) {
.white => [_]Square{ .e1, .d1 },
.black => [_]Square{ .e8, .d8 },
};
// king-side castling
if ((self.side == .white and self.castling.WK) or
(self.side == .black and self.castling.BK))
{
// make sure king side is emptry
for (king_side) |square| {
if (self.occupBoth() & @as(BoardType, 1) << square.int() != 0) return;
}
// check that castling squares are not attacked
for (attacked_king) |square| {
if (self.isSquareAttacked(square, self.enemy)) return;
}
std.debug.print("king side castling\n", .{});
}
// queen-side castling
if ((self.side == .white and self.castling.WQ) or
(self.side == .black and self.castling.BQ))
{
// make sure queen side is emptry
for (queen_side) |square| {
if (self.occupBoth() & @as(BoardType, 1) << square.int() != 0) return;
}
// check that castling squares are not attacked
for (attacked_queen) |square| {
if (self.isSquareAttacked(square, self.enemy)) return;
}
std.debug.print("queen side castling\n", .{});
}
}
fn genMoves(self: @This(), board_in: BoardType, piece: PE) void {
var source_square: SquareType = undefined;
var target_square: SquareType = undefined;
var attacks: BoardType = undefined;
var board = board_in;
while (board != 0) {
source_square = @intCast(SquareType, @ctz(board));
const attack_mask = switch (piece) {
.N, .n => self.attacks.knight_attacks[source_square],
.K, .k => self.attacks.king_attacks[source_square],
.B, .b => self.attacks.getBishopAttacks(
@intToEnum(Square, source_square),
self.occupBoth(),
),
.R, .r => self.attacks.getRookAttacks(
@intToEnum(Square, source_square),
self.occupBoth(),
),
.Q, .q => self.attacks.getQueenAttacks(
@intToEnum(Square, source_square),
self.occupBoth(),
),
.P, .p => unreachable,
};
attacks = attack_mask &
~self.occupancies[@enumToInt(self.side)];
while (attacks != 0) {
target_square = @intCast(SquareType, @ctz(attacks));
if (self.occupancies[@enumToInt(self.enemy)] &
@as(BoardType, 1) << target_square != 0)
{
std.debug.print("{any} capture: {any}->{any}\n", .{
piece,
@intToEnum(Square, source_square),
@intToEnum(Square, target_square),
});
} else {
std.debug.print("{any} move: {any}->{any}\n", .{
piece,
@intToEnum(Square, source_square),
@intToEnum(Square, target_square),
});
}
attacks ^= @as(BoardType, 1) << target_square;
}
board ^= @as(BoardType, 1) << source_square;
}
}