private void HashBlockers(int sqInd, bool rook) { ulong mask = SaveMask(sqInd, rook); int[] bitsArr = rook ? RBits : BBits; int bits = bitsArr[sqInd]; int combinations = 1 << bits; ulong[] blockers = new ulong[combinations]; ulong[] attacks = new ulong[combinations]; for (int i = 0; i < combinations; i++) { blockers[i] = GetBlockersByIndex(i, mask); attacks[i] = rook ? SlidingPieceUtils.GetRookAtt(sqInd, blockers[i]) : SlidingPieceUtils.GetBishopAtt(sqInd, blockers[i]); } ulong magic = rook ? rookMagics[sqInd] : bishopMagics[sqInd]; ulong[][] attacksTable = rook ? rookAttacksTable : bishopAttacksTable; attacksTable[sqInd] = new ulong[combinations]; for (int i = 0; i < combinations; i++) { ulong hashed = ApplyMagic(blockers[i], magic, bits); attacksTable[sqInd][hashed] = attacks[i]; } }
private ulong SaveMask(int sqInd, bool rook) { ulong mask; if (rook) { mask = rookMasks[sqInd] = SlidingPieceUtils.GetRookMask(sqInd); } else { mask = bishopMasks[sqInd] = SlidingPieceUtils.GetBishopMask(sqInd); } return(mask); }
private ulong FindMagic(int sqInd, bool rook, out ulong[] hashTable) { ulong mask = SaveMask(sqInd, rook); int[] bitsArr = rook ? RBits : BBits; int bits = bitsArr[sqInd]; int combinations = 1 << bits; ulong[] blockers = new ulong[combinations]; ulong[] attacks = new ulong[combinations]; hashTable = new ulong[combinations]; for (int i = 0; i < combinations; i++) { blockers[i] = GetBlockersByIndex(i, mask); attacks[i] = rook ? SlidingPieceUtils.GetRookAtt(sqInd, blockers[i]) : SlidingPieceUtils.GetBishopAtt(sqInd, blockers[i]); } for (int k = 0; k < 100000000; k++) { ulong magic = RandomUInt64FewBits(); ulong[] attacksTable = new ulong[combinations]; bool fail = false; for (int i = 0; i < combinations && !fail; i++) { ulong hashed = ApplyMagic(blockers[i], magic, bits); if (attacksTable[hashed] == 0) { attacksTable[hashed] = attacks[i]; } else if (attacksTable[hashed] != attacks[i]) { fail = true; } } if (!fail) { hashTable = attacksTable; return(magic); } } throw new Exception("Failed to find magic"); }