|
void | search_global_init (void) |
|
void | search_resize_hashtable (Search *search) |
|
void | search_init (Search *search) |
| Init the main search. More...
|
|
void | search_free (Search *search) |
| Free the search allocated ressource. More...
|
|
void | search_setup (Search *search) |
| Set up various structure once the board has been set. More...
|
|
void | search_clone (Search *search, Search *master) |
| Clone a search for parallel search. More...
|
|
void | search_cleanup (Search *search) |
| Clean-up some search data. More...
|
|
void | search_set_board (Search *search, const Board *board, const int player) |
| Set the board to analyze. More...
|
|
void | search_set_level (Search *search, const int level, const int n_empties) |
| Set the search level. More...
|
|
void | search_set_ponder_level (Search *search, const int level, const int n_empties) |
| Set the search level while pondering. More...
|
|
int | solvable_depth (const long long limit, int n_tasks) |
| Compute the deepest level that can be solved given a limited time... More...
|
|
void | search_set_game_time (Search *search, const long long t) |
| set time to search. More...
|
|
void | search_set_move_time (Search *search, const long long t) |
| set time to search. More...
|
|
void | search_time_init (Search *search) |
| Initialize the alloted time. More...
|
|
void | search_time_reset (Search *search, const Board *initial_board) |
| Reset the alloted time. More...
|
|
void | search_adjust_time (Search *search, const bool once) |
| Give more time. More...
|
|
bool | search_continue (Search *search) |
| Check if it can iterate more... More...
|
|
void | search_check_timeout (Search *search) |
| Check if it can iterate more... More...
|
|
void | search_set_task_number (Search *search, const int n) |
| Change the number of task. More...
|
|
void | search_swap_parity (Search *search, const int x) |
| Change parity. More...
|
|
void | search_get_movelist (const Search *search, MoveList *movelist) |
| Get a list of legal moves. More...
|
|
void | search_update_endgame (Search *search, const Move *move) |
| Update the search state after a move. More...
|
|
void | search_restore_endgame (Search *search, const Move *move) |
| Restore the search state as before a move. More...
|
|
void | search_pass_endgame (Search *search) |
| Update the search state after a passing move. More...
|
|
void | search_update_midgame (Search *search, const Move *move) |
| Update the search state after a move. More...
|
|
void | search_restore_midgame (Search *search, const Move *move) |
| Restore the search state as before a move. More...
|
|
void | search_update_pass_midgame (Search *search) |
| Update the search state after a passing move. More...
|
|
void | search_restore_pass_midgame (Search *search) |
| Update the search state after a passing move. More...
|
|
int | get_pv_extension (const int depth, const int n_empties) |
| Compute the pv_extension. More...
|
|
bool | is_depth_solving (const int depth, const int n_empties) |
| Check if final score use pv_extension or is solved. More...
|
|
long long | search_clock (Search *search) |
| Return the time spent by the search. More...
|
|
long long | search_time (Search *search) |
| Return the time spent by the search. More...
|
|
unsigned long long | search_count_nodes (Search *search) |
| Return the number of nodes searched. More...
|
|
void | search_observer (Result *result) |
| default observer. More...
|
|
void | search_set_observer (Search *search, void(*observer)(Result *)) |
| set observer. More...
|
|
void | result_print (Result *result, FILE *f) |
| Print the current search result. More...
|
|
bool | search_SC_PVS (Search *search, volatile int *alpha, volatile int *beta, int *score) |
| Stability Cutoff (SC). More...
|
|
bool | search_SC_NWS (Search *search, const int alpha, int *score) |
| Stability Cutoff (TC). More...
|
|
bool | search_TC_PVS (HashData *data, const int depth, const int selectivity, volatile int *alpha, volatile int *beta, int *score) |
| Transposition Cutoff (TC). More...
|
|
bool | search_TC_NWS (HashData *data, const int depth, const int selectivity, const int alpha, int *score) |
| Transposition Cutoff (TC). More...
|
|
bool | search_ETC_NWS (Search *search, MoveList *movelist, unsigned long long hash_code, const int depth, const int selectivity, const int alpha, int *score) |
| Enhanced Transposition Cutoff (ETC). More...
|
|
void | search_share (const Search *src, Search *dest) |
| Share search information. More...
|
|
int | search_count_tasks (const Search *search) |
| Count the number of tasks used in parallel search. More...
|
|
void | search_stop_all (Search *search, const Stop stop) |
| Stop the search. More...
|
|
void | search_set_state (Search *search, const Stop stop) |
| Set the search running/waiting state. More...
|
|
int | search_guess (Search *search, const Board *board) |
| Guess the bestmove of a given board. More...
|
|
Search the best move.
Functions that evaluate a board with different methods depending on the position in the tree search and/or that finds the best move of a given board.
At the end of the game, some trivial functions are used to compute the score. For instance, the last move is not made and only the number of flipped discs is evaluated. Special and optimized functions are used when one, two and three empty squares remain on the board, in order to speed up the search.
The search of the best move is driven with the Principal Variation Search algorithm (PVS) [1], an enhanced variation of the alphabeta algorithm. The alphabeta algorithm is known to visit less nodes when the alphabeta window is reduced. PVS takes this property into account. From a set of sibling nodes, the first node is searched using a plain alpha beta window. Then the sibling nodes are only searched with minimal windows (where beta = alpha + 1), just to refute the best (first) score. In rare cases the first move is actually refuted, then the current move is re-searched a second time in order to determinate its score more accurately. On highly ordered tree, very few re-searches will be done. Moreover, thanks to the hash table, a second search is usually faster than a first search. So the seldom and fast re-searches will not impact too much the benefit of using minimal windows. Aspiration windows have been added as another improvement, so that even the first search is done with a reduced window. During the 1990s, several re-re-search algorithms based on null-window alphabeta have been proposed : SSS*ab [2], Dual*ab[2], NegaC*[3], MDT[2], negascout[4]. Some (unpublished) experimental tests I made with them did not show any significant improvement compare to the PVS algorithm with aspiration-windows used here.
To be efficient PVS need highly ordered tree. The following ordering has been made :
- fixed square ordering: square usually leading to a good move are visited first, ie from corner squares to X and C squares.
- parity: squares on odd set of empty squares should be played first, especially near the end of the game.
- most stable ordering: a crude evaluation of stability at the corner (corner, X and C squares) to order the moves.
- fast first ordering: the moves leading to the most reduced mobility for the opponent are played first.
- best move previously found: If the position has been previously searched, the best move that was found is replayed as the first move.
Campbell MS & Marsland TA (1983) A Comparison of Minimax Trees Search Algorithms. Artificial Intelligence, 20, pp. 347-367.
- Plaat A. et al. (1996) Best-First Fixed Depth Minimax Algorithms. Artificial Intelligence, 84, pp. 255-293.
- Weill JC. (1992) Experiments With The NegaC* Search. An alternative for Othello Endgame Search. ICCA journal, 15(1), pp. 3-7.
- Reinsfeld A. (1983) An Improvement Of the Scout Tree-Search Algorithm. ICCA journal, 6(4), pp. 4-14.
- Date
- 1998 - 2017
- Author
- Richard Delorme
- Version
- 4.4