Author: Chris Moreton
Date: 17:01:01 01/01/99
Go up one level in this thread
Personally, I think the post is completely on topic and this is exactly the sort
of topic that makes me use CCC. I have successfully interfaced my non-console
application Rival with Winboard. The code can be downloaded from
http://dialspace.dial.pipex.com/chris.moreton/howto.shtml. I use Borland C++
4.52 rather than Visual C++ (although as soon as I can get it together to
convert to MFC I am going to do so (by the way - if anyone has successfully
compiled an OWL application with MFC I'd really like to know how to do it!!))
Anyway, here is how I interfaced Rival with Winboard.
On a timer, I call the method TRivalWindow::MonitorXBoard which uses scanf to
read from the input buffer. I then parse the commands appropriately. When
Rival has chosen a move I send it to the TRivalWindow::SendXBoard method.
I advise downloading the code, although I'll paste below but I guess the
formatting may go up the wall even if you copying and paste them out of here.
Hope this helps. Don't hesitate to ask for more help if needed.
Best Regards
Chris
void
TRivalWindow::MonitorXBoard()
{
char c;
static char PreviousCommand[100];
static count=0;
count++;
if (count>1) strcpy(PreviousCommand, command);
scanf( "%s", command);
if ((command[0]=='{' ||
(command[0]>='a' && command[0]<='z') ||
(command[0]>='A' && command[0]<='Z') ||
(command[0]>='0' && command[0]<='9'))) {
if (Verbose) {
FILE *log = fopen(VERBOSE, "a");
fprintf( log, "\nReceived Command %i: %s", count, command );
fclose(log);
}
}
if (strcmp("quit", command)==0) {
CloseWindow();
} else
if (strcmp("edit", command)==0) {
int colour=WHITE;
if (strcmp(PreviousCommand, "a2a3")==0) {
Game->Square[MOVER]=BLACK;
}
int NewBoard[89];
int finished=FALSE;
int piece=EMPTY;
char editcom[10];
while (!finished) {
scanf("%s", editcom);
if (strcmp(editcom, "#")==0) {
for (int i=0; i<89; i++)
NewBoard[i]=EMPTY;
} else
if (strcmp(editcom, "c")==0) {
colour=(colour==WHITE ? BLACK : WHITE);
} else
if (strcmp(editcom, ".")==0) {
finished=TRUE;
} else {
switch (editcom[0]) {
case 'P' : piece=PAWN; break;
case 'Q' : piece=QUEEN; break;
case 'R' : piece=ROOK; break;
case 'N' : piece=KNIGHT; break;
case 'B' : piece=BISHOP; break;
case 'K' : piece=KING; break;
}
int newx=editcom[1]-(int)'a'+1;
int newy=editcom[2]-(int)'0';
NewBoard[newx*10+newy]=piece+100*(colour==BLACK);
NewBoard[MOVER]=Game->GetMover();
NewBoard[WROOK1MOVED]=!(NewBoard[11]==WR);// &&
Game->GetMover()==BLACK);
NewBoard[WROOK8MOVED]=!(NewBoard[81]==WR);// &&
Game->GetMover()==BLACK);
NewBoard[BROOK1MOVED]=!(NewBoard[18]==BR);// &&
Game->GetMover()==WHITE);
NewBoard[BROOK8MOVED]=!(NewBoard[88]==BR);// &&
Game->GetMover()==WHITE);
NewBoard[WKINGMOVED]=!(NewBoard[51]==WR);// && Game->GetMover()==BLACK);
NewBoard[BKINGMOVED]=!(NewBoard[58]==BR);// && Game->GetMover()==WHITE);
NewBoard[ENPAWN]=0;
NewBoard[FIFTYMOVES]=0;
NewBoard[MOVER]=Game->GetMover();
}
}
delete Game;
Game=new TChessBoard(NewBoard);
Options.ComputerWhite=FALSE;
Options.ComputerBlack=FALSE;
} else
if (strcmp("undo", command)==0) {
// Game->TakeBackMove();
} else
if (strcmp("time", command)==0) {
int hundreths;
scanf("%i", &hundreths);
if (Verbose) {
FILE *log = fopen(VERBOSE, "a");
fprintf(log, "\nI have left: %i", hundreths);
fclose(log);
}
// current mover is the opposition
if (Game->GetMover()==WHITE) {
Game->SetBlackClock(hundreths*10);
} else {
Game->SetWhiteClock(hundreths*10);
}
} else
if (strcmp("otim", command)==0) {
int hundreths;
scanf("%i", &hundreths);
if (Verbose) {
FILE *log = fopen(VERBOSE, "a");
fprintf(log, "\nOpposition has left: %i", hundreths);
fclose(log);
}
// current mover is the opposition
if (Game->GetMover()==WHITE) {
Game->SetWhiteClock(hundreths*10);
} else {
Game->SetBlackClock(hundreths*10);
}
} else
if (strcmp("easy", command)==0) {
Options.Ponder = FALSE;
} else
if (strcmp("hard", command)==0) {
Options.Ponder = TRUE;
} else
if (strcmp("post", command)==0) {
Options.ShowAnalysis = TRUE;
} else
if (strcmp("nopost", command)==0) {
Options.ShowAnalysis = FALSE;
} else
if (strcmp("white", command)==0) {
Options.ComputerBlack = TRUE;
Options.ComputerWhite = FALSE;
Game->Square[MOVER]=WHITE;
} else
if (strcmp("black", command)==0) {
Options.ComputerWhite = TRUE;
Options.ComputerBlack = FALSE;
Game->Square[MOVER]=BLACK;
} else
if (strcmp("draw", command)==0) {
if ((lastvalue<80 && Game->TotalMovesMade()>40) ||
lastvalue<Options.Contempt) {
WriteXBoard( "offer draw\n" );
}
Options.ComputerWhite = FALSE;
Options.ComputerBlack = TRUE;
} else
if (strcmp("level", command)==0) {
int moves, minutes, increment;
scanf("%i", &moves);
scanf("%i", &minutes);
scanf("%i", &increment);
Options.Level = 2;
Options.ChampMoves=moves;
Options.ChampTime=minutes*60;
Options.BaseMinutes=minutes;
Options.Increment=increment;
if (moves==0) {
searchmethod=Options.SearchMethod=BASEINCREMENT;
} else {
searchmethod=Options.SearchMethod=CHAMPIONSHIP;
}
if (Verbose) {
FILE *log = fopen( VERBOSE, "a" );
fprintf(log, "\nChampTime %i, ChampMoves %i\n",
Options.ChampTime, Options.ChampMoves );
fclose(log);
}
} else
if (strcmp("force", command)==0) {
Options.ComputerWhite=false;
Options.ComputerBlack=false;
} else
if (strcmp("new", command)==0) {
CmNewGame();
} else
if (strcmp("go", command)==0) {
if (!GameOver()) {
if (Game->GetMover()==WHITE) {
Options.ComputerWhite=true;
Options.ComputerBlack=false;
} else {
Options.ComputerBlack=true;
Options.ComputerWhite=false;
}
if ((Options.ComputerWhite && Game->GetMover()==WHITE) ||
(Options.ComputerBlack && Game->GetMover()==BLACK)) {
if (Options.Ponder) ComputerMoveFlag = TRUE;
else ComputerMove();
}
}
} else
if ( command[0]>='a' && command[0]<='h' &&
command[1]>='1' && command[1]<='8' &&
command[2]>='a' && command[2]<='h' &&
command[3]>='1' && command[3]<='8') {
int x1 = command[0]-(int)'a'+1;
int y1 = command[1]-(int)'0';
int x2 = command[2]-(int)'a'+1;
int y2 = command[3]-(int)'0';
TPoint p1( BoardOffsetX+5+(Pawn->Width()*(x1-1)),
BoardOffsetY+5+(Pawn->Height()*(8-y1)));
TPoint p2( BoardOffsetX+5+(Pawn->Width()*(x2-1)),
BoardOffsetY+5+(Pawn->Height()*(8-y2)));
if (command[4]=='q' || command[4]=='Q') Select.PromotionPiece=QUEEN;
if (command[4]=='r' || command[4]=='R') Select.PromotionPiece=ROOK;
if (command[4]=='b' || command[4]=='B') Select.PromotionPiece=BISHOP;
if (command[4]=='n' || command[4]=='N') Select.PromotionPiece=KNIGHT;
if (Verbose) {
int s1x=(p1.x-BoardOffsetX)/Pawn->Width()+1;
int s1y=8-((p1.y-BoardOffsetY)/Pawn->Height());
int s2x=(p2.x-BoardOffsetX)/Pawn->Width()+1;
int s2y=8-((p2.y-BoardOffsetY)/Pawn->Height());
FILE *log = fopen(VERBOSE, "a");
fprintf( log, "\nMaking opposition move: %c%c-%c%c-%c with
%i%i-%i%i-%i\n",
(char)x1+'a'-1, (char)y1+'0', (char)x2+'a'-1, (char)y2+'0', command[4],
s1x,s1y,s2x,s2y, Select.PromotionPiece );
fclose(log);
}
Select.From = x1*10+y1;
Select.To = x2*10+y2;
if (Game->VerifyMove(Select)) {
MakeMove(Game, Select);
} else {
char error[200];
char reason[200];
GetReason(Game->VerifyMove(Select));
sprintf(error, "Illegal Move (%s): %c%c%c%c%c",
reason,
command[0],
command[1],
command[2],
command[3],
(strlen(command)>4 ? command[4] : ' '));
WriteXBoard(error);
}
if ((Game->GetMover()==WHITE && Options.ComputerWhite)
|| (Game->GetMover()==BLACK && Options.ComputerBlack))
makeWinboardComputerMove();
}
}
void
TRivalWindow::WriteXBoard(char* message) {
if (Verbose) {
FILE *log = fopen(VERBOSE, "a");
fprintf( log, "\nSending Command: %s", message );
fclose(log);
}
printf( message );
fflush(stdout);
}
void
TRivalWindow::SendXBoard(TMove move)
{
if (move.PromotionPiece!=EMPTY) {
sprintf( messagetext, "move %c%c%c%c\n",
GetX(move.From)+'a'-1,
GetY(move.From)+'0',
GetX(move.To)+'a'-1,
GetY(move.To)+'0' );
} else {
char Promote;
switch (move.PromotionPiece) {
case QUEEN : Promote='Q'; break;
case KNIGHT : Promote='N'; break;
case BISHOP : Promote='B'; break;
case ROOK : Promote='R'; break;
}
sprintf( messagetext, "move %c%c%c%c=%c\n",
GetX(move.From)+'a'-1,
GetY(move.From)+'0',
GetX(move.To)+'a'-1,
GetY(move.To)+'0',
Promote );
}
setbuf(stdout, NULL);
WriteXBoard(messagetext);
}
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.