This will boil down a single number to a corresponding number of pieces per color so a perfect compression of all 12 std::popcount(PieceType)
Could be used to unroll each and every loop that usually is happening over the BB of a piece.
Useful for: templated loop unrolling at compiletime - a graph of functions that are templated and all call downward towards kK.
Code: Select all
Wpawn | Bpawn | 0..8 -> each of those can exist as nbrq
Wknight | Bknight | 0..2
Wbishop | Bbishop | 0..2
Wrook | Brook | 0..2
Wqueen | Bqueen | 0..1
Wking | Bking | 1
Quick implementation:
Code: Select all
#define loop(var, cnt) for(int var = 0; var < cnt; var++) {
#define loop2(var, cnt) loop(B##var, cnt) loop(W##var, cnt)
#define loopEnd }}}}}}}}}}
struct PieceConfig
{
int Wpawn, Wknight, Wbishop, Wrook, Wqueen;
int Bpawn, Bknight, Bbishop, Brook, Bqueen;
bool valid(int pawns, int knights, int bishops, int rooks, int queens)
{
int total = pawns + knights + bishops + rooks + queens;
if (total > 15) return false;
int c_knigths = std::max(knights - 2, 0);
int c_bishops = std::max(bishops - 2, 0);
int c_rooks = std::max(rooks - 2, 0);
int c_queens = std::max(queens - 1, 0);
int c_total = c_knigths + c_bishops + c_rooks + c_queens;
int c_available = std::max(8 - pawns, 0);
if (c_total > c_available) return false;
return true;
}
bool valid()
{
return valid(Wpawn, Wknight, Wbishop, Wrook, Wqueen) && valid(Bpawn, Bknight, Bbishop, Brook, Bqueen);
}
auto operator<=> (const PieceConfig& cmp) const = default;
};
uint64_t PieceNums()
{
std::set<PieceConfig> cfgs;
loop2(knight, 10)
loop2(bishop, 10)
loop2(rook, 10)
loop2(queen, 9)
loop2(pawn, 8)
//Each pawn can also exist as nbrq
PieceConfig cfg
{
Wpawn, Wknight, Wbishop, Wrook, Wqueen,
Bpawn, Bknight, Bbishop, Brook, Bqueen
};
if (cfg.valid())
{
cfgs.insert(cfg);
}
loopEnd
return cfgs.size();
}
int main()
{
std::cout << PieceNums() << "\n";
}
73256481
I did a statistic of how many 2000 Elo or above games actually contain many pieces. The answer is this:
2 queens, 2 bishops, 2 rooks, 2 knight 99,9828215%
Result max 2 queens:
16384
So a single 14 bit number would be able to resolve all popcounts of the 12 pieces that can exist on the board for 99,98% of all games in a single lookup.
Now I did not find 73256481 referenced anyhwere so is the math correct here?