Chess engine in zig
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);
}