#include "zobrist.h" // =================================================================== // Globals // =================================================================== static uint64_t *zobrist[15]; // =================================================================== // Helpers // =================================================================== // =================================================================== // Exported method implementations // =================================================================== int zobrist_init(void) { for (int k=0; k<15; k++) { if (zobrist[k] != NULL) return EXIT_FAILURE; } for (int j=0; j<15; j++) { zobrist[j] = malloc(sizeof(uint64_t)*board_size*board_size*(2*3+1)); for (int k=0; k>= 1) hash ^= zobrist[h][l*(2*3+1)+(c&1)*3+s]; } return hash; } uint64_t 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) { hash ^= zobrist[0][loc*(2*3+1) +current_colour*3 +GET_DATA0(action)]; } else { const uint8_t gaps = GET_DATA0(action) & 0x7F, crush = GET_DATA0(action) & 0x80, num = GET_DATA1(action) & 0x0F, 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) { 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; 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; if (crush) { celldat[loc+steps*delta] |= STONE_STANDING; } else { celldat[loc+steps*delta] |= STONE_FLAT; // should be optimised out } } return hash; }