I think I have to ask you this questionmcostalba wrote:I still don't understand why if
then, in the actual encoding, we use it in this wayCode: Select all
LeadPawnIdx[leadPawnsCnt - 1][mappedLeadSq] = idx;
instead ofCode: Select all
idx = LeadPawnIdx[leadPawnsCnt - 1][23 - MapToEdges[squares[0]] / 2];
Code: Select all
idx = LeadPawnIdx[leadPawnsCnt - 1][MapToEdges[squares[0]]];

The original code reads as follows:
Code: Select all
idx = pawnidx[t][flap[pos[0]]];
Code: Select all
static const ubyte flap[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 6, 12, 18, 18, 12, 6, 0,
1, 7, 13, 19, 19, 13, 7, 1,
2, 8, 14, 20, 20, 14, 8, 2,
3, 9, 15, 21, 21, 15, 9, 3,
4, 10, 16, 22, 22, 16, 10, 4,
5, 11, 17, 23, 23, 17, 11, 5,
0, 0, 0, 0, 0, 0, 0, 0
};
Code: Select all
static const ubyte ptwist[] = {
0, 0, 0, 0, 0, 0, 0, 0,
47, 35, 23, 11, 10, 22, 34, 46,
45, 33, 21, 9, 8, 20, 32, 44,
43, 31, 19, 7, 6, 18, 30, 42,
41, 29, 17, 5, 4, 16, 28, 40,
39, 27, 15, 3, 2, 14, 26, 38,
37, 25, 13, 1, 0, 12, 24, 36,
0, 0, 0, 0, 0, 0, 0, 0
};
The reason I change the order in ptwist[] compared to flap[] is that this allows me to place the non-leading pawns in (renumbered) squares 0 to ptwist[square_of_leading_pawn]-1.
A recurring trick in the encoding function is this. I have k like pieces (same color, same type) that can be in n (remapped) squares 0 to n-1. The number of possibilities for this is Bin(n, k), which is basic combinatorics. But how to find an actual mapping of sets of squares s_1, ...., s_k to a number in 0...Bin(n,k)-1? There is a surprisingly easy formula. First sort the squares to get 0 <= s_1 < s_2 < ... < s_k < n (this is critical). Now the formula is:
Code: Select all
idx = Bin(s_1, 1) + Bin(s_2, 2) + ... + Bin(s_k, k).
I noticed that you moved the step of sorting on ptwist[] / MapToEdges[] to before the horizontal flip. I think that will lead to problems if two non-leading pawns are in symmetric positions, because their positions now have to be swapped. You wrote:
Code: Select all
// Encode leading pawns. Note that any previous horizontal flip preserves
// the order because MapToEdges[] is (almost) flip invariant.
Even if it did not crash, any change in the indexing scheme would need a corresponding change in the generator (and a regeneration of all tables).P.S: I have tried the latter: it crashes.