⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 search.cpp

📁 超强国际象棋引擎
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -