fn generateMoves(self: @This(), color: Colors) void {
var source_square: BoardType = undefined;
var target_square: BoardType = undefined;
const pieces = switch (color) {
.white => &[_]PE{ .P, .N, .B, .R, .Q, .K },
.black => &[_]PE{ .p, .n, .b, .r, .q, .k },
};
for (pieces) |piece| {
var board = @bitCast(BoardType, self.bitboards[piece.int()]);
// generate pawn and castling moves
switch (piece) {
.P, .p => {
while (board != 0) {
const s = @intCast(u6, @ctz(board));
source_square = @as(BoardType, 1) << s;
std.debug.print("pawn: {any}\n", .{@intToEnum(Square, s)});
// early exit on underflow/overflow
switch (piece) {
.P => if (@subWithOverflow(BoardType, source_square, 8, &target_square)) continue,
.p => if (@addWithOverflow(BoardType, source_square, 8, &target_square)) continue,
else => unreachable,
}
// generate quiet pawn moves
if (self.occupBoth() & target_square == 0) {
const promote_condition = switch (piece) {
.P => source_square >= @enumToInt(Square.a7) and
source_square <= @enumToInt(Square.h7),
.p => source_square >= @enumToInt(Square.a2) and
source_square <= @enumToInt(Square.h2),
else => unreachable,
};
const double_step_condition = switch (piece) {
.P => source_square >= @enumToInt(Square.a2) and
source_square <= @enumToInt(Square.h2) and
self.occupBoth() & (target_square - 8) == 0,
.p => source_square >= @enumToInt(Square.a7) and
source_square <= @enumToInt(Square.h7) and
self.occupBoth() & (target_square + 8) == 0,
else => unreachable,
};
if (promote_condition) {
// TODO: add move to move list
} else {
// TODO: single step
// TODO: double step
// FIXME: if single step is no-go, double can not work
if (double_step_condition) {}
}
}
// pop least significant bit
board ^= source_square;
}
},
else => {},
}
}
// generate move for rest of pieces
}