Given how Zobrist hashes work and that Zobrist is a mutable struct, it’s highly likely that mutation is the problem. The solution would be to either make Zobrist an immutable struct and adapt the code as needed or simply key the transposition table on the Zobrist value rather than the object.
Now that I look up Zobrist hashing, it doesn’t seem like a mutable object is necessary? I still don’t understand the algorithm at all, really.
For thoroughness, when a key is inserted, its index is computed by the hash function, and the index does not change. So if the key’s value changes in a way that also changes its hash value, you have a couple problems: 1) it cannot be used to find its own existing index, 2) another key with the previous value (and thus hash value) can be inserted.
I was really careful not to say mutable or immutable struct because 1) a mutable struct can have const fields or fixed properties like size(::Matrix), and the hash value is constant if it only depends on those, and 2) an immutable struct’s value and hash value can depend on a field holding a mutable instance e.g. many wrappers of mutable arrays are actually immutable structs.