FRUDIRWXGFOZERET3DNUNAZ5HSA3G32JZX6WMIXNGZOACTTCRIQAC
JEBZTHJHLCZETHYCCY26KUGG4IJMALL5H3L2VO4Z4FDV7V5X3IJQC
2TRWSYAHRLVT2V6FGRNHKYQZKFDCMKMJOI2G3HYMOVLSJMGSBFDQC
X3FYJUNL5ORLRC7TW3C5OMNZOX4JEWL73RXOQZLRKLAUBVNARIMAC
RNEXG5IFDKMHSUR6RMNTI3Y32ORLVMZ6UJYKHLV2XBMT2QONBTVQC
G4HJL4QLASCZBWYGCEXYYRBYL7UVX6ENELHRRBFB5UAXXGVVGZGQC
A46B5KNQFPTZEIL2JZKD2CQELGU3COE6FGTV2ABS5U7DVTVDGEBQC
46RTAHPCLRHCLSYGKZIFIFRIWPJ54TJJ2WM5M5FZNNHUSZZZZAYQC
FOORIA7SEZCLKDBNMV6KEDTQOJJVAH57BQFBRSQMET6FERJPHCVQC
DKK2G2S3X7KFEJBHGLUEVTBBW6UBR36XR7ZBUWG5GO6JYXWGJOOAC
EHBLDMND5ASGZTTLDLEA5RGQIAZTXZN4HBPGD5PB6FDGZGTJ33SQC
XCZABYMDLHLHXNTHZFCXPNP6VOCNYUROAQACE5SWBL5FJK2EB7WQC
BL3ZR4OWJM54HFXUNMUZKB5YQYVBT7ETFIXCOXWL6S5SZFM6IFDQC
7SQSGQOZRCHN3GGWPNFI36K2R7YZMOPXZP3FP4PYDDOZML5YIYOQC
JPK7SJDQWLCNDXJQEQQHXBN4Y677BPQ5QBL55GRZ55RSP4GK4L4AC
TB4YBE4CMWCLSKJ43QF6IU5HVYUUO33BLXVG7XDRLJS3IFIBQLYAC
2CU67A3QXXPH722WBAL74O6P2N2RRXFBQVPT3A5QAXTUCQ3UUU5AC
THYIOCFC72V4ZMTLMGRGRIBARXT2LPSQCL2XNOIBI22QRVYUMIYQC
XHCMZF25YBLNQLVKKBJJWWJ3G24VFUSLE3LAT2DRWL52RJX4Z3EAC
test "bestMove" {
var gs = try GameState.init(std.testing.allocator, null);
gs.show();
std.debug.print("{s}", .{bestMove(&gs, 4)});
}
std.debug.print("{s}\n", .{search.bestMove(&gs, 3)});
} else try handleUCI();
var moves = Board.MoveList.init(arena.allocator(), {});
defer moves.deinit();
try gs.generateMoves(&moves);
while (moves.removeOrNull()) |mp| {
mp.move.show();
std.debug.print("{d}\n", .{mp.score});
}
} else try handleUCI(arena.allocator());
const Game = struct {
state: Board.GameState,
history: std.ArrayList(Board.BitMove),
fn init(allocator: std.mem.Allocator) @This() {
var game: Game = undefined;
game.state = Board.GameState.init(null) catch unreachable;
game.history = std.ArrayList(Board.BitMove).init(allocator);
return game;
}
fn deinit(self: @This()) void {
self.history.deinit();
}
};
test "Game" {
var game = Game.init(std.testing.allocator);
defer game.deinit();
}
pub fn init(FEN: ?Str) !@This() {
var gs = GameState{ .attacks = Attacks.init() };
pub fn init(allocator: std.mem.Allocator, FEN: ?Str) !@This() {
var gs = GameState{ .allocator = allocator, .attacks = Attacks.init() };
try ml.append(BitMove{
.source = @intToEnum(Square, source_square),
.target = @intToEnum(Square, target_square),
.piece = piece,
});
{
const move = BitMove{
.source = @intToEnum(Square, source_square),
.target = @intToEnum(Square, target_square),
.piece = piece,
};
try ml.add(.{ .move = move, .score = self.scoreMove(move) });
}
}
}
pub fn scoreMove(gs: @This(), move: BitMove) isize {
if (move.capture) {
var target_piece = Chess.PE.P; // this could be p as well
const pieces = switch (gs.side) {
.white => &[_]Chess.PE{ .P, .N, .B, .R, .Q, .K },
.black => &[_]Chess.PE{ .p, .n, .b, .r, .q, .k },
};
for (pieces) |piece| {
if (gs.bitboards[@enumToInt(piece)].isSet(move.target)) {
target_piece = piece;
break;
}
}
return MVV_LVA[@enumToInt(move.piece)][@enumToInt(target_piece)];
// most valuable victim & less valuable attacker
// (Victims) Pawn Knight Bishop Rook Queen King
// (Attackers)
// Pawn 105 205 305 405 505 605
// Knight 104 204 304 404 504 604
// Bishop 103 203 303 403 503 603
// Rook 102 202 302 402 502 602
// Queen 101 201 301 401 501 601
// King 100 200 300 400 500 600
// MVV LVA [attacker][victim]
const MVV_LVA: [12][12]u10 = .{
.{ 105, 205, 305, 405, 505, 605, 105, 205, 305, 405, 505, 605 },
.{ 104, 204, 304, 404, 504, 604, 104, 204, 304, 404, 504, 604 },
.{ 103, 203, 303, 403, 503, 603, 103, 203, 303, 403, 503, 603 },
.{ 102, 202, 302, 402, 502, 602, 102, 202, 302, 402, 502, 602 },
.{ 101, 201, 301, 401, 501, 601, 101, 201, 301, 401, 501, 601 },
.{ 100, 200, 300, 400, 500, 600, 100, 200, 300, 400, 500, 600 },
.{ 105, 205, 305, 405, 505, 605, 105, 205, 305, 405, 505, 605 },
.{ 104, 204, 304, 404, 504, 604, 104, 204, 304, 404, 504, 604 },
.{ 103, 203, 303, 403, 503, 603, 103, 203, 303, 403, 503, 603 },
.{ 102, 202, 302, 402, 502, 602, 102, 202, 302, 402, 502, 602 },
.{ 101, 201, 301, 401, 501, 601, 101, 201, 301, 401, 501, 601 },
.{ 100, 200, 300, 400, 500, 600, 100, 200, 300, 400, 500, 600 },
};