Generating special magic numbers

135 views Asked by At

For context: https://www.chessprogramming.org/Looking_for_Magics are the magic numbers I am talking about

Hey, I would like to map availabilty of king attacks to low order 8 bits. For example, king's attack's on A1 would be (B1, A2, B2). Suppose I have a bitboard of only (A2, B2) I want to map it to 0b110. So it is really simple to do with PEXT instruction:

uint64_t map(uint64_t attacks, square sq) {
    return _pext_u64(attacks, KingAttacks[sq]);
}

But I want to support cpu's without pext. Here is my humble try:

static uint64_t use_magic(Bitboard bb, uint64_t factor, unsigned bits) {
    return (uint64_t(bb) * factor) >> (64 - bits);
}


static uint64_t FindKingMagic(Random& rand, Square sq) {

    const Bitboard attacks = KingAttacks[sq];

    for (;;) {
        const uint64_t factor = rand();
        uint8_t low_mask = 0;
        Bitboard perm = 0;
        bool ok = true;
        do {
            if (use_magic(perm, factor, 8) != low_mask) {
                ok = false;
                break;
            }
            // permute the 8-bit mask
            ++low_mask;
        // hover the bitboard to the next attack permutation
        } while ((perm = perm.permute(attacks)));

        if (ok) {
            return factor;
        }
    }

}

So for every loop iteration I generate a magic number and test if it generates the correct 8-bit mask for every permutation. If so, I succeded.

The problem is no matter how much time I give it, it never succedes, anyone got an idea?

Very possible is try to vectorize the function and make threads that work on it. But I heard that people generate magic numbers in fractions of a second, and this doesn't generate even in a minute, so I assume this is not correct.

Basically, I have 64 uint64_ts, would I would like to have a fast function to emulate PEXT. Anyone got an idea?

0

There are 0 answers