📄 search.cpp
字号:
// search.cpp
// includes
#ifdef _WIN32
#include <windows.h>
#include <process.h>
#else
#include <pthread.h>
#include <unistd.h>
#endif
#include <csetjmp>
#include <cstring>
#include "board.h"
#include "move.h"
#include "make_move.h"
#include "move_gen.h"
#include "config.h"
#include "interface.h"
#include "pv.h"
#include "search.h"
#include "search_root.h"
#include "sort.h"
#include "transposition.h"
#include "values.h"
// variables
int number_threads = 1;
static search_multipv_t save_multipv[10];
search_input_t search_input[1];
search_info_t search_info[16][1];
search_root_t search_root[16][1];
search_current_t search_current[16][1];
search_best_t search_best[16][10];
// prototypes
static void search_send_stat(int thread_id);
#ifdef _WIN32
void search_thread (void *param);
#else
void * search_thread (void *param);
#endif
// functions
// depth_is_ok()
bool depth_is_ok(int depth)
{
return depth > -128 && depth < 64;
}
// height_is_ok()
bool height_is_ok(int height)
{
return height >= 0 && height < 256;
}
// search_clear()
void search_clear()
{
int thread_id;
// search_input
search_input->infinite = false;
search_input->depth_is_limited = false;
search_input->depth_limit = 0;
search_input->time_is_limited = false;
search_input->time_limit_1 = 0.0;
search_input->time_limit_2 = 0.0;
// search_info
for ( thread_id = 0; thread_id < number_threads; thread_id++ )
{
search_info[thread_id]->can_stop = false;
search_info[thread_id]->stop = false;
search_info[thread_id]->check_nb = 10000;
search_info[thread_id]->check_inc = 10000;
search_info[thread_id]->last_time = 0.0;
// search_best
search_best[thread_id][search_current[thread_id]->multipv].move = 0;
search_best[thread_id][search_current[thread_id]->multipv].value = 0;
search_best[thread_id][search_current[thread_id]->multipv].flags = 0;
PV_CLEAR(search_best[thread_id][search_current[thread_id]->multipv].pv);
// search_root
search_root[thread_id]->depth = 0;
search_root[thread_id]->move = 0;
search_root[thread_id]->move_pos = 0;
search_root[thread_id]->move_nb = 0;
search_root[thread_id]->last_value = 0;
search_root[thread_id]->bad_1 = false;
search_root[thread_id]->bad_2 = false;
search_root[thread_id]->change = false;
search_root[thread_id]->easy = false;
search_root[thread_id]->flag = false;
// search_current
search_current[thread_id]->max_depth = 0;
search_current[thread_id]->node_nb = 0;
search_current[thread_id]->time = 0.0;
search_current[thread_id]->speed = 0.0;
}
}
// search()
void search()
{
int i;
int thread_id;
int ThreadIds[16];
#ifdef _WIN32
HANDLE handle[16];
#else
pthread_t handle[16];
#endif
for ( i = 0; i < 10; i++ )
{
save_multipv[i].mate = 0;
save_multipv[i].depth = 0;
save_multipv[i].max_depth = 0;
save_multipv[i].value = 0;
save_multipv[i].time = 0;
save_multipv[i].node_nb = 0;
strcpy(save_multipv[i].pv_string, "");
}
search_input->multipv = option_get_int("MultiPV") - 1;
for ( thread_id = 0; thread_id < number_threads; thread_id++ )
{
search_current[thread_id]->multipv = 0;
}
// search_input
gen_legal_moves(search_input->list, search_input->board);
if(LIST_SIZE(search_input->list) < search_input->multipv + 1)
{
search_input->multipv = LIST_SIZE(search_input->list) - 1;
}
if(LIST_SIZE(search_input->list) <= 1)
{
search_input->depth_is_limited = true;
search_input->depth_limit = 4; // was 1
}
// start thread
for ( i = 1; i < number_threads; i++ )
{
ThreadIds[i - 1] = i;
#ifdef _WIN32
handle[i - 1] = (HANDLE)_beginthread(search_thread, 0, &ThreadIds[i - 1]);
#else
pthread_create(&(handle[i-1]),NULL,search_thread,
&(ThreadIds[i-1]));
#endif
}
search_smp(0);
for ( thread_id = 1; thread_id < number_threads; thread_id++ )
{ // stop threads
search_info[thread_id]->stop = true;
}
for ( thread_id = 1; thread_id < number_threads; thread_id++ )
{
#ifdef _WIN32
WaitForSingleObject(handle[thread_id - 1], INFINITE);
#else
pthread_join(handle[thread_id-1],NULL);
#endif
}
}
#ifdef _WIN32
void search_thread(void *param)
{
int thread_id = *((int *)param);
search_smp(thread_id);
_endthread();
}
#else
void * search_thread(void *param)
{
int thread_id = *((int *)param);
search_smp(thread_id);
return NULL;
}
#endif
// search_smp()
void search_smp(int thread_id)
{
int depth;
int i;
bool search_ready;
sint64 node_nb;
double speed;
// search_info
if(setjmp(search_info[thread_id]->buf) != 0)
{
search_update_current(thread_id);
return;
}
// search_root
list_copy(search_root[thread_id]->list, search_input->list);
// search_current
board_copy(search_current[thread_id]->board, search_input->board);
timer_reset(search_current[thread_id]->timer);
timer_start(search_current[thread_id]->timer);
// init
trans_inc_date(Trans);
sort_init(thread_id);
search_full_init(search_root[thread_id]->list, search_current[thread_id]->board, thread_id);
// iterative deepening
search_ready = false;
if(thread_id == 0)
{ // main thread
for ( depth = 1; depth < 64; depth++ )
{
for ( search_current[thread_id]->multipv = 0; search_current[thread_id]->multipv <= search_input->multipv;
search_current[thread_id]->multipv++ )
{
if(search_current[thread_id]->multipv == 0)
send("info depth %d", depth);
search_current[thread_id]->act_iteration = depth;
search_root[thread_id]->bad_1 = false;
search_root[thread_id]->change = false;
board_copy(search_current[thread_id]->board, search_input->board);
if(depth <= 1)
{
search_full_root(search_root[thread_id]->list, search_current[thread_id]->board, depth, 1,
thread_id);
}
else
{
search_full_root(search_root[thread_id]->list, search_current[thread_id]->board, depth, 0,
thread_id);
}
search_update_current(thread_id);
node_nb = 0;
speed = 0;
for ( i = 0; i < number_threads; i++ )
{
node_nb += search_current[thread_id]->node_nb;
speed += search_current[thread_id]->speed;
}
if(search_current[thread_id]->multipv == search_input->multipv)
{
send("info depth %d seldepth %d time %.0f nodes "
S64_FORMAT " nps %.0f",depth,search_current[thread_id]->
max_depth,search_current[thread_id]->time
*1000.0,node_nb,speed);
}
// update search info
if(depth >= 1)
search_info[thread_id]->can_stop = true;
if(depth == 1 && LIST_SIZE(search_root[thread_id]->list) >= 2
&& LIST_VALUE(search_root[thread_id]->list, 0) >= LIST_VALUE(search_root[thread_id]->list, 1)
+ 150)
{
search_root[thread_id]->easy = true;
}
if(depth > 1)
{
search_root[thread_id]->bad_2 = search_root[thread_id]->bad_1;
search_root[thread_id]->bad_1 = false;
}
search_root[thread_id]->last_value = search_best[thread_id][0].value;
// stop search?
if(search_input->depth_is_limited && search_current[thread_id]->multipv >= search_input->multipv
&& depth >= search_input->depth_limit)
{
search_root[thread_id]->flag = true;
}
if(search_input->time_is_limited && search_current[thread_id]->time >= search_input->time_limit_1
&& !search_root[thread_id]->bad_2)
{
search_root[thread_id]->flag = true;
}
if(search_input->time_is_limited
&& search_current[thread_id]->time >= search_input->time_limit_1 * 0.2
&& search_root[thread_id]->easy)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -