GZPVUGLJGD3VGLIK7JDABQ24E5SWN5CYRDGI6PIAFZ2BIMRDMANQC YVNKHIU4ENET52Y5BD5WFA23EVTQ4ZQQLIAZRRA4AN44TXUTNRCQC BL3ZR4OWJM54HFXUNMUZKB5YQYVBT7ETFIXCOXWL6S5SZFM6IFDQC TDHJSFFSJZBEZFMDHPLRSVB6CIVJ7AWGGNIC3WUCADQLQSIQKXDAC SNMQLFZFCV5XTPRLSD7SV4RPVOGUVJOYCZAKI5ATCEPSI5JMGVAAC XARNBDT4A5X6F3WFC5YNZBV5RNZ5GBRYOWKAK5R6HSTPBNIXTHDAC FR6N5DIUYYWT5BBOIBOX3GCSEKZIINSGT4F4CWM6YA2XLQEOU4ZQC }return attacks;}fn attackWithBlocker(blocks: Chess.BoardType, square: Chess.Square, piece: Chess.Pieces) Chess.BoardType {const rank = @intCast(isize, square.rank());const file = @intCast(isize, square.file());const moves = switch (piece) {.bishop => [_][2]i3{.{ -1, -1 },.{ -1, 1 },.{ 1, -1 },.{ 1, 1 },},.rook => [_][2]i3{.{ -1, 0 },.{ 1, 0 },.{ 0, -1 },.{ 0, 1 },},else => unreachable,};var attacks: Chess.BoardType = 0;for (moves) |m| {var step: i5 = 1;while (step < Chess.SIZE) : (step += 1) {const dr = rank + m[0] * step;const df = file + m[1] * step;if (m[0] > 0 and dr > 7) break;if (m[0] < 0 and dr < 0) break;if (m[1] > 0 and df > 7) break;if (m[1] < 0 and df < 0) break;const s = @intCast(u6, dr * Chess.SIZE + df);const mask = @intCast(Chess.BoardType, @as(Chess.BoardType, 1) << s);attacks |= mask;// stop when we hit a blockerif (mask & blocks != 0) break;}
try std.testing.expectEqual(bb.board, got);}{ // rook d4bb.board = 0;bb.setSlice(&[_]Chess.Square{ .b4, .d3, .d5 });const got = attackWithBlocker(bb.board, .d4, .rook);bb.board = 0;bb.setSlice(&[_]Chess.Square{ .c4, .b4, .d3, .d5, .e4, .f4, .g4, .h4 });try std.testing.expectEqual(bb.board, got);}{ // rook h8bb.board = 0;bb.setSlice(&[_]Chess.Square{.b8});const got = attackWithBlocker(bb.board, .h8, .rook);bb.board = 0;bb.setSlice(&[_]Chess.Square{ .b8, .c8, .d8, .e8, .f8, .g8, .h7, .h6, .h5, .h4, .h3, .h2, .h1 });try std.testing.expectEqual(bb.board, got);}}
}pub fn riderBlocker(self: @This(), square: Square, piece: Pieces) BoardType {const rank = @intCast(isize, square.rank());const file = @intCast(isize, square.file());const moves = switch (piece) {.bishop => [_][2]i3{.{ -1, -1 },.{ -1, 1 },.{ 1, -1 },.{ 1, 1 },},.rook => [_][2]i3{.{ -1, 0 },.{ 1, 0 },.{ 0, -1 },.{ 0, 1 },},else => unreachable,};var blockers: BoardType = 0;for (moves) |m| {var step: i5 = 1;while (step < SIZE) : (step += 1) {const dr = rank + m[0] * step;const df = file + m[1] * step;if (m[0] > 0 and dr > 7) break;if (m[0] < 0 and dr < 0) break;if (m[1] > 0 and df > 7) break;if (m[1] < 0 and df < 0) break;const s = @intCast(u6, dr * SIZE + df);const mask = @intCast(BoardType, @as(BoardType, 1) << s);blockers |= mask;// stop when we hit a blockerif (mask & self.board != 0) break;}}return blockers;
test "riderBlocker" {var bb: BitBoard = .{};{ // bishop d4bb.board = 0;bb.setSlice(&[_]Square{ .c3, .b6, .f2 });const got = bb.riderBlocker(.d4, .bishop);bb.board = 0;bb.setSlice(&[_]Square{ .c3, .f2, .e3, .c5, .b6, .e5, .f6, .g7, .h8 });try std.testing.expectEqual(bb.board, got);}{ // rook d4bb.board = 0;bb.setSlice(&[_]Square{ .b4, .d3, .d5 });const got = bb.riderBlocker(.d4, .rook);bb.board = 0;bb.setSlice(&[_]Square{ .c4, .b4, .d3, .d5, .e4, .f4, .g4, .h4 });try std.testing.expectEqual(bb.board, got);}{ // rook h8bb.board = 0;bb.setSlice(&[_]Square{.b8});const got = bb.riderBlocker(.h8, .rook);bb.board = 0;bb.setSlice(&[_]Square{ .b8, .c8, .d8, .e8, .f8, .g8, .h7, .h6, .h5, .h4, .h3, .h2, .h1 });try std.testing.expectEqual(bb.board, got);}}