XRCSCQWQKVYASIMAJO7JVUJXHXE44FZROCJPBW2BR7EE4RPEIBKAC
ARKJ6V5BZRW2R5WJHAFDCO5LEZDS75BFPSXWNKTQK4BYT4DCQGHQC
WAJ2J7G4QZE4LLGGZNIQ3ZIBCR3CSFOH3V2NIK2JQPALFHARRNMAC
RNEXG5IFDKMHSUR6RMNTI3Y32ORLVMZ6UJYKHLV2XBMT2QONBTVQC
X3FYJUNL5ORLRC7TW3C5OMNZOX4JEWL73RXOQZLRKLAUBVNARIMAC
2TRWSYAHRLVT2V6FGRNHKYQZKFDCMKMJOI2G3HYMOVLSJMGSBFDQC
HNCUAGWTMX3UHH2KFTUM3M6Q4CC33M6PVE5DWZWFG5UM2Y7J2ZKAC
FRUDIRWXGFOZERET3DNUNAZ5HSA3G32JZX6WMIXNGZOACTTCRIQAC
A46B5KNQFPTZEIL2JZKD2CQELGU3COE6FGTV2ABS5U7DVTVDGEBQC
TB4YBE4CMWCLSKJ43QF6IU5HVYUUO33BLXVG7XDRLJS3IFIBQLYAC
2CU67A3QXXPH722WBAL74O6P2N2RRXFBQVPT3A5QAXTUCQ3UUU5AC
WSRRWTTVBE2K6NKPS54CXMY3QYK5YTDRGEH3YJ53VQ2XW5UM5O2QC
FOORIA7SEZCLKDBNMV6KEDTQOJJVAH57BQFBRSQMET6FERJPHCVQC
WZNDXPQM23LLYDZ3ZCTB4GOVRJLL7PMSEPSYBVFX6AOTJOZ5YYZQC
ITBUR5DO3QNEPXLYLFZP2OZIRI4LJU66R3TAD3F4D3YPUR4E2VMQC
if (@bitCast(BitMoveType, gs.best_move) != 0) {
// loop over the pv_line
var count: usize = 0;
while (count < pv_length[0]) : (count += 1) {
// print PV move
pv_table[0][count].print();
std.debug.print(" ", .{});
}
std.debug.print("\n", .{});
if (@bitCast(BitMoveType, pv_table[0][0]) != 0) {
@tagName(gs.best_move.source),
@tagName(gs.best_move.target),
if (gs.best_move.prom != .none) @tagName(gs.best_move.prom) else "",
@tagName(pv_table[0][0].source),
@tagName(pv_table[0][0].target),
if (pv_table[0][0].prom != .none) @tagName(pv_table[0][0].prom) else "",
if (score > alpha) {
// PV (principal validation) node
alpha = score;
if (scr > alpha) {
// store history moves
if (!mp.move.capture) {
score.history_moves[@enumToInt(mp.move.piece)][@enumToInt(mp.move.target)] += depth;
}
// PV (principal valuation) node
alpha = scr;
{
// write PV move
pv_table[gs.ply][gs.ply] = mp.move;
// copy move from deeper ply into the current ply's line
var next: usize = gs.ply + 1;
while (next < pv_length[gs.ply + 1]) : (next += 1) {
pv_table[gs.ply][next] = pv_table[gs.ply + 1][next];
}
const std = @import("std");
const Chess = @import("Chess.zig");
const BitMove = @import("Board.zig").BitMove;
const BitMoveType = @import("Board.zig").BitMoveType;
const GameState = @import("Board.zig").GameState;
// This value is arbitrary
const KILLER_MAX = 64;
// These values are arbitrary, but only decreasing makes sense.
const CAPTURE_BOOST = 10_000;
const KILLER_FIRST = 9_000;
const KILLER_SECOND = 8_000;
pub fn Move(gs: *const GameState, 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)] + CAPTURE_BOOST;
} else {
// score 1st killer move
if (gs.ply < KILLER_MAX and
@bitCast(BitMoveType, killer_moves[0][gs.ply]) == @bitCast(BitMoveType, move))
{
return KILLER_FIRST;
}
// score 2nd killer move
else if (gs.ply < KILLER_MAX and
@bitCast(BitMoveType, killer_moves[1][gs.ply]) == @bitCast(BitMoveType, move))
{
return KILLER_SECOND;
}
// score history moves
else {
return @intCast(
isize,
history_moves[@enumToInt(move.piece)][@enumToInt(move.target)],
);
}
return 0;
}
return 0;
}
// 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]isize = .{
.{ 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 },
};
// Killer moves
pub var killer_moves: [2][KILLER_MAX]BitMove = .{
[_]BitMove{@bitCast(BitMove, @as(BitMoveType, 0))} ** KILLER_MAX,
[_]BitMove{@bitCast(BitMove, @as(BitMoveType, 0))} ** KILLER_MAX,
};
pub var history_moves: [12][64]usize = [_][64]usize{[_]usize{0} ** 64} ** 12;
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)];
}
return 0;
}
// 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 },
};
exe.linkLibCpp();
exe.addIncludePath("src/nnue");
exe.addCSourceFiles(&[_][]const u8{ "src/nnue/nnue.cpp", "src/nnue/misc.cpp" }, flags);
// exe.linkLibCpp();
// exe.addIncludePath("src/nnue");
// exe.addCSourceFiles(&[_][]const u8{ "src/nnue/nnue.cpp", "src/nnue/misc.cpp" }, flags);