You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
knights/knights/proto_xboard.cpp

688 lines
15 KiB

/***************************************************************************
proto_xboard.cpp - description
-------------------
begin : Sat Oct 26 2002
copyright : (C) 2003 by Troy Corbin Jr.
email : tcorbin@users.sf.net
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <klocale.h>
#include <tqtimer.h>
#include <tqstringlist.h>
#include <tqregexp.h>
#include "proto_xboard.moc"
#include "definitions.h"
proto_xboard::proto_xboard( const int ID ) : proto_base( ID )
{
FEATURE_Analyze = TRUE;
FEATURE_Colors = TRUE;
FEATURE_Draw = TRUE;
FEATURE_ICS = FALSE;
FEATURE_Name = TRUE;
FEATURE_Pause = FALSE;
FEATURE_Ping = FALSE;
FEATURE_PlayOther = FALSE;
FEATURE_Reuse = TRUE;
FEATURE_SetBoard = FALSE;
FEATURE_SAN = FALSE;
FEATURE_SIGINT = TRUE;
FEATURE_SIGTERM = TRUE;
FEATURE_Time = TRUE;
FEATURE_UserMove = FALSE;
FEATURE_Variants = 0;
FEATURE_Level = 1;
FEATURE_BookEngine = 0;
CMDList = new CommandList;
InitTimer = new TQTimer( this );
connect( InitTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( releaseBuffer() ) );
Check = TRUE;
Team = FALSE;
JustMoved = FALSE;
AcceptIllegal = FALSE;
DelayedGo = FALSE;
Forced = TRUE;
Turn = WHITE;
}
proto_xboard::~proto_xboard()
{
delete InitTimer;
delete CMDList;
}
///////////////////////////////////////
//
// proto_xboard::parse( const Command &command )
//
///////////////////////////////////////
void proto_xboard::parse( const Command &command )
{
TQString temp;
Command cmd = command;
if( InitTimer->isActive() )
{
/*
Store Command for later use..
we're still waiting for the engine to finish
*/
CMDList->append( command );
return;
}
switch( cmd.getCommand() )
{
/* Command: Init */
case CMD_Init:
emit output( "xboard\nprotover 3" );
InitTimer->start( 2000, TRUE );
break;
/* Command: New Game */
case CMD_NewGame:
emit output( "new\nrandom" );
break;
/* Command: Exit */
case CMD_Exit:
emit output( "quit" );
if( FEATURE_SIGTERM )
emit output( Command( myID, CMD_Send_SIGTERM ) );
break;
/* Command: Move Now */
case CMD_MoveNow:
emit output( "?" );
break;
/* Command: Move */
case CMD_Move:
if( JustMoved )
{
JustMoved = FALSE;
break;
}
AcceptIllegal = TRUE;
myMove = cmd.getMove();
/* Send Time */
if( FEATURE_Time )
{
if( Army == WHITE )
{
emit output( TQString( "time %1" ).arg( cmd.getWhiteTime() ) );
emit output( TQString( "otim %1" ).arg( cmd.getBlackTime() ) );
}
else
{
emit output( TQString( "time %1" ).arg( cmd.getBlackTime() ) );
emit output( TQString( "otim %1" ).arg( cmd.getWhiteTime() ) );
}
}
if( FEATURE_UserMove )
temp = "usermove ";
if( FEATURE_SAN )
temp += myMove.SAN;
else
temp += myMove.CAN;
if( DelayedGo )
{
DelayedGo = FALSE;
temp += "\ngo";
Forced = FALSE;
}
emit output( temp );
break;
/* Command: Pause */
case CMD_Pause:
if( FEATURE_Pause )
emit output( "pause" );
else
{
emit output( "force" );
Forced = TRUE;
}
break;
/* Command: Resume */
case CMD_Resume:
if( FEATURE_Pause )
emit output( "resume" );
else
{
if( Turn == Army )
{
emit output( "go" );
Forced = FALSE;
}
else
DelayedGo = TRUE;
}
break;
/* Command: Play White */
case CMD_Play_White:
Army = WHITE;
if( Turn == BLACK )
{
if( FEATURE_PlayOther )
{
emit output( "playother" );
}
else if( FEATURE_Colors )
{
emit output( "black" );
}
else
{
emit output( "force" );
Forced = TRUE;
DelayedGo = TRUE;
}
break;
}
else
{
temp = "force";
if( FEATURE_Colors )
temp += "\nwhite";
temp += "\ngo";
emit output( temp );
break;
}
break;
/* Command: Play Black */
case CMD_Play_Black:
Army = BLACK;
if( Turn == WHITE )
{
if( FEATURE_PlayOther )
{
emit output( "playother" );
}
else if( FEATURE_Colors )
{
emit output( "white" );
}
else
{
emit output( "force" );
Forced = TRUE;
DelayedGo = TRUE;
}
break;
}
else
{
temp = "force";
if( FEATURE_Colors )
temp += "\nblack";
temp += "\ngo";
emit output( temp );
break;
}
break;
/* Command: Result White */
case CMD_Result_White:
emit output( "result 1-0 {White Mates}" );
AcceptIllegal = FALSE;
// if( Army == WHITE )
// (*IT).Wins++;
// else
// (*IT).Losses++;
break;
/* Command: Result Black */
case CMD_Result_Black:
emit output( "result 0-1 {Black Mates}" );
AcceptIllegal = FALSE;
// if( Army == BLACK )
// (*IT).Wins++;
// else
// (*IT).Losses++;
break;
/* Command: Result Draw */
case CMD_Result_Draw:
emit output( "result 1/2-1/2 {Draw Game}" );
AcceptIllegal = FALSE;
// (*IT).Draws++;
break;
/* Command: Your Time */
case CMD_Your_Time:
if( FEATURE_Time )
{
if( Army == WHITE )
emit output( TQString( "time %1" ).arg( cmd.getWhiteTime() ) );
else
emit output( TQString( "time %1" ).arg( cmd.getBlackTime() ) );
}
break;
/* Command: Enemy Time */
case CMD_Enemy_Time:
if( FEATURE_Time )
{
if( Army == WHITE )
emit output( TQString( "otim %1" ).arg( cmd.getBlackTime() ) );
else
emit output( TQString( "otim %1" ).arg( cmd.getWhiteTime() ) );
}
break;
/* Command: Offer Draw */
case CMD_Offer_Draw:
if( FEATURE_Draw )
emit output( "draw" );
break;
/* Command: Book Mode */
case CMD_Book_Mode:
if( FEATURE_BookEngine != 0 )
emit output( "bookengine" );
break;
/* Command: Check Book */
case CMD_Check_Book:
emit output( "go" );
Forced = FALSE;
break;
/* Command: Ponder */
case CMD_Ponder:
emit output( "hard" );
break;
/* Command: No Pondering */
case CMD_No_Pondering:
emit output( "hard\neasy" );
break;
/* Command: Retract Move */
case CMD_Retract_Move:
emit output( "remove" );
break;
/* Command: Hint */
case CMD_Hint:
emit output( "hint" );
break;
/* Command: Listen */
case CMD_Listen:
emit output( "force" );
Forced = TRUE;
DelayedGo = FALSE;
break;
/* Command: Play */
case CMD_Play:
if( Army == Turn )
{
emit output( "go" );
Forced = FALSE;
}
else
DelayedGo = TRUE;
break;
/* Command: White Resign */
case CMD_White_Resign:
parse( Command( 0, CMD_Result_White ) );
break;
/* Command: Black Resign */
case CMD_Black_Resign:
parse( Command( 0, CMD_Result_Black ) );
break;
/* Command: Set Board */
case CMD_Set_Board:
if( FEATURE_SetBoard == TRUE )
{
emit output( TQString( "setboard %1" ).arg( cmd.getData() ) );
}
else
{
// Convert FEN to edit commands here and feed them to engine
}
break;
/* Command: Set Difficulty */
case CMD_Set_Difficulty:
emit output( "sd " + cmd.getData() );
// emit output( "st " + TQString::number( cmd.getData().toInt() >> 1 ) );
break;
/* Command: Set Name */
case CMD_Set_Name:
FEATURE_MyName = cmd.getData();
break;
default:
break;
}
}
///////////////////////////////////////
//
// proto_xboard::parse( const TQString &string )
//
///////////////////////////////////////
void proto_xboard::parse( const TQString &string )
{
TQString strIn = string;
TQStringList strList( TQStringList::split( ' ', strIn ) );
if( ( FEATURE_SIGINT ) && ( !Forced ) )
emit output( Command( myID, CMD_Send_SIGINT ) );
/* Illegal */
if( strList[0].contains( "illegal", FALSE ) )
{
if( AcceptIllegal )
{
if( strIn.contains("(no matching move)board") )
return;
if( strIn.contains("(no matching move)protover") )
return;
if( strIn.contains("(no matching move)sd") )
return;
AcceptIllegal = FALSE;
emit output( Command( myID, CMD_Illegal ) );
}
return;
}
/* A Move */
if( strList[0] == "move" )
{
if( strList.count() < 2 )
{
kdWarning() << "proto_xboard::parse: Incomplete Move command" << endl;
return;
}
Command::clearMove( &myMove );
strcpy( myMove.SAN, strList[1].latin1() );
strcpy( myMove.CAN, strList[1].latin1() );
if( Team )
{
emit output( "force" );
Forced = TRUE;
}
JustMoved = TRUE;
emit output( Command( myID, CMD_Move, 0, 0, myMove ) );
return;
}
/* A Move ( Old Variation ) */
if( ( strList[0].contains( TQRegExp("\\d+\\.") ) ) && ( strList[1] == "..." ) )
{
Command::clearMove( &myMove );
strcpy( myMove.SAN, strList[2].latin1() );
strcpy( myMove.CAN, strList[2].latin1() );
if( Team )
{
emit output( "force" );
Forced = TRUE;
}
JustMoved = TRUE;
emit output( Command( myID, CMD_Move, 0, 0, myMove ) );
return;
}
/* Hint */
if( strList[0] == "Hint:" )
{
emit output( Command( myID, CMD_Hint, i18n( "%1 suggests this move:\n%2" ).arg( FEATURE_MyName ).arg( strList[1] ) ) );
return;
}
/* Offer Draw */
if( ( strList[0] == "offer" ) && ( strList[1] == "draw" ) )
{
emit output( Command( myID, CMD_Offer_Draw ) );
}
/* Out of Book */
if( strList[0] == "outofbook" )
{
emit output( "force" );
Forced = TRUE;
emit output( Command( myID, CMD_Out_Of_Book ) );
return;
}
/* Tell User */
if( strList[0] == "telluser" )
{
emit output( Command( myID, CMD_Tell_User, i18n( "%1 tells you:\n%2" ).arg( FEATURE_MyName ).arg( strIn.right( strIn.length() - 9 ) ) ) );
return;
}
/* Tell User Error */
if( strList[0] == "tellusererror" )
{
emit output( Command( myID, CMD_Tell_User_Error, i18n( "%1 tells you:\n%2" ).arg( FEATURE_MyName ).arg( strIn.right( strIn.length() - 14 ) ) ) );
return;
}
/* Error */
if( strList[0] == "Error" )
{
emit output( Command( myID, CMD_Tell_User_Error, i18n( "%1 tells you:\n%2" ).arg( FEATURE_MyName ).arg( strIn.right( strIn.length() ) ) ) );
return;
}
/* Tell Opponent */
if( strList[0] == "tellopponent" )
{
emit output( Command( myID, CMD_Tell_Opponent, TQString( "%1" ).arg( strIn.right( strIn.length() - 13 ) ) ) );
return;
}
/* Tell Others */
if( strList[0] == "tellothers" )
{
emit output( Command( myID, CMD_Tell_Others, TQString( "%1" ).arg( strIn.right( strIn.length() - 11 ) ) ) );
return;
}
/* Tell All */
if( strList[0] == "tellall" )
{
emit output( Command( myID, CMD_Tell_All, TQString( "%1" ).arg( strIn.right( strIn.length() - 8 ) ) ) );
return;
}
/* Tell ICS */
if( strList[0] == "tellics" )
{
emit output( Command( myID, CMD_Tell_ICS, TQString( "%1" ).arg( strIn.right( strIn.length() - 8 ) ) ) );
return;
}
/* Tell ICS No Alias */
if( strList[0] == "tellicsnoalias" )
{
emit output( Command( myID, CMD_Tell_ICS, TQString( "%1" ).arg( strIn.right( strIn.length() - 15 ) ) ) );
return;
}
/* Resign */
if( strIn.contains( "resign", FALSE ) )
{
if( Army == WHITE )
emit output( Command( myID, CMD_White_Resign ) );
else
emit output( Command( myID, CMD_Black_Resign ) );
return;
}
/*
Parse Features
*/
if( !InitTimer->isActive() )
return;
for( unsigned int loop = 0; loop < strList.count(); loop++ )
{
if( strList[loop] == "done=1" )
{
InitTimer->stop();
releaseBuffer();
continue;
}
/* This buys you 10 minutes */
if( strList[loop] == "done=0" )
{
InitTimer->changeInterval( 600000 );
continue;
}
if( strList[loop] == "feature" )
{
continue;
}
if( strList[loop].left(3) == "ics" )
{
FEATURE_ICS = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted ics" );
continue;
}
if( strList[loop].left(3) == "san" )
{
FEATURE_SAN = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted san" );
continue;
}
if( strList[loop].left(4) == "draw" )
{
FEATURE_Draw = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted draw" );
continue;
}
if( strList[loop].left(4) == "name" )
{
FEATURE_Name = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted name" );
continue;
}
if( strList[loop].left(4) == "ping" )
{
FEATURE_Ping = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted ping" );
continue;
}
if( strList[loop].left(4) == "time" )
{
FEATURE_Time = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted time" );
continue;
}
if( strList[loop].left(5) == "level" )
{
FEATURE_Level = TQString( strList[loop].right( strList[loop].length() - 6 ) ).toInt();
emit output( "accepted level" );
continue;
}
if( strList[loop].left(5) == "pause" )
{
FEATURE_Pause = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted pause" );
continue;
}
if( strList[loop].left(5) == "reuse" )
{
FEATURE_Reuse = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted reuse" );
continue;
}
if( strList[loop].left(6) == "colors" )
{
FEATURE_Colors = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted colors" );
continue;
}
if( strList[loop].left(6) == "myname" )
{
FEATURE_MyName = TQString( strList[loop].right( strList[loop].length() - 8 ) );
emit output( "accepted myname" );
continue;
}
if( strList[loop].left(6) == "sigint" )
{
FEATURE_SIGINT = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted sigint" );
continue;
}
if( strList[loop].left(7) == "analyze" )
{
FEATURE_Analyze = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted analyze" );
continue;
}
if( strList[loop].left(7) == "sigterm" )
{
FEATURE_SIGTERM = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted sigterm" );
continue;
}
if( strList[loop].left(8) == "setboard" )
{
FEATURE_SetBoard = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted setboard" );
continue;
}
if( strList[loop].left(8) == "usermove" )
{
FEATURE_UserMove = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted usermove" );
continue;
}
if( strList[loop].left(8) == "variants" )
{
// FIFO_Tmp = strList[loop].right( strList[loop].length() - 10 );
// This must be finished
emit output( "accepted variants" );
continue;
}
if( strList[loop].left(9) == "playother" )
{
FEATURE_PlayOther = TQString( strList[loop].right(1) ).toInt();
emit output( "accepted playother" );
continue;
}
if( strList[loop].left(10) == "bookengine" )
{
FEATURE_BookEngine = TQString( strList[loop].right( strList[loop].length() - 11 ) ).toInt();
emit output( "accepted bookengine" );
continue;
}
}
}
///////////////////////////////////////
//
// proto_xboard::releaseBuffer
//
///////////////////////////////////////
void proto_xboard::releaseBuffer( void )
{
CommandList::Iterator it;
for( it = CMDList->begin(); it != CMDList->end(); it++ )
{
parse( *it );
}
CMDList->clear();
}