diff options
| author | tslil clingman <tslil@posteo.de> | 2021-01-26 23:54:46 -0500 |
|---|---|---|
| committer | tslil <tslil@posteo.de> | 2026-08-28 19:37:41 +0100 |
| commit | 8f15c1131342376ab3de2c6ce50d1ca5f20ec32a (patch) | |
| tree | 7f6a165878ab3a43bb0f5203d20db5e0979a1933 /include/zobrist.c | |
| parent | 6b48baaf6b67cc7364d5945eb6d9b25ea9683bd9 (diff) | |
I don't have the presence of mind to debug this right now
Diffstat (limited to 'include/zobrist.c')
| -rw-r--r-- | include/zobrist.c | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/include/zobrist.c b/include/zobrist.c index 8eeb758..6208339 100644 --- a/include/zobrist.c +++ b/include/zobrist.c @@ -60,8 +60,9 @@ zobrist_apply(const action_t action, uint64_t hash) { const enum A_TYPE type = GET_TYPE(action); const int8_t loc = GET_LOC(action); if (type == A_PLACE) { + enum COLOUR c = (current_colour == C_BLACK) ? C_WHITE : C_BLACK; hash ^= zobrist[0][loc*(2*3+1) - +current_colour*3 + +c*3 +GET_DATA0(action)]; } else { const uint8_t gaps = GET_DATA0(action) & 0x7F, @@ -70,35 +71,63 @@ zobrist_apply(const action_t action, uint64_t hash) { dir = GET_DATA1(action) >> 4; const int8_t delta = move_deltas[dir]; - // TODO: adapt this int8_t steps = 1; - uint8_t gap_bit = 1, total = 1; - for (int8_t d = 1; d < num; d++, total++, gap_bit <<= 1) { + uint8_t gap_bit = 1, num_dropped = 1, total = COUNT_AT(loc); + for (int8_t d = 1; d < num; d++, num_dropped++, gap_bit <<= 1) { if (gaps & gap_bit) { - colours[loc] <<= total; - colours[loc] |= colours[loc+steps*delta] & ((1 << total) - 1); - colours[loc+steps*delta] >>= total; - celldat[loc] += total*NUM_INC; - celldat[loc+steps*delta] -= total*NUM_INC; - total = 0; + const int8_t target = loc+steps*delta, th = COUNT_AT(target); + // Stash these stones to offset for the height at source + total += num_dropped; + // Apply XOR for stones at source and current target + uint8_t point = 1; + for (int k = 0, ht = th-1, hs = total-1; k < num_dropped; + k++, ht--, hs--, point<<=1) { + hash ^= zobrist[ht][target*(2*3+1) + +(point & colours[target])*3 + +STONE_FLAT]; + hash ^= zobrist[hs][loc*(2*3+1) + +(point & colours[target])*3 + +STONE_FLAT]; + } + // Continue processing gap sequence + num_dropped = 0; steps++; } } - colours[loc] <<= total; - colours[loc] |= colours[loc+steps*delta] & ((1 << total) - 1); - colours[loc+steps*delta] >>= total; - - celldat[loc] += total*NUM_INC; - // celldat[loc] &= CLR_STONE; is not necessary, as STONE_FLAT == 0 - celldat[loc] |= STONE_AT(loc+steps*delta); - celldat[loc+steps*delta] -= total*NUM_INC; - celldat[loc+steps*delta] &= CLR_STONE; + total += num_dropped; + const int8_t target = loc+steps*delta, th = COUNT_AT(target); + const enum STONE_VARIANT top_stone = STONE_AT(target); + // Stash these stones to offset for the height at source + // Apply XOR for stones at source and end target. After this + // source will be correct, but we must account for crush @ target. + uint8_t point = 1; + for (int k = 0, ht = th-1, hs = total-1; k < num_dropped; + k++, ht--, hs--, point<<=1) { + if (k == 0) { + hash ^= zobrist[ht][target*(2*3+1) + +(point & colours[target])*3 + +top_stone]; + hash ^= zobrist[hs][loc*(2*3+1) + +(point & colours[target])*3 + +top_stone]; + } else { + hash ^= zobrist[ht][target*(2*3+1) + +(point & colours[target])*3 + +STONE_FLAT]; + hash ^= zobrist[hs][loc*(2*3+1) + +(point & colours[target])*3 + +STONE_FLAT]; + } + } + // Correct for crush if (crush) { - celldat[loc+steps*delta] |= STONE_STANDING; - } else { - celldat[loc+steps*delta] |= STONE_FLAT; // should be optimised out + hash ^= zobrist[th-1][target*(2*3+1) + +(colours[target] & 1)*3 + +STONE_FLAT]; + hash ^= zobrist[th-1][target*(2*3+1) + +(colours[target] & 1)*3 + +STONE_STANDING]; } - } return hash; } |
