const std = @import("std"); const BitMove = @import("Board.zig").BitMove; const BitMoveType = @import("Board.zig").BitMoveType; const Chess = @import("Chess.zig"); const Square = @import("Board.zig").Square; pub const Flag = enum { empty, exact, lower, upper, }; pub const Item = struct { key: u64, score: isize, best: BitMove, depth: u8, flag: Flag, }; pub const Table = struct { data: std.ArrayList(Item), size: usize, pub fn init(allocator: std.mem.Allocator, max_size: usize) !@This() { const size = max_size / @sizeOf(Item); var ret = std.ArrayList(Item).init(allocator); try ret.ensureTotalCapacity(size); ret.expandToCapacity(); return @This(){ .data = ret, .size = size, }; } pub fn deinit(self: @This()) void { self.data.deinit(); } pub fn clear(self: *@This()) void { for (self.data.items) |*item| { item.* = Item{ .key = 0, .score = 0, .best = @as(BitMove, @bitCast(@as(BitMoveType, 0))), .depth = 0, .flag = .empty, }; } } pub fn get(self: *const @This(), hash: u64) ?Item { const entry = self.data.items[hash % self.size]; if (entry.flag == .empty or entry.key != hash) { return null; } return entry; } pub fn set(self: *@This(), entry: Item) void { self.data.items[entry.key % self.size] = entry; } }; test "Transposition Table" { var tt = try Table.init(std.testing.allocator, 16 * (1 << 10)); defer tt.deinit(); tt.clear(); tt.set(Item{ .key = std.math.maxInt(u64), .score = 3000, .depth = 8, .flag = .exact, .best = @as(BitMove, @bitCast(@as(BitMoveType, 0))), }); const got = tt.get(std.math.maxInt(u64)); try std.testing.expect(got != null); try std.testing.expectEqual(got.?.score, 3000); }