static void update_best_move_history(position_t *p, int index_of_best, sortable_move_t* lst, int count) { tbassert(ENABLE_TABLES, "Tables weren't enabled.\n"); int color_to_move = color_to_move_of(p); for (int i = 0; i < count; i++) { move_t mv = get_move(lst[i]); ptype_t pce = ptype_mv_of(mv); rot_t ro = rot_of(mv); // rotation square_t fs = from_square(mv); int ot = ORI_MASK & (ori_of(p->board[fs]) + ro); square_t ts = to_square(mv); int s = best_move_history[BMH(color_to_move, pce, ts, ot)]; if (index_of_best == i) { s = s + 11200; // number will never exceed 1017 } s = s * 0.90; // decay score over time tbassert(s < 102000, "s = %d\n", s); // or else sorting will fail best_move_history[BMH(color_to_move, pce, ts, ot)] = s; } }
// Obtain a sorted move list. static int get_sortable_move_list(searchNode *node, sortable_move_t * move_list, int hash_table_move) { // number of moves in list int num_of_moves = generate_all_opt(&(node->position), move_list, false); color_t fake_color_to_move = color_to_move_of(&(node->position)); move_t killer_a = killer[KMT(node->ply, 0)]; move_t killer_b = killer[KMT(node->ply, 1)]; // sort special moves to the front for (int mv_index = 0; mv_index < num_of_moves; mv_index++) { move_t mv = get_move(move_list[mv_index]); if (mv == hash_table_move) { set_sort_key(&move_list[mv_index], SORT_MASK); } else if (mv == killer_a) { set_sort_key(&move_list[mv_index], SORT_MASK - 1); } else if (mv == killer_b) { set_sort_key(&move_list[mv_index], SORT_MASK - 2); } else { ptype_t pce = ptype_mv_of(mv); rot_t ro = rot_of(mv); // rotation square_t fs = from_square(mv); int ot = ORI_MASK & (ori_of(node->position.board[fs]) + ro); square_t ts = to_square(mv); set_sort_key(&move_list[mv_index], best_move_history[BMH(fake_color_to_move, pce, ts, ot)]); } } return num_of_moves; }
// converts a move to string notation for FEN void move_to_str(move_t mv, char *buf, size_t bufsize) { square_t f = from_square(mv); // from-square square_t t = to_square(mv); // to-square rot_t r = rot_of(mv); // rotation const char *orig_buf = buf; buf += square_to_str(f, buf, bufsize); if (f != t) { buf += square_to_str(t, buf, bufsize - (buf - orig_buf)); } else { switch (r) { case NONE: buf += square_to_str(t, buf, bufsize - (buf - orig_buf)); break; case RIGHT: buf += snprintf(buf, bufsize - (buf - orig_buf), "R"); break; case UTURN: buf += snprintf(buf, bufsize - (buf - orig_buf), "U"); break; case LEFT: buf += snprintf(buf, bufsize - (buf - orig_buf), "L"); break; default: tbassert(false, "Whoa, now. Whoa, I say.\n"); // Bad, bad, bad break; } } }
// Obtain a sorted move list. static int get_sortable_move_list(searchNode *node, sortable_move_t * move_list, int hash_table_move) { // number of moves in list int num_of_moves = generate_all(&(node->position), move_list, false); color_t fake_color_to_move = color_to_move_of(&(node->position)); move_t killer_a = killer[KMT(node->ply, 0)]; move_t killer_b = killer[KMT(node->ply, 1)]; for (int mv_index = 0; mv_index < num_of_moves; mv_index++) { move_t mv = move_list[mv_index]; // don't use get_move. assumes generate_all doesn't bungle up high bits if (mv == hash_table_move) { set_sort_key(&move_list[mv_index], SORT_MASK); } else if (mv == killer_a) { set_sort_key(&move_list[mv_index], SORT_MASK - 1); } else if (mv == killer_b) { set_sort_key(&move_list[mv_index], SORT_MASK - 2); } else { ptype_t pce = ptype_mv_of(mv); rot_t ro = rot_of(mv); // rotation square_t fs = from_square(mv); int ot = ORI_MASK & (ori_of(node->position.board[fs]) + ro); square_t ts = to_square(mv); set_sort_key(&move_list[mv_index], best_move_history[BMH(fake_color_to_move, pce, ts, ot)]); } sortable_move_t insert = move_list[mv_index]; // TODO: enable this optimization for final since node counts change // if (insert > SORT_MASK) { int hole = mv_index; while (hole > 0 && insert > move_list[hole-1]) { move_list[hole] = move_list[hole-1]; hole--; } move_list[hole] = insert; // } } return num_of_moves; }