Yes that is what I was looking for, ty.odomobo wrote: ↑Tue Apr 30, 2019 9:01 pm Actually, something I just realized is that c++ doesn't like the notation for pointers to normal arrays, so std::array will help us out here. Maybe there's a way to do it, but if so it's beyond me.
Let me know if you have any questionsCode: Select all
// These are vectors for the bishop. Ex: mvsNW[A1][0] is the number of squares. [A1][1-7] are the to squares. // Note that we have to declare the dimensions in reverse order, since we're explicitly nesting the types std::array<std::array<u08, 8>, 64> mvsNW; std::array<std::array<u08, 8>, 64> mvsNE; std::array<std::array<u08, 8>, 64> mvsSE; std::array<std::array<u08, 8>, 64> mvsSW; // This is an array of pointers to the above arrays. // Note that this is storing the exact same pointer as befores, but now it's preserving type information. // We could have mvsB itself be a std::array, but it's not necessary. std::array<std::array<u08, 8>, 64> * mvsB[] = { &mvsNW, &mvsNE, &mvsSW, &mvsSE }; // In this code I declare unsigned char *ptr and in line 4 it is assigned each array address by a for loop // Then It is used with pointer arithmetic. But, I thought it would be possible to use it as an array name as in ptr[fs][j] void WBf(threadS *t, u08 id, u08 depth, moveS *m) { unsigned char *ptr = &t->inv[id][t->top[id]]; m->fs = t->sqr[id]; if (*ptr) WSBBG(t, id, m->fs, ptr, &t->stk[id][t->top[id]]); for (u08 i = 0; i < 4; i++) { // Why are we dereferencing, and then holding a reference to the underlying array object? Why not leave it as a pointer? // Because otherwise we'd need to explicitly deference like this: // (*mvs)[m->fs][j] // BTW, if we just dereferenced, but didn't hold a reference, semantically we're asking the compiler to copy the contents of the array onto the stack. auto & mvs = *mvsB[i]; for (u08 j = 1; j <= mvs[m->fs][0]; j++) { m->ts = mvs[m->fs][j]; m->id = t->brd[m->ts]; m->typ = (m->id) ? WBC : WBM; MakeMove(t, m); if (depth > 0) Perft(t, depth - 1); TakeBack(t, m); } } }
"(*mvs)[m->fs][j]"
I believe that this notation is what I could not remember.
However, if it works, I like the std::array as it is very precise and writing "mvs[m->fs][0]" is so much more natural than writing "*(ptr + ((m->fs << 3) + j))". And of course less error prone.
If it is possible with natural arrays I'm thinking maybe a typedef can be used.
typedef unsigned char array[64][8];
array *mvsB [] = { &mvsNW, ...
array * mvs = mvsB;
Or something close. Because something similar works for functions!
typedef void MGt(threadS *, u08 id, u08 depth, moveS *);
MGt WPf, WNf, WBf, WRf, WQf, WKf, WSf, WLf, BPf, BNf, BBf, BRf, BQf, BKf, BSf, BLf;
MGt *MGf[] = { WPf, WPf, WNf, WBf, WRf, WQf, WKf, WSf, WLf, BPf, BPf, BNf, BBf, BRf, BQf, BKf, BSf, BLf };
void Perft(threadS *t, u08 depth) {
u08 id = t->wtm ? 19 : 39, typ;
id = t->nxt[id];
do {
typ = t->typ[id];
MGf[typ](t, id, depth, &t->moves[t->ply]);
} while ((id = t->nxt[id]));
}
But, idk and my intuition is not always right.