
I thought Pulsar could do Shatranj, but the free download does not seem to include it. Just a bunch of other variant, like atomic, losers, 3checks and twokings.
Do there exist other free WinBoard Shatranj engines, or is Fairy-Max now the only one?
Moderator: Ras
Hi Harm,hgm wrote:I recently adapted Fairy-Max to handle scoring of promoting Pawns a bit less silly in variants where they promote to useless pieces, like in Shatranj. As a consequence, it might actually now play at an acceptable level. (What also helps is that it now starts with the King in the coreect positions.) I would like to test that against another Shatranj engine, but I coud not find any.
I thought Pulsar could do Shatranj, but the free download does not seem to include it. Just a bunch of other variant, like atomic, losers, 3checks and twokings.
Do there exist other free WinBoard Shatranj engines, or is Fairy-Max now the only one?
Code: Select all
[NewRival.cpp]
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) writeMessage(VERBOSE, "Receieved Command", count);
if (Verbose) writeMessage(VERBOSE, command);
}
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) writeMessage(VERBOSE, "I have left ", hundreths);
// 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) writeMessage(VERBOSE, "Opposition has left", hundreths);
// 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 (IsDrawPosition()) {
WriteXBoard( "offer draw\n" );
}
} 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) writeMessage(VERBOSE, "ChampTime", Options.ChampTime);
if (Verbose) writeMessage(VERBOSE, "ChampMoves", Options.ChampMoves);
} 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)==0) {
MakeMove(Game, Select);
} else {
char error[200];
char reason[200];
GetReason(Game->VerifyMove(Select), reason);
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();
}
}
Jim.As of v1.5.03, Rival can analyse the winboard.debug file and report the number of
wins for each side following a multi-match game.
To allow Rival to act as an engine for the Winboard interface:
newrival -winboard
Add the following line to the /firstChessProgramNames section of the winboard.ini file.
\"newrival -winboard\" /fd=\"c:\\Program Files\\RivalChess\"
The following is an example of how to run Rival on an ICS, such as the Internet Chess Club.
winboard -zp -ics -icshost chessclub.com -autoflag -fcp "newrival -winboard" -icshelper timestamp
Using the above command you can log into the ICC and type "seek 2 5", for example. Use the
ICC command "+alias gameend seek 2 5" to allow the program to play unattended.
An example of how to launch Winboard for two engines to play each other 50 times is
winboard /cp /tc 1 /inc 2 /mg 50
...you can then select the two engines from the Winboard front screen.
Rival does not support all Winboard commands. The following Winboard
commands are supported when recieved by Rival:
new
white
black
go
level
time
otim
move
draw
quit
edit
post
nopost
easy
hard
Rival sends out the following commands to Winboard:
move MOVE
offer draw
1-0 {White Mates}
0-1 {Black Mates}
1/2-1/2 {Stalemate}
1/2-1/2 {Draw by Repetition}
1/2-1/2 {Draw by Fifty Moves}
Illegal move (reason): move