summaryrefslogtreecommitdiffstats
path: root/knights/proto_xboard.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'knights/proto_xboard.cpp')
-rw-r--r--knights/proto_xboard.cpp687
1 files changed, 687 insertions, 0 deletions
diff --git a/knights/proto_xboard.cpp b/knights/proto_xboard.cpp
new file mode 100644
index 0000000..8b68bb0
--- /dev/null
+++ b/knights/proto_xboard.cpp
@@ -0,0 +1,687 @@
+/***************************************************************************
+ 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 <qtimer.h>
+#include <qstringlist.h>
+#include <qregexp.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 QTimer( this );
+ connect( InitTimer, SIGNAL( timeout() ), this, 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 )
+{
+ QString 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( QString( "time %1" ).arg( cmd.getWhiteTime() ) );
+ emit output( QString( "otim %1" ).arg( cmd.getBlackTime() ) );
+ }
+ else
+ {
+ emit output( QString( "time %1" ).arg( cmd.getBlackTime() ) );
+ emit output( QString( "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( QString( "time %1" ).arg( cmd.getWhiteTime() ) );
+ else
+ emit output( QString( "time %1" ).arg( cmd.getBlackTime() ) );
+ }
+ break;
+
+ /* Command: Enemy Time */
+ case CMD_Enemy_Time:
+ if( FEATURE_Time )
+ {
+ if( Army == WHITE )
+ emit output( QString( "otim %1" ).arg( cmd.getBlackTime() ) );
+ else
+ emit output( QString( "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( QString( "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 " + QString::number( cmd.getData().toInt() >> 1 ) );
+ break;
+
+ /* Command: Set Name */
+ case CMD_Set_Name:
+ FEATURE_MyName = cmd.getData();
+ break;
+ default:
+ break;
+ }
+}
+///////////////////////////////////////
+//
+// proto_xboard::parse( const QString &string )
+//
+///////////////////////////////////////
+void proto_xboard::parse( const QString &string )
+{
+ QString strIn = string;
+ QStringList strList( QStringList::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( QRegExp("\\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, QString( "%1" ).arg( strIn.right( strIn.length() - 13 ) ) ) );
+ return;
+ }
+
+ /* Tell Others */
+ if( strList[0] == "tellothers" )
+ {
+ emit output( Command( myID, CMD_Tell_Others, QString( "%1" ).arg( strIn.right( strIn.length() - 11 ) ) ) );
+ return;
+ }
+
+ /* Tell All */
+ if( strList[0] == "tellall" )
+ {
+ emit output( Command( myID, CMD_Tell_All, QString( "%1" ).arg( strIn.right( strIn.length() - 8 ) ) ) );
+ return;
+ }
+
+ /* Tell ICS */
+ if( strList[0] == "tellics" )
+ {
+ emit output( Command( myID, CMD_Tell_ICS, QString( "%1" ).arg( strIn.right( strIn.length() - 8 ) ) ) );
+ return;
+ }
+
+ /* Tell ICS No Alias */
+ if( strList[0] == "tellicsnoalias" )
+ {
+ emit output( Command( myID, CMD_Tell_ICS, QString( "%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 = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted ics" );
+ continue;
+ }
+ if( strList[loop].left(3) == "san" )
+ {
+ FEATURE_SAN = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted san" );
+ continue;
+ }
+ if( strList[loop].left(4) == "draw" )
+ {
+ FEATURE_Draw = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted draw" );
+ continue;
+ }
+ if( strList[loop].left(4) == "name" )
+ {
+ FEATURE_Name = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted name" );
+ continue;
+ }
+ if( strList[loop].left(4) == "ping" )
+ {
+ FEATURE_Ping = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted ping" );
+ continue;
+ }
+ if( strList[loop].left(4) == "time" )
+ {
+ FEATURE_Time = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted time" );
+ continue;
+ }
+ if( strList[loop].left(5) == "level" )
+ {
+ FEATURE_Level = QString( strList[loop].right( strList[loop].length() - 6 ) ).toInt();
+ emit output( "accepted level" );
+ continue;
+ }
+ if( strList[loop].left(5) == "pause" )
+ {
+ FEATURE_Pause = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted pause" );
+ continue;
+ }
+ if( strList[loop].left(5) == "reuse" )
+ {
+ FEATURE_Reuse = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted reuse" );
+ continue;
+ }
+ if( strList[loop].left(6) == "colors" )
+ {
+ FEATURE_Colors = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted colors" );
+ continue;
+ }
+ if( strList[loop].left(6) == "myname" )
+ {
+ FEATURE_MyName = QString( strList[loop].right( strList[loop].length() - 8 ) );
+ emit output( "accepted myname" );
+ continue;
+ }
+ if( strList[loop].left(6) == "sigint" )
+ {
+ FEATURE_SIGINT = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted sigint" );
+ continue;
+ }
+ if( strList[loop].left(7) == "analyze" )
+ {
+ FEATURE_Analyze = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted analyze" );
+ continue;
+ }
+ if( strList[loop].left(7) == "sigterm" )
+ {
+ FEATURE_SIGTERM = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted sigterm" );
+ continue;
+ }
+ if( strList[loop].left(8) == "setboard" )
+ {
+ FEATURE_SetBoard = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted setboard" );
+ continue;
+ }
+ if( strList[loop].left(8) == "usermove" )
+ {
+ FEATURE_UserMove = QString( 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 = QString( strList[loop].right(1) ).toInt();
+ emit output( "accepted playother" );
+ continue;
+ }
+ if( strList[loop].left(10) == "bookengine" )
+ {
+ FEATURE_BookEngine = QString( 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();
+}