Instead of maintaing 4 Bitboards we just maintain 2. One for the normal occupancy and one for the rotated occupancy meaning sq = sq ^ 63.
That is we have the normal occ and we have the bitrotated rev_occ at all times.
Now I gave my sifter these symbols:
Code: Select all
//Scalars
1ull;
2ull;
56ull;
sq;
occ;
rev_occ;
//Unary Func
std::popcount(arg0);
std::countl_zero(arg0);
std::countr_zero(arg0);
bit_reverse(arg0);
//Binary func
(arg0 | arg1);
(arg0 & ~arg1);
(arg0 ^ arg1);
(arg0 - arg1);
(arg0 << arg1);
(arg0 >> arg1);
Here is all the solutions for the 4 rays in chess:
Code: Select all
SOLVE HO:
Solution Found : (occ ^ (occ - 1ull)) #19788
Solution Found : (occ ^ (occ - 2ull)) #85324
Solution Found : ((occ - 1ull) ^ occ) #263388
Solution Found : ((occ - 2ull) ^ occ) #267484
Solution Found : (occ ^ ((occ &~ 1ull) - 1ull)) #310604
Solution Found : ((occ ^ (occ - 1ull)) | 1ull) #316618
Solution Found : ((occ ^ (occ - 1ull)) &~ 1ull) #316619
Solution Found : ((occ ^ (occ - 1ull)) ^ 1ull) #316620
Solution Found : ((occ ^ (occ - 1ull)) - 1ull) #316621
Solution Found : (bit_reverse(rev_occ) ^ (occ - 1ull)) #316828
Solution Found : (occ ^ ((occ - 1ull) | 1ull)) #318028
Solution Found : (occ ^ ((occ - 1ull) &~ 1ull)) #318284
Solution Found : (occ ^ ((occ - 1ull) ^ 1ull)) #318540
Solution Found : (occ ^ ((occ - 1ull) - 1ull)) #318796
Solution Found : (occ ^ (bit_reverse(rev_occ) - 1ull)) #367948
Solution Found : (occ ^ (occ - popcount(1ull))) #413004
Solution Found : (occ ^ (occ - (1ull | 1ull))) #675148
Solution Found : (occ ^ (occ - (1ull << 1ull))) #937292
Solution Found : (occ ^ (occ - 1ull)) #1068364
Solution Found : (occ ^ (occ - 2ull)) #1133900
Solution Found : ((occ - 1ull) ^ occ) #1311964
Solution Found : ((occ - 2ull) ^ occ) #1316060
Solution Found : ((occ ^ (occ - 2ull)) | 1ull) #1365194
Solution Found : ((occ ^ (occ - 2ull)) &~ 1ull) #1365195
Solution Found : ((occ ^ (occ - 2ull)) ^ 1ull) #1365196
Solution Found : (bit_reverse(rev_occ) ^ (occ - 2ull)) #1365404
Solution Found : (occ ^ ((occ - 2ull) | 1ull)) #1366604
Solution Found : (occ ^ ((occ - 2ull) &~ 1ull)) #1366860
Solution Found : (occ ^ ((occ - 2ull) ^ 1ull)) #1367116
Solution Found : (occ ^ (bit_reverse(rev_occ) - 2ull)) #1416524
Solution Found : (occ ^ (occ - popcount(2ull))) #1461580
Solution Found : (occ ^ (occ - countr_zero(2ull))) #1592652
SOLVE VE:
Solution Found : ((occ - 1ull) << 1ull) #1246
Solution Found : ((occ << 1ull) - 1ull) #1261
Solution Found : ((occ - 2ull) << 1ull) #5342
Solution Found : ((occ << 2ull) - 1ull) #5357
Solution Found : ((occ - 56ull) << 1ull) #9438
Solution Found : (((occ &~ 1ull) - 1ull) << 1ull) #19422
Solution Found : (((occ &~ 1ull) << 1ull) - 1ull) #19437
Solution Found : (occ ^ (occ - 1ull)) #19788
Solution Found : (((occ - 1ull) | 1ull) << 1ull) #19886
Solution Found : (((occ - 1ull) &~ 1ull) << 1ull) #19902
Solution Found : (((occ - 1ull) ^ 1ull) << 1ull) #19918
Solution Found : (((occ - 1ull) - 1ull) << 1ull) #19934
Solution Found : (((occ - 1ull) << 1ull) | 1ull) #19946
Solution Found : (((occ - 1ull) << 1ull) &~ 1ull) #19947
Solution Found : (((occ - 1ull) << 1ull) ^ 1ull) #19948
Solution Found : (((occ - 1ull) << 1ull) - 1ull) #19949
Solution Found : (((occ - 1ull) << 1ull) << 1ull) #19950
Solution Found : (((occ << 1ull) &~ 1ull) - 1ull) #20157
Solution Found : (((occ << 1ull) - 1ull) | 1ull) #20186
Solution Found : (((occ << 1ull) - 1ull) &~ 1ull) #20187
Solution Found : (((occ << 1ull) - 1ull) ^ 1ull) #20188
Solution Found : (((occ << 1ull) - 1ull) - 1ull) #20189
Solution Found : (((occ << 1ull) - 1ull) << 1ull) #20190
Solution Found : (((occ << 1ull) << 1ull) - 1ull) #20205
Solution Found : ((bit_reverse(rev_occ) - 1ull) << 1ull) #23006
Solution Found : ((bit_reverse(rev_occ) << 1ull) - 1ull) #23021
Solution Found : (bit_reverse((rev_occ >> 1ull)) - 1ull) #24477
Solution Found : ((occ - popcount(1ull)) << 1ull) #25822
Solution Found : ((occ << popcount(1ull)) - 1ull) #25837
Solution Found : ((occ - countl_zero(1ull)) << 1ull) #29918
Solution Found : ((occ - (1ull | 1ull)) << 1ull) #42206
Solution Found : ((occ << (1ull | 1ull)) - 1ull) #42221
SOLVE D1:
Solution Found : ((occ - 1ull) << 1ull) #1246
Solution Found : ((occ << 1ull) - 1ull) #1261
Solution Found : ((occ - 2ull) << 1ull) #5342
Solution Found : ((occ << 2ull) - 1ull) #5357
Solution Found : ((occ - 56ull) << 1ull) #9438
Solution Found : (((occ &~ 1ull) - 1ull) << 1ull) #19422
Solution Found : (((occ &~ 1ull) << 1ull) - 1ull) #19437
Solution Found : (occ ^ (occ - 1ull)) #19788
Solution Found : (((occ - 1ull) | 1ull) << 1ull) #19886
Solution Found : (((occ - 1ull) &~ 1ull) << 1ull) #19902
Solution Found : (((occ - 1ull) ^ 1ull) << 1ull) #19918
Solution Found : (((occ - 1ull) - 1ull) << 1ull) #19934
Solution Found : (((occ - 1ull) << 1ull) | 1ull) #19946
Solution Found : (((occ - 1ull) << 1ull) &~ 1ull) #19947
Solution Found : (((occ - 1ull) << 1ull) ^ 1ull) #19948
Solution Found : (((occ - 1ull) << 1ull) - 1ull) #19949
Solution Found : (((occ - 1ull) << 1ull) << 1ull) #19950
Solution Found : (((occ << 1ull) &~ 1ull) - 1ull) #20157
Solution Found : (((occ << 1ull) - 1ull) | 1ull) #20186
Solution Found : (((occ << 1ull) - 1ull) &~ 1ull) #20187
Solution Found : (((occ << 1ull) - 1ull) ^ 1ull) #20188
Solution Found : (((occ << 1ull) - 1ull) - 1ull) #20189
Solution Found : (((occ << 1ull) - 1ull) << 1ull) #20190
Solution Found : (((occ << 1ull) << 1ull) - 1ull) #20205
Solution Found : ((bit_reverse(rev_occ) - 1ull) << 1ull) #23006
Solution Found : ((bit_reverse(rev_occ) << 1ull) - 1ull) #23021
Solution Found : (bit_reverse((rev_occ >> 1ull)) - 1ull) #24477
Solution Found : ((occ - popcount(1ull)) << 1ull) #25822
Solution Found : ((occ << popcount(1ull)) - 1ull) #25837
Solution Found : ((occ - countl_zero(1ull)) << 1ull) #29918
Solution Found : ((occ - (1ull | 1ull)) << 1ull) #42206
Solution Found : ((occ << (1ull | 1ull)) - 1ull) #42221
SOLVE D2:
Solution Found : ((occ - 1ull) << 1ull) #1246
Solution Found : ((occ << 1ull) - 1ull) #1261
Solution Found : ((occ - 2ull) << 1ull) #5342
Solution Found : ((occ << 2ull) - 1ull) #5357
Solution Found : ((occ - 56ull) << 1ull) #9438
Solution Found : ((occ - sq) << 1ull) #13534
Solution Found : (((occ &~ 1ull) - 1ull) << 1ull) #19422
Solution Found : (((occ &~ 1ull) << 1ull) - 1ull) #19437
Solution Found : (occ ^ (occ - 1ull)) #19788
Solution Found : (((occ - 1ull) | 1ull) << 1ull) #19886
Solution Found : (((occ - 1ull) &~ 1ull) << 1ull) #19902
Solution Found : (((occ - 1ull) ^ 1ull) << 1ull) #19918
Solution Found : (((occ - 1ull) - 1ull) << 1ull) #19934
Solution Found : (((occ - 1ull) << 1ull) | 1ull) #19946
Solution Found : (((occ - 1ull) << 1ull) &~ 1ull) #19947
Solution Found : (((occ - 1ull) << 1ull) ^ 1ull) #19948
Solution Found : (((occ - 1ull) << 1ull) - 1ull) #19949
Solution Found : (((occ - 1ull) << 1ull) << 1ull) #19950
Solution Found : (((occ << 1ull) &~ 1ull) - 1ull) #20157
Solution Found : (((occ << 1ull) - 1ull) | 1ull) #20186
Solution Found : (((occ << 1ull) - 1ull) &~ 1ull) #20187
Solution Found : (((occ << 1ull) - 1ull) ^ 1ull) #20188
Solution Found : (((occ << 1ull) - 1ull) - 1ull) #20189
Solution Found : (((occ << 1ull) - 1ull) << 1ull) #20190
Solution Found : (((occ << 1ull) << 1ull) - 1ull) #20205
Solution Found : ((bit_reverse(rev_occ) - 1ull) << 1ull) #23006
Solution Found : ((bit_reverse(rev_occ) << 1ull) - 1ull) #23021
Solution Found : (bit_reverse((rev_occ >> 1ull)) - 1ull) #24477
Solution Found : ((occ - popcount(1ull)) << 1ull) #25822
Solution Found : ((occ << popcount(1ull)) - 1ull) #25837
Solution Found : ((occ - countl_zero(1ull)) << 1ull) #29918
Solution Found : ((occ - (1ull | 1ull)) << 1ull) #42206
occ := occ & mask
rev_occ := occ' & mask
General Solution (set intersection of all possible solutions): POSITIVE
(occ ^ (occ - 1ull)) & mask
For good measure here is the negative ray:
General Solution (set intersection of all possible solutions): NEGATIVE
bit_reverse((rev_occ ^ (rev_occ - 1ull)) & mask)
Now you can imagine that the bit reversal is not needed because we need this perspective as well. For the cost of a single OR and XOR per move get something unique. What that means in terms of nps compared to other approaches I cannot say yet.
Self analysis:
This is Hyperbola qsc for a single line:
Code: Select all
uint64_t o = pieces & mask;
return ((o - (1ull << x)) ^ bit_bswap(bit_bswap(o) - (1ull << (x ^ 56)))) & mask;
Code: Select all
uint64_t h = occ & r.ho; uint64_t H = occ & r.HO;
return ((h ^ (h - 1ull)) & r.ho) | bit_rotate((H ^ (H - 1ull)) & r.HO);
This is actually a trend I see continuing. When making chesscode exponentially faster the first thing that goes is conditional code, the second thing that goes is the work on single uint64_t's either we work on them in bulk via YMM or we maintain a bigger board structure that enables additional shortcuts. Either way maintining color agnosticity has more advantages than people realize yet and above code becomes INSANE when we work with YMM registers since all 4 rays in 8 directions of a queen can be solved forward and reverse order like this:
Code: Select all
//Bulk of the work with AVX2
u64x4 shvxy = (hvxy ^ (hvxy - one)) & dirs;
u64x4 SHVXY = (HVXY ^ (HVXY - one)) & DIRS; //to be reversed