Computer Chess Club Archives


Search

Terms

Messages

Subject: sources (long 22KB)

Author: Jarkko Pesonen

Date: 15:13:20 09/04/05

Go up one level in this thread



// option.cpp

// includes

#include <cstdlib>

#include "option.h"
#include "protocol.h"
#include "util.h"

// types

struct option_t {
   const char * var;
   bool declare;
   const char * init;
   const char * type;
   const char * extra;
   const char * val;
};

// variables

option_t Option[] = {

   { "Hash", true, "16", "spin", "min 4 max 1024", NULL },

   { "Ponder", true, "false", "check", "", NULL },

   { "OwnBook",  true, "true",           "check",  "", NULL },
   { "BookFile", true, "book_small.bin", "string", "", NULL },

   { "NullMove Pruning",       true, "Fail High", "combo", "var Always var Fail
High var Never", NULL },
   { "NullMove Reduction",     true, "3",         "spin",  "min 1 max 3", NULL
},
   { "Verification Search",    true, "Endgame",   "combo", "var Always var
Endgame var Never", NULL },
   { "Verification Reduction", true, "5",         "spin",  "min 1 max 6", NULL
},

   { "History Pruning",     true, "true", "check", "", NULL },
   { "History Threshold",   true, "60",   "spin",  "min 0 max 100", NULL },

   { "Futility Pruning", true, "false", "check", "", NULL },
   { "Futility Margin",  true, "100",   "spin",  "min 0 max 500", NULL },

   { "Delta Pruning", true, "false", "check", "", NULL },
   { "Delta Margin",  true, "50",    "spin",  "min 0 max 500", NULL },

   { "Quiescence Check Plies", true, "1", "spin", "min 0 max 2", NULL },

   { "Material",        true, "100", "spin", "min 0 max 400", NULL },
   { "Piece Activity",  true, "100", "spin", "min 0 max 400", NULL },
   { "King Safety",     true, "100", "spin", "min 0 max 400", NULL },
   { "Pawn Structure",  true, "100", "spin", "min 0 max 400", NULL },
   { "Passed Pawns",    true, "100", "spin", "min 0 max 400", NULL },
   { "MultiPV",    true, "1", "spin", "min 1 max 10", NULL },

   { NULL, false, NULL, NULL, NULL, NULL, },
};

// prototypes

static option_t * option_find (const char var[]);

// functions

// option_init()

void option_init() {

   option_t * opt;

   for (opt = &Option[0]; opt->var != NULL; opt++) {
      option_set(opt->var,opt->init);
   }
}

// option_list()

void option_list() {

   option_t * opt;

   for (opt = &Option[0]; opt->var != NULL; opt++) {
      if (opt->declare) {
         if (opt->extra != NULL && *opt->extra != '\0') {
            send("option name %s type %s default %s
%s",opt->var,opt->type,opt->val,opt->extra);
         } else {
            send("option name %s type %s default
%s",opt->var,opt->type,opt->val);
         }
      }
   }
}

// option_set()

bool option_set(const char var[], const char val[]) {

   option_t * opt;

   ASSERT(var!=NULL);
   ASSERT(val!=NULL);

   opt = option_find(var);
   if (opt == NULL) return false;

   my_string_set(&opt->val,val);

   return true;
}

// option_get()

const char * option_get(const char var[]) {

   option_t * opt;

   ASSERT(var!=NULL);

   opt = option_find(var);
   if (opt == NULL) my_fatal("option_get(): unknown option \"%s\"\n",var);

   return opt->val;
}

// option_get_bool()

bool option_get_bool(const char var[]) {

   const char * val;

   val = option_get(var);

   if (false) {
   } else if (my_string_equal(val,"true") || my_string_equal(val,"yes") ||
my_string_equal(val,"1")) {
      return true;
   } else if (my_string_equal(val,"false") || my_string_equal(val,"no") ||
my_string_equal(val,"0")) {
      return false;
   }

   ASSERT(false);

   return false;
}

// option_get_int()

int option_get_int(const char var[]) {

   const char * val;

   val = option_get(var);

   return atoi(val);
}

// option_get_string()

const char * option_get_string(const char var[]) {

   const char * val;

   val = option_get(var);

   return val;
}

// option_find()

static option_t * option_find(const char var[]) {

   option_t * opt;

   ASSERT(var!=NULL);

   for (opt = &Option[0]; opt->var != NULL; opt++) {
      if (my_string_equal(opt->var,var)) return opt;
   }

   return NULL;
}

// end of option.cpp

/////////////////////////////////////////////////////////////////////////////

// search.cpp

// includes

#include <csetjmp>
#include <string.h>
#include <stdlib.h>
#include <minmax.h>
#include <memory.h>
#include <math.h>
#include "attack.h"
#include "board.h"
#include "book.h"
#include "colour.h"
#include "list.h"
#include "material.h"
#include "move.h"
#include "move_do.h"
#include "move_gen.h"
#include "option.h"
#include "pawn.h"
#include "protocol.h"
#include "pv.h"
#include "search.h"
#include "search_full.h"
#include "sort.h"
#include "trans.h"
#include "util.h"
#include "value.h"

// constants

static const bool UseCpuTime = false; // false
static const bool UseEvent = true; // true

static const bool UseShortSearch = true;
static const int ShortSearchDepth = 1;

static const bool DispBest = true; // true
static const bool DispDepthStart = true; // true
static const bool DispDepthEnd = true; // true
static const bool DispRoot = true; // true
static const bool DispStat = true; // true

static const bool UseEasy = true; // singular move
static const int EasyThreshold = 150;
static const double EasyRatio = 0.20;

static const bool UseEarly = true; // early iteration end
static const double EarlyRatio = 0.60;

static const bool UseBad = true;
static const int BadThreshold = 50; // 50
static const bool UseExtension = true;

// variables

search_input_t SearchInput[1];
search_info_t SearchInfo[1];
search_root_t SearchRoot[1],SearchMultiStart[1];
search_current_t SearchCurrent[1];
search_best_t SearchBest[1];

multi_t multiV[10];
// prototypes

static void search_send_stat ();

// functions

// depth_is_ok()

bool depth_is_ok(int depth) {

   return depth > -128 && depth < DepthMax;
}

// height_is_ok()

bool height_is_ok(int height) {

   return height >= 0 && height < HeightMax;
}

// search_clear()

void search_clear() {

   // SearchInput

   SearchInput->infinite = false;
   SearchInput->depth_is_limited = false;
   SearchInput->depth_limit = 0;
   SearchInput->time_is_limited = false;
   SearchInput->time_limit_1 = 0.0;
   SearchInput->time_limit_2 = 0.0;

   // SearchInfo

   SearchInfo->can_stop = false;
   SearchInfo->stop = false;
   SearchInfo->check_nb = 10000; // was 100000
   SearchInfo->check_inc = 10000; // was 100000
   SearchInfo->last_time = 0.0;

   // SearchBest

   SearchBest->move = MoveNone;
   SearchBest->value = 0;
   SearchBest->flags = SearchUnknown;
   PV_CLEAR(SearchBest->pv);

   // SearchRoot

   SearchRoot->depth = 0;
   SearchRoot->move = MoveNone;
   SearchRoot->move_pos = 0;
   SearchRoot->move_nb = 0;
   SearchRoot->last_value = 0;
   SearchRoot->bad_1 = false;
   SearchRoot->bad_2 = false;
   SearchRoot->change = false;
   SearchRoot->easy = false;
   SearchRoot->flag = false;
   SearchRoot->multiPV = 1;

   // SearchCurrent

   SearchCurrent->max_depth = 0;
   SearchCurrent->node_nb = 0;
   SearchCurrent->time = 0.0;
   SearchCurrent->speed = 0.0;
   SearchCurrent->cpu = 0.0;
}
void bubblesort( multi_t *sortv,int n)
{
	int i,j;
	multi_t temp;

	for (i=0; i < n-1; i++) {
		for (j=0; j < n-1-i; j++)
			if (sortv[j+1].value > sortv[j].value) {  /* compare the two neighbors */
				memcpy(&temp,&sortv[j],sizeof(multi_t));         /* swap a[j] and a[j+1]
 */
				memcpy(&sortv[j],&sortv[j+1],sizeof(multi_t));
				memcpy(&sortv[j+1], &temp,sizeof(multi_t));
			}
	}
}

// search()
int multiBegin;

void search() {

   int move;
   int depth;
const char *mv;
char multi;
int idx,i;


   ASSERT(board_is_ok(SearchInput->board));

   // opening book

   if (option_get_bool("OwnBook") && !SearchInput->infinite) {

      move = book_move(SearchInput->board);

      if (move != MoveNone) {

         // play book move

         SearchBest->move = move;
         SearchBest->value = 1;
         SearchBest->flags = SearchExact;
         SearchBest->depth = 1;
         SearchBest->pv[0] = move;
         SearchBest->pv[1] = MoveNone;

         search_update_best();

         return;
      }
   }

   // SearchInput

   gen_legal_moves(SearchInput->list,SearchInput->board);

   if (LIST_SIZE(SearchInput->list) <= 1) {
      SearchInput->depth_is_limited = true;
      SearchInput->depth_limit = 4; // was 1
   }

   // SearchInfo

   if (setjmp(SearchInfo->buf) != 0) {
      ASSERT(SearchInfo->can_stop);
      ASSERT(SearchBest->move!=MoveNone);
      search_update_current();
      return;
   }

   // SearchRoot

   list_copy(SearchRoot->list,SearchInput->list);

   // SearchCurrent

   board_copy(SearchCurrent->board,SearchInput->board);
   my_timer_reset(SearchCurrent->timer);
   my_timer_start(SearchCurrent->timer);

   // init

   trans_inc_date(Trans);

   sort_init();
   search_full_init(SearchRoot->list,SearchCurrent->board);

   // iterative deepening

   for (depth = 1; depth < DepthMax; depth++) {

      if (DispDepthStart) send("info depth %d",depth);

	  mv=&multi;
	  mv=option_get("MultiPV");
	  multiBegin=min(SearchRoot->multiPV = atoi(mv),SearchRoot->list->size);

      SearchRoot->bad_1 = false;
      SearchRoot->change = false;
multiPV:
      board_copy(SearchCurrent->board,SearchInput->board);

      if (UseShortSearch && depth <= ShortSearchDepth) {

search_full_root(SearchRoot->list,SearchCurrent->board,depth,SearchShort);
      } else {

search_full_root(SearchRoot->list,SearchCurrent->board,depth,SearchNormal);
      }
	  if(SearchRoot->multiPV==multiBegin)
			list_copy(SearchMultiStart->list,SearchRoot->list);
      search_update_current();

      if (DispDepthEnd) {
         send("info depth %d seldepth %d time %.0f nodes " S64_FORMAT " nps
%.0f",depth,SearchCurrent->max_depth,SearchCurrent->time*1000.0,SearchCurrent->node_nb,SearchCurrent->speed);
      }
	  if(SearchRoot->multiPV > 1){
		  idx=list_get_index( SearchRoot->list, SearchBest->move);
		  list_remove( SearchRoot->list,  idx) ;
		  SearchRoot->multiPV--;
		  SearchRoot->change = true;
			  goto multiPV;
	  }

      // update search info

      if (depth >= 1) SearchInfo->can_stop = true;

      if (depth == 1
       && LIST_SIZE(SearchRoot->list) >= 2
       && LIST_VALUE(SearchRoot->list,0) >= LIST_VALUE(SearchRoot->list,1) +
EasyThreshold) {
         SearchRoot->easy = true;
      }

      if (UseBad && depth > 1) {
         SearchRoot->bad_2 = SearchRoot->bad_1;
         SearchRoot->bad_1 = false;

ASSERT(SearchRoot->bad_2==(SearchBest->value<=SearchRoot->last_value-BadThreshold));
      }

      SearchRoot->last_value = SearchBest->value;

      // stop search?

      if (SearchInput->depth_is_limited
       && depth >= SearchInput->depth_limit) {
         SearchRoot->flag = true;
      }

      if (SearchInput->time_is_limited
       && SearchCurrent->time >= SearchInput->time_limit_1
       && !SearchRoot->bad_2) {
         SearchRoot->flag = true;
      }

      if (UseEasy
       && SearchInput->time_is_limited
       && SearchCurrent->time >= SearchInput->time_limit_1 * EasyRatio
       && SearchRoot->easy) {
         ASSERT(!SearchRoot->bad_2);
         ASSERT(!SearchRoot->change);
         SearchRoot->flag = true;
      }

      if (UseEarly
       && SearchInput->time_is_limited
       && SearchCurrent->time >= SearchInput->time_limit_1 * EarlyRatio
       && !SearchRoot->bad_2
       && !SearchRoot->change) {
         SearchRoot->flag = true;
      }

      if (SearchInfo->can_stop
       && (SearchInfo->stop || (SearchRoot->flag && !SearchInput->infinite))) {
         break;
      }
	  list_copy(SearchRoot->list,SearchMultiStart->list);
	  for(i=0;i<multiBegin;i++){
		idx=list_get_index(SearchRoot->list,  multiV[i].move);
		SearchRoot->list->value[idx]=multiV[i].value;
	  }
	  list_sort(SearchRoot->list);
   }
}

// search_update_best()

void search_update_best() {

   int move, value, flags, depth, max_depth;
   const mv_t * pv;
   double time;
   sint64 node_nb;
   int mate;
   char move_string[256], pv_string[512],multi;
   const char *mv;



   search_update_current();

   if (DispBest) {

      move = SearchBest->move;
      value = SearchBest->value;
      flags = SearchBest->flags;
      depth = SearchBest->depth;
      pv = SearchBest->pv;

      max_depth = SearchCurrent->max_depth;
      time = SearchCurrent->time;
      node_nb = SearchCurrent->node_nb;

      move_to_string(move,move_string,256);
      pv_to_string(pv,pv_string,512);

      mate = value_to_mate(value);

      if (mate == 0) {

         // normal evaluation
		  if( multiBegin==1){
         if (false) {
         } else if (flags == SearchExact) {
            send("info depth %d seldepth %d score cp %d time %.0f nodes "
S64_FORMAT " pv %s",depth,max_depth,value,time*1000.0,node_nb,pv_string);
         } else if (flags == SearchLower) {
            send("info depth %d seldepth %d score cp %d lowerbound time %.0f
nodes " S64_FORMAT " pv
%s",depth,max_depth,value,time*1000.0,node_nb,pv_string);
         } else if (flags == SearchUpper) {
            send("info depth %d seldepth %d score cp %d upperbound time %.0f
nodes " S64_FORMAT " pv
%s",depth,max_depth,value,time*1000.0,node_nb,pv_string);
         }
		  }
		mv=&multi;
		mv=option_get("MultiPV");

		multiV[multiBegin-SearchRoot->multiPV].value=value;
		multiV[multiBegin-SearchRoot->multiPV].move=move;
		multiV[multiBegin-SearchRoot->multiPV].nodes=node_nb;
		multiV[multiBegin-SearchRoot->multiPV].mate=0;
		strcpy(multiV[multiBegin-SearchRoot->multiPV].pv,pv_string);

		if(multiBegin-SearchRoot->multiPV+1>1)
			bubblesort( multiV, multiBegin-SearchRoot->multiPV+1);

	if(SearchRoot->multiPV>=1){
		for(int i=0;i<multiBegin-SearchRoot->multiPV+1;i++)
			if(multiV[i].mate==1)
				send("info multipv %d depth %d  seldepth %d score mate %d  nodes "
S64_FORMAT " nps 1031 hashfull 0 pv
%s",i+1,depth,max_depth,multiV[i].value,multiV[i].nodes,multiV[i].pv);
			else
				send("info multipv %d depth %d  seldepth %d score cp %d  nodes " S64_FORMAT
" nps 1031 hashfull 0 pv
%s",i+1,depth,max_depth,multiV[i].value,multiV[i].nodes,multiV[i].pv);
	}

      } else {

         // mate announcement
		  if( multiBegin==1){
		  if (false) {
         } else if (flags == SearchExact) {
            send("info depth %d seldepth %d score mate %d time %.0f nodes "
S64_FORMAT " pv %s",depth,max_depth,mate,time*1000.0,node_nb,pv_string);
         } else if (flags == SearchLower) {
            send("info depth %d seldepth %d score mate %d lowerbound time %.0f
nodes " S64_FORMAT " pv %s",depth,max_depth,mate,time*1000.0,node_nb,pv_string);
         } else if (flags == SearchUpper) {
            send("info depth %d seldepth %d score mate %d upperbound time %.0f
nodes " S64_FORMAT " pv %s",depth,max_depth,mate,time*1000.0,node_nb,pv_string);
         }
		  }
		 if(SearchRoot->multiPV>=1){
		multiV[multiBegin-SearchRoot->multiPV].value=mate;
		multiV[multiBegin-SearchRoot->multiPV].move=move;
		multiV[multiBegin-SearchRoot->multiPV].nodes=node_nb;
		strcpy(multiV[multiBegin-SearchRoot->multiPV].pv,pv_string);
		multiV[multiBegin-SearchRoot->multiPV].mate=1;
		if(multiBegin-SearchRoot->multiPV+1>1)
			bubblesort( multiV, multiBegin-SearchRoot->multiPV+1);
		for(int i=0;i<multiBegin-SearchRoot->multiPV+1;i++)
			if(multiV[i].mate==1)
				send("info multipv %d depth %d  seldepth %d score mate %d  nodes "
S64_FORMAT " nps 1031 hashfull 0 pv
%s",i+1,depth,max_depth,multiV[i].value,multiV[i].nodes,multiV[i].pv);
			else
				send("info multipv %d depth %d  seldepth %d score cp %d  nodes " S64_FORMAT
" nps 1031 hashfull 0 pv
%s",i+1,depth,max_depth,multiV[i].value,multiV[i].nodes,multiV[i].pv);
		 }
	  }
   }

   // update time-management info

   if (UseBad && SearchBest->depth > 1) {
      if (SearchBest->value <= SearchRoot->last_value - BadThreshold) {
         SearchRoot->bad_1 = true;
         SearchRoot->easy = false;
         SearchRoot->flag = false;
      } else {
         SearchRoot->bad_1 = false;
      }
   }
}

// search_update_root()

void search_update_root() {

   int move, move_pos, move_nb;
   double time;
   sint64 node_nb;
   char move_string[256];

   if (DispRoot) {

      search_update_current();

      if (SearchCurrent->time >= 1.0) {

         move = SearchRoot->move;
         move_pos = SearchRoot->move_pos;
         move_nb = SearchRoot->move_nb;

         time = SearchCurrent->time;
         node_nb = SearchCurrent->node_nb;

         move_to_string(move,move_string,256);

         send("info currmove %s currmovenumber %d",move_string,move_pos+1);
      }
   }
}

// search_update_current()

void search_update_current() {

   my_timer_t *timer;
   sint64 node_nb;
   double time, speed, cpu;

   timer = SearchCurrent->timer;

   node_nb = SearchCurrent->node_nb;
   time = (UseCpuTime) ? my_timer_elapsed_cpu(timer) :
my_timer_elapsed_real(timer);
   speed = (time >= 1.0) ? double(node_nb) / time : 0.0;
   cpu = my_timer_cpu_usage(timer);

   SearchCurrent->time = time;
   SearchCurrent->speed = speed;
   SearchCurrent->cpu = cpu;
}

// search_check()

void search_check() {

   search_send_stat();

   if (UseEvent) event();

   if (SearchInput->depth_is_limited
    && SearchRoot->depth > SearchInput->depth_limit) {
      SearchRoot->flag = true;
   }

   if (SearchInput->time_is_limited
    && SearchCurrent->time >= SearchInput->time_limit_2) {
      SearchRoot->flag = true;
   }

   if (SearchInput->time_is_limited
    && SearchCurrent->time >= SearchInput->time_limit_1
    && !SearchRoot->bad_1
    && !SearchRoot->bad_2
    && (!UseExtension || SearchRoot->move_pos == 0)) {
      SearchRoot->flag = true;
   }

   if (SearchInfo->can_stop
    && (SearchInfo->stop || (SearchRoot->flag && !SearchInput->infinite))) {
      longjmp(SearchInfo->buf,1);
   }
}

// search_send_stat()

static void search_send_stat() {

   double time, speed, cpu;
   sint64 node_nb;

   search_update_current();

   if (DispStat && SearchCurrent->time >= SearchInfo->last_time + 1.0) { // at
least one-second gap

      SearchInfo->last_time = SearchCurrent->time;

      time = SearchCurrent->time;
      speed = SearchCurrent->speed;
      cpu = SearchCurrent->cpu;
      node_nb = SearchCurrent->node_nb;

      send("info time %.0f nodes " S64_FORMAT " nps %.0f cpuload
%.0f",time*1000.0,node_nb,speed,cpu*1000.0);

      trans_stats(Trans);
   }
}



// end of search.cpp

///////////////////////////////////////////////////////////////////////////
// search.h

#ifndef SEARCH_H
#define SEARCH_H

// includes

#include <csetjmp>

#include "board.h"
#include "list.h"
#include "move.h"
#include "util.h"

// constants

const int DepthMax = 64;
const int HeightMax = 256;

const int SearchNormal = 0;
const int SearchShort  = 1;

const int SearchUnknown = 0;
const int SearchUpper   = 1;
const int SearchLower   = 2;
const int SearchExact   = 3;

// types

struct search_input_t {
   board_t board[1];
   list_t list[1];
   bool infinite;
   bool depth_is_limited;
   int depth_limit;
   bool time_is_limited;
   double time_limit_1;
   double time_limit_2;
};

struct search_info_t {
   jmp_buf buf;
   bool can_stop;
   bool stop;
   int check_nb;
   int check_inc;
   double last_time;
};

struct search_root_t {
   list_t list[1];
   int depth;
   int move;
   int move_pos;
   int move_nb;
   int last_value;
   bool bad_1;
   bool bad_2;
   bool change;
   bool easy;
   bool flag;
   int multiPV;
};

struct search_best_t {
   int move;
   int value;
   int flags;
   int depth;
   mv_t pv[HeightMax];
};

struct search_current_t {
   board_t board[1];
   my_timer_t timer[1];
   int max_depth;
   sint64 node_nb;
   double time;
   double speed;
   double cpu;
};

 struct multi_t{
	   int value;
	   int move;
	   sint64 nodes;
	   char pv[512];
	   int mate;
   };

// variables

extern search_input_t SearchInput[1];
extern search_info_t SearchInfo[1];
extern search_best_t SearchBest[1];
extern search_root_t SearchRoot[1];
extern search_current_t SearchCurrent[1];

// functions

extern bool depth_is_ok           (int depth);
extern bool height_is_ok          (int height);

extern void search_clear          ();
extern void search                ();

extern void search_update_best    ();
extern void search_update_root    ();
extern void search_update_current ();

extern void search_check          ();

#endif // !defined SEARCH_H

// end of search.h




This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.