}
fn parseFEN(self: *@This(), in: []const u8) !void {
self.reset();
// std.debug.print("in: {s}\n", .{in});
// parse ranks
var rank: u6 = 0;
var file: u6 = 0;
var idx: usize = 0;
while (idx < in.len) : ({
idx += 1;
if (in[idx - 1] != '/') file += 1;
}) {
// std.debug.print("{c} {d}\n", .{ in[idx], rank * SIZE + file });
const ch = in[idx];
switch (ch) {
'/' => {
rank += 1;
file = 0;
},
'0'...'9' => {
file += try std.fmt.parseUnsigned(u6, in[idx .. idx + 1], 10) - 1;
},
65...90 => { // uppercase
self.occupancies[@enumToInt(Colors.white)].set(rank * SIZE + file);
switch (ch) {
'P' => self.bitboards[PE.P.int()].set(rank * SIZE + file),
'N' => self.bitboards[PE.N.int()].set(rank * SIZE + file),
'B' => self.bitboards[PE.B.int()].set(rank * SIZE + file),
'R' => self.bitboards[PE.R.int()].set(rank * SIZE + file),
'Q' => self.bitboards[PE.Q.int()].set(rank * SIZE + file),
'K' => self.bitboards[PE.K.int()].set(rank * SIZE + file),
else => unreachable,
}
},
97...122 => { // lowercase
self.occupancies[@enumToInt(Colors.black)].set(rank * SIZE + file);
switch (ch) {
'p' => self.bitboards[PE.p.int()].set(rank * SIZE + file),
'n' => self.bitboards[PE.n.int()].set(rank * SIZE + file),
'b' => self.bitboards[PE.b.int()].set(rank * SIZE + file),
'r' => self.bitboards[PE.r.int()].set(rank * SIZE + file),
'q' => self.bitboards[PE.q.int()].set(rank * SIZE + file),
'k' => self.bitboards[PE.k.int()].set(rank * SIZE + file),
else => unreachable,
}
},
' ' => break,
else => unreachable,
}
}
// parse rest
// std.debug.print("rest: {s}\n", .{in[idx..]});
var parts = std.mem.tokenize(u8, in[idx..], " ");
// side
const side = parts.next().?[0];
// std.debug.print("side: {c}\n", .{side});
switch (side) {
'w' => self.side = .white,
'b' => self.side = .black,
else => unreachable,
}
// castling
const castling = parts.next().?;
// std.debug.print("castling: {s}\n", .{castling});
for (castling) |ch| {
switch (ch) {
'K' => self.castling.WK = true,
'Q' => self.castling.WQ = true,
'k' => self.castling.BK = true,
'q' => self.castling.BQ = true,
'-' => break,
else => unreachable,
}
}
// enpassant
const enpassant = parts.next().?;
// std.debug.print("enpassant: {s}\n", .{enpassant});
if (enpassant[0] != '-') {
const f = enpassant[0] - 'a';
const r = SIZE - @intCast(u6, try std.fmt.parseUnsigned(u3, enpassant[1..], 10));
self.enpassant = @intToEnum(Square, r * SIZE + f);
}
return;