I found a bug in the JS representation of the evaluation.
Let's take a position to examine.
[d]8/5k2/8/6p1/7p/8/6N1/4K3 w - - 1 66
The point is that the code wants to check the passed h4-pawn for a "Passed block."
Code: Select all
function passed_block(pos, square) {
if (square == null) return sum(pos, passed_block);
if (!passed_leverable(pos, square)) return 0;
if (rank(pos, square) < 4) return 0;
if (board(pos, square.x, square.y - 1) != "-") return 0;
var r = rank(pos, square) - 1;
var w = r > 2 ? 5 * r - 13 : 0;
var pos2 = colorflip(pos);
var defended = 0, unsafe = 0, wunsafe = 0, defended1 = 0, unsafe1 = 0;
for (var y = square.y - 1; y >= 0; y--) {
if (attack(pos, {x:square.x,y:y})) defended++;
if (attack(pos2, {x:square.x,y:7-y})) unsafe++;
if (attack(pos2, {x:square.x-1,y:7-y})) wunsafe++;
if (attack(pos2, {x:square.x+1,y:7-y})) wunsafe++;
if (y == square.y - 1) {
defended1 = defended;
unsafe1 = unsafe;
}
}
for (var y = square.y + 1; y < 8; y++) {
if (board(pos, square.x, y) == "R"
|| board(pos, square.x, y) == "Q") defended1 = defended = square.y;
if (board(pos, square.x, y) == "r"
|| board(pos, square.x, y) == "q") unsafe1 = unsafe = square.y;
}
var k = (unsafe == 0 && wunsafe == 0 ? 35 : unsafe == 0 ? 20 : unsafe1 == 0 ? 9 : 0)
+ (defended1 != 0 ? 5 : 0);
return k * w;
}
Code: Select all
if (attack(pos2, {x:square.x+1,y:7-y})) wunsafe++;Code: Select all
function attack(pos, square) {
if (square == null) return sum(pos, attack);
var v = 0;
v += pawn_attack(pos, square);
v += king_attack(pos, square);
v += knight_attack(pos, square);
v += bishop_xray_attack(pos, square);
v += rook_xray_attack(pos, square);
v += queen_attack(pos, square);
return v;
}Code: Select all
v += knight_attack(pos, square);Code: Select all
function knight_attack(pos, square, s2) {
if (square == null) return sum(pos, knight_attack);
var v = 0;
for (var i = 0; i < 8; i++) {
var ix = ((i > 3) + 1) * (((i % 4) > 1) * 2 - 1);
var iy = (2 - (i > 3)) * ((i % 2 == 0) * 2 - 1);
var b = board(pos, square.x + ix, square.y + iy);
if (b == "N"
&& (s2 == null || s2.x == square.x + ix && s2.y == square.y + iy)
&& !pinned(pos, {x:square.x + ix, y:square.y + iy})) v++;
}
return v;
}Code: Select all
function board(pos, x, y) {
if (x >= 0 && x <= 7 && y >= 0 && y <= 7) return pos.b[x][y];
return "x";
}
The code includes a separate function to check for going off the board.
Code: Select all
function bounds(x, y) {
return x >= 0 && x <= 7 && y >= 0 && y <= 7;
}Code: Select all
if (attack(pos2, {x:square.x-1,y:7-y})) wunsafe++;
if (attack(pos2, {x:square.x+1,y:7-y})) wunsafe++;Code: Select all
passed_block()If the historical legacy of the core engine matters to anyone, then shouldn't it be fixed?