Author: Uri Blass
Date: 11:22:54 09/29/02
void ponder()
{
/*this function is going to start by make_expected_move and
later choosemove,my idea is that there is going also to be
a function continue_to_ponder and this function is going to be called
during searching when the opponent makes a move.
The function continue_to_ponder may simply continue the search
if the opponent make the expected move or stop the search
in case of unexpected move
I think that an interface should not tell the engine how to ponder
and this is the reason that I do not think to include it in a general
winboard function
I plan in the near future to ponder in the normal way but
I want to design the program in order to give me an option also
to do it in a different way without too many changes*/
}
void new_command()
{
/*we use book when there is a new game*/
UseBook=1;
/*setup set up position in FEN notation*/
setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
computer_side = DARK;
}
void sd_command()
{
sscanf(buffer, "sd %d", &max_depth);
max_time = 1 << 25;
}
void st_command()
{
/*today movei does not support the st command*/
}
void time_command()
{
//max_time is the time in centiseconds
sscanf(buffer, "time %d", &max_time);
/*handletime should calculate the target time and the maximal time
based on the variables max_time and num_moves and increasment
opponent time and the time that already wasted in pondering*/
handletime();
}
void hint_command()
{
/*if the opponent ask for a hint calculate
for the opponent and give a hint*/
choosemove(0);
if (pv[0][0].u)
printf("Hint: %s\n", move_str(pv[0][0].b));
else
printf("mistake");
fflush(stdout);
}
void level_command()
{
sscanf(buffer,"level%d %d %d",&num_moves,&max_time,&increasement);
/*-1 is only a flag that says that we do not know the
ply of first move*/
starting_ply=-1;
if (num_moves>0)
firstnum_moves=num_moves;
else
{
firstnum_moves=INFINIT;
num_moves=INFINIT;
}
}
void setboard_command()
{
char position[256];
char str2[10],str3[10],str4[10],str5[10],str6[10];
UseBook=0;
sscanf(buffer,"setboard%s %s %s %s %s
%s",&position,&str2,&str3,&str4,&str5,&str6);
strcat(position," ");
strcat(position,str2);
strcat(position," ");
strcat(position,str3);
strcat(position," ");
strcat(position,str4);
strcat(position," ");
strcat(position,str5);
strcat(position," ");
strcat(position,str6);
/*a function that help the computer to setup FEN*/
setup(position);
/*we do not know which side is the computer so we set computer_side to
EMPTY*/
computer_side = EMPTY;
}
void remove_command()
{
if (hply<2)
{
unmakemove();
unmakemove();
}
}
void result_command()
{
/*we stop the game when we get the result,learning from the value
is going to be done later*/
computer_side=EMPTY;
/* sscanf(buffer,"result %s ",);*/
}
void analyze_command()
{
UseBook=0;
analyze=ANALYSIS_MODE;
computer_side=EMPTY;
/*wait_flag is changed to 1 only if search is not
needed. It means in mate or stalemate position or if the search
is finished when the program found mate or got maximal depth*/
wait_flag=0;
do
{
if (mateorstalemate())
wait_flag=1;
if (wait_flag==0)
choosemove(YES);
if (wait_flag==1)
fgets(buffer, 256, stdin);
wait_flag=0;
sscanf(buffer, "%s", command);
/*making the move if it is legal*/
makeusermove(buffer);
switch(command[0])
{
case 'u':if (!strcmp(command, "undo"))
{
unmakemove();
continue;
}
break;
case 'n':if (!strcmp(command, "new"))
{
/*we do not use book when we analyze*/
UseBook=0;
setup("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0
1");
continue;
}
break;
case 's':
if (!strcmp(command, "setboard"))
{
setboard_command();
continue;
}
break;
case 'e':
if (!strcmp(command, "exit"))
{
analyze=PLAY_MODE;
continue;
}
break;
case '.':
if (!strcmp(command, "."))
//today last commands are ignored
continue;
break;
case 'b':if (!strcmp(command, "bk"))
continue;
break;
case 'h':if (!strcmp(command, "hint"))
continue;
}
}
while (analyze==ANALYSIS_MODE);
}
void xboard()
{
int i;
signal(SIGINT, SIG_IGN);
printf("\n");
/*input_init called only one time at start_up*/
input_init();
/*computer_side can get only 3 values
LIGHT if the computer is white,DARK if the computer is black
and EMPTY if the game is finished or it is analyzed mode*/
computer_side = EMPTY;
/*analyze can get 3 values ANALYSIS_MODE when the computer analyze
ponder_mode when the computer ponders and PLAY_MODE in other cases*/
analyze=PLAY_MODE;
for (;;)
{
if (side == computer_side)
{
/*printing the result in case that the game is finished*/
if (gamefinished())
{
computer_side=EMPTY;
/*print_result prints with printf the following informatuion based on the
result
"0-1 {Black mates}\n" or
"1-0 {White mates}\n" or
"1/2-1/2 {Stalemate}\n" or
"1/2-1/2 {Draw by insufficient material}\n" or
"1/2-1/2 {Draw by repetition}\n"
"1/2-1/2 {Draw by fifty move rule}\n"*/
print_result();
fflush(stdout);
}
else
{
/*choosemove is the function that choose the move of
the program,it get the move and decides based on the
value of post if to print main lines*/
choosemove(post);
/*num_moves give the number of moves until the
next time control
if the time control is fisher time control
the first value is 999999 moves
so num_moves is very high and is not important
for time allocation
*/
if (computer_side==side)
{
num_moves--;
/*firstnum_moves is the number of moves in level
of x minutes/y moves*/
if (num_moves==0)
num_moves=firstnum_moves;
/*this function make and print the move using printf*/
makeandprintpvmove();
if (gamefinished())
print_result();
else
{
if (ponder_flag==1)
ponder();
}
fflush(stdout);
}
}
}
if (!fgets(buffer, 256, stdin))
return;
if (buffer[0] == '\n')
continue;
sscanf(buffer, "%s", command);
switch(command[0])
{
/*we are not in analysis mode so we can know that
we do not get the exit command so I ignored it*/
case'a':if (!strcmp(command, "analyze"))
{
/*analyze_commands takes us to a different loop
when we get out of it only by exit command*/
analyze_command();
continue;
}
break;
case'e':if (!strcmp(command, "easy"))
{
ponder_flag=0;
continue;
}
break;
case 'f':if (!strcmp(command, "force"))
{
computer_side=EMPTY;
continue;
}
break;
case 'g':if (!strcmp(command, "go"))
{
/*side is the side to move and computer_side is the side
that the the computer plays*/
computer_side=side;
continue;
}
break;
case 'h':switch (command[1])
{
case 'a':if (!strcmp(command, "hard"))
{
ponder_flag=1;
continue;
}
break;
case 'i':if (!strcmp(command, "hint"))
{
hint_command();
continue;
}
}
break;
case 'l':if (!strcmp(command, "level"))
{
level_command();
continue;
}
break;
case 'n':switch (command[1])
{
case 'e':if (!strcmp(command, "new"))
{
new_command();
continue;
}
break;
case 'o':if (!strcmp(command, "nopost"))
{
post=NO;
continue;
}
}
break;
case 'o':if (!strcmp(command, "otim"))
{
/*should be
sscanf(buffer, "opptime %d", &max_time);
when I use it but today I ignore it*/
continue;
}
break;
case 'p':switch (command[1])
{
case 'o':if (!strcmp(command, "post"))
{
post=YES;
continue;
}
break;
case 'r':if (!strcmp(command, "protover"))
{
printf("feature setboard=1 draw=0 done=1
analyze=1\n");
fflush(stdout);
continue;
}
}
break;
case 'q':if (!strcmp(command, "quit"))
return;
break;
case 'r':if (command[1]=='e')
switch (command[2])
{
case 'm':if (!strcmp(command, "remove"))
{
remove_command();
continue;
}
break;
case 's':if (!strcmp(command, "result"))
{
result_command();
continue;
}
}
break;
case 's':switch (command[1])
{
case 'd':if (!strcmp(command, "sd"))
{
sscanf(buffer, "sd %d", &max_depth);
max_time = 1 << 25;
continue;
}
break;
case 'e':if (!strcmp(command, "setboard"))
{
setboard_command();
continue;
}
break;
case 't':if(!strcmp(command, "st"))
{
//need to add
continue;
}
}
break;
case 't':if(!strcmp(command, "time"))
{
time_command();
continue;
}
break;
case 'u':if(!strcmp(command, "undo"))
{/*unmakemove is a function that undo move unless
it is the beginning of the game*/
unmakemove();
computer_side=EMPTY;
continue;
}
break;
case 'x':if(!strcmp(command, "xboard"))
continue;
break;
}
/*makeusermove make the move of the player to move
and returen 0 only if the move is illegal*/
i=makeusermove(buffer);
if (i==0)
{
printf("Error (unknown command): %s\n", command);
fflush(stdout);
}
else
print_result();
}
}
loop when searching
static int is_pipe;
static HANDLE input_handle;
/* Call once at startup. thanks to Dieter for this function and the
same for input_available and part of readwbinput*/
void input_init(void)
{
DWORD dw;
input_handle = GetStdHandle(STD_INPUT_HANDLE);
is_pipe = !GetConsoleMode(input_handle, &dw);
}
int input_available(void)
{
DWORD nchars;
/* When using Standard C input functions, also check if there
is anything in the buffer. After a call to such functions,
the input waiting in the pipe will be copied to the buffer,
and the call to PeekNamedPipe can indicate no input available.
Setting stdin to unbuffered was not enough, IIRC */
//input_init();
if (stdin->_cnt > 0)
return 1;
if (is_pipe)
{
/* When running under a GUI, you will end here. */
if (!PeekNamedPipe(input_handle, NULL, 0, NULL, &nchars, NULL))
return 1;
/* Something went wrong. Probably the parent program exited.
Could call exit() here. Returning 1 will make the next call
to the input function return EOF, where this should be
catched then. */
return nchars != 0;
}
else
return _kbhit(); /* In "text-mode" without GUI */
}
jmp_buf env;
void readwbinput(void)
{
char command[256];
if (input_available())
{
if (fgets(buffer, sizeof buffer, stdin) == NULL)
{
printf("probably broken pipe");
exit(1);
}
/* Now you have the command as a string in buf. */
/* Do something with the contents of buf */
if (sscanf(buffer, "%s", command))
{
/*we have command that we want to read and our actions
can be different in analysis mode,ponder_mode or play_mode*/
switch(analyze)
{
case PLAY_MODE:
switch (command[0])
{
/*we jump to the beginning of the search
undo the moves and go back to the passive loop
if we are asked to move now*/
case'?':if (!strcmp(command, "?"))
{
stop_search=1;
longjmp(env,0);
}
break;
case 'e':if (!strcmp(command, "easy"))
ponder_flag=0;
break;
case 'h':if (!strcmp(command, "hard"))
ponder_flag=1;
break;
case 'r':if (!strcmp(command,"result"))
{
stop_search=1;
longjmp(env,0);
}
break;
case 'f':computer_side=EMPTY;
stop_search=1;
longjmp(env,0);
break;
}
break;
case ANALYSIS_MODE:
/*if command tell us to stop the search
we first stop the search and later
continue process the command*/
if ((!strcmp(command, "undo"))||
(!strcmp(command, "new"))||
(!strcmp(command, "setboard"))||
(!strcmp(command, "exit")))
{
stop_search=1;
longjmp(env, 0);
}
/*maybe the user entered a move
it is also a reason to stop the search and continue later*/
if (legal(command))
{
stop_search=1;
longjmp(env,0);
}
break;
case PONDER_MODE:
switch (command[0])
{
case 't':if(!strcmp(command, "time"))
time_command();
break;
case 'o':if (!strcmp(command,"otim"));
break;
case 'e':if(!strcmp(command, "easy"))
{
stop_search=1;
longjmp(env,0);
}
}
break;
}
}
/* For example in ponder mode, the string might be "time 500\n", which you
must process immediately. It may contain a move, which may mean, if it
is your predicted ponder move, that you just change from "ponder mode" to
"search mode". You will probably want to check the clocks at this time,
and decide, if you actually want to search on, or to return immediately
the sofar best move */
}
}
void checkup(void)
{
if ((analyze==PLAY_MODE)&&(get_ms()>=stop_time))
{
stop_search = 1;
longjmp(env, 0);
}
else
{
/*NodesFrequency is 2^n-1*/
if (((nodes&Nodes_Frequency)==0)&&input_available)
readwbinput();
}
}
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.