3H3DSWLBWCE7C43W6LHICCPJ5KQDLASLQPIKJOK2KAE6OFF2L6WAC
FOORIA7SEZCLKDBNMV6KEDTQOJJVAH57BQFBRSQMET6FERJPHCVQC
A46B5KNQFPTZEIL2JZKD2CQELGU3COE6FGTV2ABS5U7DVTVDGEBQC
2CU67A3QXXPH722WBAL74O6P2N2RRXFBQVPT3A5QAXTUCQ3UUU5AC
TB4YBE4CMWCLSKJ43QF6IU5HVYUUO33BLXVG7XDRLJS3IFIBQLYAC
XHCMZF25YBLNQLVKKBJJWWJ3G24VFUSLE3LAT2DRWL52RJX4Z3EAC
OF6NBX4Y6UWXBSSENWBBYH3AU4TI5FCD5S7WKYMINBUBCKA2MD4AC
fn perftTest(self: *@This(), depth: usize) void {
var ml = Board.MoveList.init(0) catch unreachable;
self.gs.generateMoves(&ml) catch unreachable;
fn perftTest(self: *@This(), depth: usize) !void {
var ml = try Board.MoveList.init(0);
try self.gs.generateMoves(&ml);
test "PerfTest" {
var gs = try Board.GameState.init("8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -");
gs.show();
var p = Perft{ .gs = gs };
var timer = try std.time.Timer.start();
try p.perftTest(3);
std.debug.print("Checked {d} nodes in {d} ms\n", .{ p.nodes, timer.read() / std.time.ns_per_ms });
}
// handling captures
if (move.capture) {
const pieces = switch (self.side) {
.white => [_]Chess.PE{ .p, .n, .b, .r, .q, .k },
.black => [_]Chess.PE{ .P, .N, .B, .R, .Q, .K },
};
{ // handling captures
if (move.capture) {
const pieces = switch (self.side) {
.white => [_]Chess.PE{ .p, .n, .b, .r, .q, .k },
.black => [_]Chess.PE{ .P, .N, .B, .R, .Q, .K },
};
// loop over enemy bitboards, when target occupancy found pop it
for (pieces) |piece| {
if (self.bitboards[piece.int()].isSet(move.target)) {
self.bitboards[piece.int()].pop(move.target);
break;
// loop over enemy bitboards, when target occupancy found pop it
for (pieces) |piece| {
if (self.bitboards[piece.int()].isSet(move.target)) {
self.bitboards[piece.int()].pop(move.target);
break;
}
// handling promotions
if (move.prom != .none) {
// erase pawn from target square (already moved)
self.bitboards[move.piece.int()].pop(move.target);
// add promoted item to target peace
self.bitboards[move.prom.int()].set(move.target);
}
{ // pawn stuff
// handling promotions
if (move.prom != .none) {
// erase pawn from target square (already moved)
self.bitboards[move.piece.int()].pop(move.target);
// add promoted item to target peace
self.bitboards[move.prom.int()].set(move.target);
}
// handling enpassant
if (move.enpassant) {
switch (self.side) {
.white => self.bitboards[Chess.PE.p.int()]
.pop(@intToEnum(Square, @enumToInt(move.target) + 8)),
.black => self.bitboards[Chess.PE.P.int()]
.pop(@intToEnum(Square, @enumToInt(move.target) - 8)),
// handling enpassant
if (move.enpassant) {
switch (self.side) {
.white => self.bitboards[Chess.PE.p.int()]
.pop(@intToEnum(Square, @enumToInt(move.target) + 8)),
.black => self.bitboards[Chess.PE.P.int()]
.pop(@intToEnum(Square, @enumToInt(move.target) - 8)),
}
// handle double pawn step
if (move.double) {
const enpassant = switch (self.side) {
.white => @intToEnum(Square, @enumToInt(move.target) + 8),
.black => @intToEnum(Square, @enumToInt(move.target) - 8),
};
self.enpassant = enpassant;
// handle double pawn step
if (move.double) {
const enpassant = switch (self.side) {
.white => @intToEnum(Square, @enumToInt(move.target) + 8),
.black => @intToEnum(Square, @enumToInt(move.target) - 8),
};
self.enpassant = enpassant;
}
// update occupancy boards
{
var white: BoardType = 0;
var black: BoardType = 0;
for ([_]Chess.PE{ .P, .N, .B, .R, .Q, .K }) |piece| {
white |= @bitCast(BoardType, self.bitboards[piece.int()]);
}
for ([_]Chess.PE{ .p, .n, .b, .r, .q, .k }) |piece| {
black |= @bitCast(BoardType, self.bitboards[piece.int()]);
}
}
self.occupancies[@enumToInt(Chess.Colors.white)] = @bitCast(BitBoard, white);
self.occupancies[@enumToInt(Chess.Colors.black)] = @bitCast(BitBoard, black);
{ // update occupancy boards
var white: BoardType = 0;
var black: BoardType = 0;
for ([_]Chess.PE{ .P, .N, .B, .R, .Q, .K }) |piece| {
white |= @bitCast(BoardType, self.bitboards[piece.int()]);
}
for ([_]Chess.PE{ .p, .n, .b, .r, .q, .k }) |piece| {
black |= @bitCast(BoardType, self.bitboards[piece.int()]);
// make sure the move is valid (king is not in check)
self.occupancies[@enumToInt(Chess.Colors.white)] = @bitCast(BitBoard, white);
self.occupancies[@enumToInt(Chess.Colors.black)] = @bitCast(BitBoard, black);
}
{ // make sure the move is valid (king is not in check)
// FLIP SIDE
self.side = self.side.enemy();
return true;
}
},
.captures => {
if (move.capture) {
return self.makeMove(move, .all);