/*************************************************************************** match.cpp - description ------------------- begin : Mon Jul 2 2001 copyright : (C) 2003 by Troy Corbin Jr. email : tcorbin@users.sourceforge.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 #include #include "match.moc" #include "board_base.h" #include "board_2d.h" #include "audio.h" #define WHITE_INPUT Record->Param->type(WHITE) #define BLACK_INPUT Record->Param->type(BLACK) /////////////////////////////////////// // // match::match // /////////////////////////////////////// match::match( QWidget *parent, match_param *param, resource *Rsrc ) : QWidget(parent) { Resource = Rsrc; /* Init Children */ Record = new pgn( Resource, param ); Logic = new logic( Resource, param ); Board = new board_2d( parent, "Board", Resource, Logic ); Board->show(); connect( Board, SIGNAL( leftClick(int) ), this, SLOT( slot_Select(int) ) ); connect( Board, SIGNAL( rightClick(int) ), this, SLOT( slot_Preview(int) ) ); Clock = new chessclock( this, "Clock", Resource ); Record->init(); Logic->Init(); Clock->Reset(); clearSelections(); /* Init Variables */ Draw_Offered[WHITE] = FALSE; Draw_Offered[BLACK] = FALSE; Modified = FALSE; Loading = FALSE; Paused = FALSE; JustMoved = FALSE; preMoved = FALSE; Current = FALSE; loadTimer = 0; StatusCode = READY; StatusMessage = QString::null; ICSGameMode = Null; parseMatchParam(); /* Connect Signals and Slots */ connect( param, SIGNAL( valuesChanged() ), this, SLOT( parseMatchParam() ) ); connect( Record, SIGNAL( processMove(ChessMove) ), this, SLOT( move(ChessMove) ) ); connect( Record, SIGNAL( processSpecial() ), this, SLOT( loadSpecial() ) ); connect( Clock, SIGNAL( flagFell(const bool) ), this, SLOT( slot_flagFell(const bool) ) ); connect( this, SIGNAL( setStatusBar( const int&, const QString& ) ), this, SLOT( saveStatusBar( const int&, const QString& ) ) ); } /////////////////////////////////////// // // match::~match // /////////////////////////////////////// match::~match() { delete Clock; if( Board != NULL ) delete Board; delete Record; delete Logic; } /////////////////////////////////////// // // match::setVisibility // /////////////////////////////////////// void match::setVisibility( const bool vis ) { if( vis == TRUE ) { show(); Board->show(); setEnabled( TRUE ); } else { hide(); Board->hide(); setEnabled( FALSE ); } } /////////////////////////////////////// // // match::parseMatchParam // /////////////////////////////////////// void match::parseMatchParam( void ) { switch( BLACK_INPUT ) { case PLAYERLOCAL: Board->setLocalArmy( BLACK ); break; } switch( WHITE_INPUT ) { case PLAYERLOCAL: Board->setLocalArmy( WHITE ); break; } } /////////////////////////////////////// // // match::tick // /////////////////////////////////////// void match::tick(void) { Clock->Tick(); emit setClocks(); if( Loading ) { if( loadTimer ) loadTimer--; else { /* All this is for a match we just finished loading */ if( !Record->loadNext() ) { Loading = FALSE; emit sendCMD( Command( myID, CMD_Play ) ); if( Record->TAG_Result == "*" ) { /* Unfinished Game */ Clock->Set( Record->whiteTime, Record->blackTime, onMove() ); } else { /* Finished Match */ Clock->Pause(); if( Record->TAG_Result == "1/2-1/2" ) emit setStatusBar( GAME_DRAW ); if( Record->TAG_Result == "1-0" ) emit setStatusBar( WHITE_WIN ); if( Record->TAG_Result == "0-1" ) emit setStatusBar( BLACK_WIN ); } } } } } /////////////////////////////////////// // // match::clearSelections // /////////////////////////////////////// void match::clearSelections( void ) { bool commitFlag( FALSE ); register char tmp; if( ICSGameMode == Null ) { for( tmp = 0; tmp < 64; tmp++ ) { if( Logic->current[tmp].Note != NOTE_NONE ) { Logic->current[tmp].Note = NOTE_NONE; Board->drawPosition( tmp ); commitFlag = TRUE; } } } else { for( tmp = 0; tmp < 64; tmp++ ) { Logic->current[tmp].Note = NOTE_NONE; Board->drawPosition( tmp ); commitFlag = TRUE; } } if( commitFlag ) { Board->commit(); } } /////////////////////////////////////// // // match::flip // /////////////////////////////////////// void match::flip(void) { Board->flipBoard(); } /////////////////////////////////////// // // match::resize // /////////////////////////////////////// void match::resize(void) { Board->resizeBoard(); setFixedSize( Board->width(), Board->height() ); } /////////////////////////////////////// // // match::redraw // /////////////////////////////////////// void match::redraw(void) { Board->redrawAll(); } /////////////////////////////////////// // // match::slot_flagFell // /////////////////////////////////////// void match::slot_flagFell( const bool Army ) { if( Army == WHITE ) { emit setStatusBar( WHITE_FLAG ); if( ( Resource->OPTION_Auto_Call_Flag ) && ( WHITE_INPUT != PLAYERLOCAL ) && ( BLACK_INPUT == PLAYERLOCAL ) ) { emit sendCMD( Command( myID, CMD_Black_Called_Flag ) ); recvCMD( Command( myID, CMD_Black_Called_Flag ) ); } } else { emit setStatusBar( BLACK_FLAG ); if( ( Resource->OPTION_Auto_Call_Flag ) && ( BLACK_INPUT != PLAYERLOCAL ) && ( WHITE_INPUT == PLAYERLOCAL ) ) { emit sendCMD( Command( myID, CMD_White_Called_Flag ) ); recvCMD( Command( myID, CMD_White_Called_Flag ) ); } } } /////////////////////////////////////// // // match::setPaused // /////////////////////////////////////// void match::setPaused( const bool State ) { Paused = State; Board->setPaused( State ); if( Paused ) { Clock->Pause(); emit setStatusBar( PAUSED ); } else { Clock->Resume(); if( onMove() == WHITE ) emit setStatusBar( WHITE_TURN ); else emit setStatusBar( BLACK_TURN ); } } /////////////////////////////////////// // // match::inputOnMove // /////////////////////////////////////// char match::inputOnMove( bool reverse ) { if( reverse ) { if( Logic->OnMove == BLACK ) return WHITE_INPUT; if( Logic->OnMove == WHITE ) return BLACK_INPUT; } else { if( Logic->OnMove == WHITE ) return WHITE_INPUT; if( Logic->OnMove == BLACK ) return BLACK_INPUT; } return Null; } /////////////////////////////////////// // // match::input // /////////////////////////////////////// char match::input( char army ) { return Record->Param->type(army); } /////////////////////////////////////// // // match::save // /////////////////////////////////////// bool match::save( QString URL ) { Record->whiteTime = Clock->getCentiseconds(WHITE); Record->blackTime = Clock->getCentiseconds(BLACK); return Record->save( URL ); } /////////////////////////////////////// // // match::load // /////////////////////////////////////// bool match::load( const QString URL, const int pos ) { bool Result; Loading = TRUE; loadTimer = 20; if( !Record->open( URL ) ) { return FALSE; } Result = Record->load( pos ); if( !Record->TAG_FEN.isEmpty() ) { // We must set up the FEN position Logic->setBoardFromFen( Record->TAG_FEN ); sendCMD( Command( myID, CMD_Set_Board, Record->TAG_FEN ) ); } return Result; } /////////////////////////////////////// // // match::loadSpecial // /////////////////////////////////////// void match::loadSpecial( void ) { /* As pointless as this function may seem ( in light of these variables and more being setup in tick(), it is required to initialize a Chess Engine and feed it the moves from a saved game so you can play it again later. */ emit sendCMD( Command( myID, CMD_New_Players ) ); } /////////////////////////////////////// // // match::url // /////////////////////////////////////// QString match::url( void ) { if( !Record->CurrentURL.isEmpty() ) return Record->CurrentURL; if( Resource->OPTION_Reuse_PGN ) return Resource->PGN_Filename; return QString::null; } /////////////////////////////////////// // // match::clock // /////////////////////////////////////// QString match::clock( const bool Army ) { if( Army == WHITE ) return Clock->whiteClock; return Clock->blackClock; } /////////////////////////////////////// // // match::slot_Select // /////////////////////////////////////// void match::slot_Select( int position ) { bool preMoving(FALSE); register char tmp, army, selected(Null); if( Paused ) return; /* Clear all non-SELECT notes */ for( tmp = 0;tmp < 64;tmp++ ) { if( Logic->current[tmp].Note != NOTE_NONE ) { if( Logic->current[tmp].Note != NOTE_SELECT ) { Logic->current[tmp].Note = NOTE_NONE; Board->drawPosition( tmp ); } else { selected = tmp; } } } Board->commit(); /* Check to make sure it's our turn to select. */ if( !( inputOnMove() & PLAYERLOCAL ) ) { if( ( inputOnMove(TRUE) == PLAYERLOCAL ) && ( Resource->OPTION_Premove ) ) { preMoving = TRUE; } else { return; } } /* If you left click on a selected square, it becomes unselected. */ if( Logic->current[position].Note == NOTE_SELECT ) { Logic->current[position].Note = NOTE_NONE; drawPosition( position ); playSound( SND_SELECT ); return; } if( preMoved ) { preMoved = FALSE; playSound( SND_SELECT ); Board->setPremovePositions( Null, Null ); Board->drawPosition( Logic->Pointer( preMove.fromFile, preMove.fromRank ) ); Board->drawPosition( Logic->Pointer( preMove.toFile, preMove.toRank ) ); Board->commit(); } /* Check to see if there is already a selected square. */ if( selected != Null ) { /* If there is already a selected square, and you just clicked on another of your men, we'll change your selection. */ if( Logic->current[position].ManPtr != Null ) { if( Logic->chessman[ Logic->current[selected].ManPtr ].Army == Logic->chessman[ Logic->current[position].ManPtr ].Army ) { Logic->current[selected].Note = NOTE_NONE; Logic->current[position].Note = NOTE_SELECT; Board->drawPosition( selected ); drawPosition( position ); if( Resource->OPTION_Auto_Preview == TRUE ) slot_Preview( position ); else playSound( SND_SELECT ); return; } } /* If there is already a selected square, but this one you just clicked isn't one of your chessmen, you must want to move a piece. */ if( ( Record->currentIndex != ( Record->Positions.count() - 1 ) ) && ( Record->currentIndex ) ) { emit setStatusBar( NO_MOVE_WHILE_REVIEW ); return; } if( preMoving ) { Command::clearMove( &preMove ); preMove.fromRank = Logic->current[selected].Rank; preMove.fromFile = Logic->current[selected].File; preMove.toRank = Logic->current[position].Rank; preMove.toFile = Logic->current[position].File; preMoved = TRUE; playSound( SND_SELECT ); Board->setPremovePositions( selected, position ); } else { Command::clearMove( &chessMove ); chessMove.fromRank = Logic->current[selected].Rank; chessMove.fromFile = Logic->current[selected].File; chessMove.toRank = Logic->current[position].Rank; chessMove.toFile = Logic->current[position].File; JustMoved = TRUE; if( move() == FALSE ) { Logic->current[selected].Note = NOTE_SELECT; drawPosition( selected ); } } return; } tmp = Logic->current[position].ManPtr; /* You can't select an empty square. */ if( tmp == Null ) { return; } army = Logic->chessman[ tmp ].Army; /* You can't select your enemy */ if( ( army != onMove() ) && ( preMoving == FALSE ) ) { return; } /* If your clicking on one of your chessmen, you can select it. */ clearSelections(); if( ( army == WHITE ) && ( WHITE_INPUT & PLAYERLOCAL ) ) { Logic->current[position].Note = NOTE_SELECT; } if( ( army == BLACK ) && ( BLACK_INPUT & PLAYERLOCAL ) ) { Logic->current[position].Note = NOTE_SELECT; } drawPosition( position ); if( Resource->OPTION_Auto_Preview == TRUE ) { slot_Preview( position ); } else { /* Play the select sound if you selected a square & you didn't preview */ if( Logic->current[position].Note == NOTE_SELECT ) { playSound( SND_SELECT ); } } } /////////////////////////////////////// // // match::slot_Preview // /////////////////////////////////////// void match::slot_Preview( int position ) { char tmp; if( Paused ) { return; } clearSelections(); tmp = Logic->current[position].ManPtr; if( tmp == Null ) return; Logic->HashLegal( tmp ); /* If your clicking on one of your chessmen, you can select it. */ if( ( Logic->chessman[tmp].Army == Logic->OnMove ) && ( Record->Param->type( Logic->OnMove ) & PLAYERLOCAL ) ) Logic->current[position].Note = NOTE_SELECT; for( tmp = 0;tmp < 64;tmp++ ) { if( Logic->current[tmp].Note != NOTE_NONE ) { Board->drawPosition( tmp ); } } drawPosition( 0 ); playSound( SND_SELECT ); } /////////////////////////////////////// // // match::recvCMD // /////////////////////////////////////// void match::recvCMD( const Command &constCommand ) { Command cmd( constCommand ); if( cmd.getID() != myID ) return; ChessMove newMove = cmd.getMove(); switch( cmd.getCommand() ) { /* CMD_Move */ case CMD_Move: if( newMove.ICS_Mode == Null ) { /* Not an ICS Move */ move( newMove ); } else { /* Do NOT accept a setBoard on a concluded match */ if( ( Logic->OnMove == -1 ) && ( newMove.ICS_Mode < ICS_Examine ) ) return; ICSGameMode = newMove.ICS_Mode; Logic->OnMove = newMove.ICS_OnMove; if( ICSGameMode == ICS_Movelist ) { /* Recieving Movelist */ Logic->chessMove = newMove; Logic->parseSAN(); JustMoved = FALSE; } else { /* Recieving Standard Move */ Logic->setBoard( cmd.getData(), newMove.ICS_PawnPushFile ); Logic->MoveCounter = newMove.ICS_MoveCounter; Logic->chessMove = newMove; Logic->parseCAN( Logic->OnMove ); } chessMove = Logic->chessMove; /* Run through the Move function */ if( !JustMoved ) move(); else { JustMoved = FALSE; Logic->OnMove = !Logic->OnMove; } Clock->Set( cmd.getWhiteTime(), cmd.getBlackTime(), !newMove.ICS_OnMove ); if( newMove.ICS_ClockTicking ) { Clock->Resume(); } else { Clock->Pause(); } } break; /* CMD_Offer_Draw */ case CMD_Offer_Draw: if( cmd.getData() == "W" ) { Draw_Offered[WHITE] = 2; emit setStatusBar( WHITE_DRAW_OFFER ); } else { Draw_Offered[BLACK] = 2; emit setStatusBar( BLACK_DRAW_OFFER ); } break; /* CMD_Illegal */ case CMD_Illegal: retract(); emit setNotation(); break; /* Lost Contact */ case CMD_Lost_Contact: Clock->Pause(); Logic->OnMove = -1; emit setStatusBar( LOST_CONTACT ); Record->TAG_Result = "*"; Record->TAG_Termination = "Lost Contact with Opponent"; break; /* Result White */ case CMD_Result_White: Clock->Pause(); Logic->OnMove = -1; emit setStatusBar( WHITE_CHECKMATE ); Record->TAG_Result = "1-0"; Record->TAG_Termination = "Normal"; break; /* Result Black */ case CMD_Result_Black: Clock->Pause(); Logic->OnMove = -1; emit setStatusBar( BLACK_CHECKMATE ); Record->TAG_Result = "0-1"; Record->TAG_Termination = "Normal"; break; /* Result Draw */ case CMD_Result_Draw: Clock->Pause(); Logic->OnMove = -1; if( Logic->MoveCounter == 50 ) { emit setStatusBar( GAME_50_MOVES ); } else { emit setStatusBar( GAME_DRAW ); } Record->TAG_Result = "1/2-1/2"; break; /* White Resign */ case CMD_White_Resign: Clock->Pause(); Logic->OnMove = -1; emit setStatusBar( WHITE_RESIGN ); Record->TAG_Result = "0-1"; Record->TAG_Termination = "White resigned"; break; /* Black Resign */ case CMD_Black_Resign: Clock->Pause(); Logic->OnMove = -1; emit setStatusBar( BLACK_RESIGN ); Record->TAG_Result = "1-0"; Record->TAG_Termination = "Black resigned"; break; /* White Called Flag */ case CMD_White_Called_Flag: Clock->Pause(); Logic->OnMove = -1; emit setStatusBar( WHITE_CALL_FLAG ); Record->TAG_Result = "1-0"; Record->TAG_Termination = "Black's flag was called"; break; /* Black Called Flag */ case CMD_Black_Called_Flag: Clock->Pause(); Logic->OnMove = -1; emit setStatusBar( BLACK_CALL_FLAG ); Record->TAG_Result = "0-1"; Record->TAG_Termination = "White's flag was called"; break; default: break; } } /////////////////////////////////////// // // match::move // /////////////////////////////////////// bool match::move( ChessMove newMove ) { /* Clear selections from the board */ clearSelections(); Logic->chessMove = newMove; if( Logic->parseCAN( onMove() ) != TRUE ) { if( Logic->parseSAN() != TRUE ) { kdDebug() << "#" << myID << ": Recieved bad data: " << newMove.CAN << endl; return FALSE; } } chessMove = Logic->chessMove; JustMoved = TRUE; return move(); } bool match::move( void ) { int soundType( SND_MOVE ); int result(Null); char manPtr(Null); QString SAN; /* Bring the display up to the latest move before we proceed */ if( ICSGameMode == Null ) { if( Record->currentIndex != ( Record->Positions.count() - 1 ) ) { review( Record->Moves.count() - 1 ); } } /* Clear selections from the board */ clearSelections(); /* Build Pointers */ char fromPtr = ( chessMove.fromRank << 3 ) + chessMove.fromFile; char toPtr = ( chessMove.toRank << 3 ) + chessMove.toFile; /* Skip all this if we're being called due to normal server moves */ if( ( JustMoved == TRUE ) || ( ICSGameMode == ICS_Movelist ) ) { if( ( fromPtr > 63 ) || ( toPtr > 63 ) ) return FALSE; if( ( fromPtr < 0 ) || ( toPtr < 0 ) ) return FALSE; manPtr = Logic->current[fromPtr].ManPtr; if( manPtr == Null ) return FALSE; /* Make the move */ Logic->chessMove = chessMove; if( Logic->Move() == FALSE ) return FALSE; chessMove = Logic->chessMove; } /* Play sound for Promotion */ if( QString( chessMove.SAN ).contains( QChar( '=' ) ) ) { soundType = SND_PROMOTE; } /* Check to see if the game is ended */ /* 50 Move Rule? */ if( Logic->MoveCounter == 50 ) { result = CMD_Result_Draw; } /* A Draw via 3 move repeat if( Record->isThreeMoveDraw() ) { result = CMD_Result_Draw; Record->TAG_Result = "1/2-1/2"; emit setStatusBar( GAME_DRAW ); } */ /* A Draw? Condition 1 = White Material Draw Condition 2 = Black Material Draw Condition 3 = Both sides agree to a draw */ if( ( Logic->OnMove == BLACK && Logic->isDraw( WHITE ) ) || ( Logic->OnMove == WHITE && Logic->isDraw( BLACK ) ) || ( Draw_Offered[WHITE] && Draw_Offered[BLACK] ) ) { result = CMD_Result_Draw; } /* Is White under check? */ if( Logic->isCheck( WHITE ) ) { if( !Logic->isLegal( WHITE ) ) { SAN += '#'; result = CMD_Result_Black; } else { SAN += '+'; soundType = SND_CHECK; } } /* Is Black under check? */ if( Logic->isCheck( BLACK ) ) { if( !Logic->isLegal( BLACK ) ) { SAN += '#'; result = CMD_Result_White; } else { SAN += '+'; soundType = SND_CHECK; } } /* Check to make sure this isn't the starting position in an ICS match */ if( QString( chessMove.SAN ) != "none" ) { if( !SAN.isEmpty() ) { strcat( chessMove.SAN, SAN.latin1() ); } Record->Positions << Logic->board(); Record->Moves << chessMove; Record->currentIndex = Record->Moves.count() - 1; if( JustMoved == TRUE ) { /* Send this move to engines and servers */ emit sendCMD( Command( myID, CMD_Move, centiseconds( WHITE ), centiseconds( BLACK ), chessMove, Record->notation(FALSE)->join(QString(" ")) ) ); } /* Draw The Move */ if( ICSGameMode != ICS_Movelist ) Board->drawMove( chessMove ); } /* Take care of changing turns, status messages, etc. */ if( result == Null ) { Clock->Moved(); if( Paused ) Clock->Pause(); Logic->OnMove = !Logic->OnMove; /* Set Status Bar */ if( Logic->OnMove == WHITE ) { emit setStatusBar( WHITE_TURN ); } if( Logic->OnMove == BLACK ) { emit setStatusBar( BLACK_TURN ); } /* Set Cursor */ if( ( inputOnMove(TRUE) == PLAYERLOCAL ) && ( inputOnMove() != PLAYERLOCAL ) ) { Board->setCursor( Resource->CURSOR_Thinking ); } else { Board->setCursor( Resource->CURSOR_Standard ); } /* Deprecieate Draw Offers */ if( Draw_Offered[WHITE] ) { Draw_Offered[WHITE]--; } if( Draw_Offered[BLACK] ) { Draw_Offered[BLACK]--; } /* Display NAG Anotation */ if( chessMove.NAG != 0 ) { emit setStatusBar( COMMENT + chessMove.NAG ); } } else { /* End of Match */ Board->setCursor( Resource->CURSOR_Standard ); recvCMD( Command( myID, result ) ); emit sendCMD( Command( myID, result ) ); soundType = SND_MATCH_OVER; } emit setNotation(); if( ICSGameMode != ICS_Movelist ) { Board->redrawLights(); Board->commit(); } /* Play the Sound */ playSound( soundType ); /* Handle special cases */ if( loading() ) { loadTimer = 10; // Loading... } else { Modified = TRUE; } if( preMoved ) { preMoved = FALSE; Board->setPremovePositions( Null, Null ); chessMove = preMove; JustMoved = TRUE; move(); } /* if( inputOnMove() == PLAYEREMAIL ) { Clock->Pause(); // Email KMessageBox::questionYesNo( this, i18n("Would you like to email this move?"), i18n("Send Email?") ); } */ return TRUE; } /////////////////////////////////////// // // match::retract // /////////////////////////////////////// void match::retract( void ) { emit setStatusBar(ILLEGAL_MOVE); review( Record->Moves.count() - 2 ); _retract(); } void match::_retract( void ) { if( Record->Moves.count() ) { Record->Moves.remove( Record->Moves.at( Record->Moves.count() - 1 ) ); Record->Positions.remove( Record->Positions.at( Record->Positions.count() - 1 ) ); Record->currentIndex = Record->Moves.count() - 1; } } /////////////////////////////////////// // // match::review // /////////////////////////////////////// void match::review( const int Index ) { int tmp(0), step; QString tmpS; if( ICSGameMode == ICS_Examine ) { /* Examined Game: Use Examine Semantics */ if( Index < (signed)Record->currentIndex ) step = -1; else step = 1; if( ( Record->currentIndex == 0 ) && ( Index == 0 ) && ( step == 1 ) ) { emit sendCMD( Command( myID, CMD_Examine_Forward ) ); } if( step == 1 ) { for( tmp = Record->currentIndex; tmp != Index; tmp += step ) { emit sendCMD( Command( myID, CMD_Examine_Forward ) ); } } else { for( tmp = Record->currentIndex; tmp != Index; tmp += step ) { _retract(); _retract(); emit sendCMD( Command( myID, CMD_Examine_Backward ) ); } } } else { /* Regular Game: Use Standard Review Semantics */ if( Record->Positions.count() == 0 ) return; if( Index < 0 ) return; if( Index > ( (signed int)Record->Positions.count() - 1 ) ) return; /* Review differently depending on our Animation Option */ if( Resource->OPTION_Animate_Moves ) { if( (unsigned)Index > Record->currentIndex ) { /* Forward */ Logic->setBoard( Record->Positions[Index - 1] ); while( tmp < 64 ) Board->drawPosition( tmp++ ); Logic->setBoard( Record->Positions[Index] ); Board->drawMove( Record->Moves[Index] ); } else if( (unsigned)Index < Record->currentIndex ) { /* Reverse */ Logic->setBoard( Record->Positions[Index + 1] ); while( tmp < 64 ) Board->drawPosition( tmp++ ); Board->drawMove( Record->Moves[Index + 1], TRUE ); Logic->setBoard( Record->Positions[Index] ); } } else { /* No Animation */ Logic->setBoard( Record->Positions[Index] ); while( tmp < 64 ) Board->drawPosition( tmp++ ); Board->drawMove( Record->Moves[Index] ); } Board->commit(); /* Statusbar shows NAG if available, otherwise Army to move */ if( Record->Moves[Index].NAG ) { tmp = StatusCode; tmpS = StatusMessage; emit setStatusBar( COMMENT + Record->Moves[Index].NAG ); StatusCode = tmp; StatusMessage = tmpS; } else emit setStatusBar( StatusCode, StatusMessage ); Record->currentIndex = Index; } } /////////////////////////////////////// // // match::playSound // /////////////////////////////////////// void match::playSound( const int snd ) { if( Resource->OPTION_Audio_Current_Only && !Current ) { return; } Resource->play( snd ); } /////////////////////////////////////// // // match::drawPosition // /////////////////////////////////////// void match::drawPosition( const int position ) { Board->drawPosition( position ); Board->commit(); } /////////////////////////////////////// // // match::requestHint // /////////////////////////////////////// void match::requestHint( void ) { emit sendCMD( Command( myID, CMD_Hint ) ); emit sendCMD( Command( myID, CMD_UCI_Hint, centiseconds( WHITE ), centiseconds( BLACK ), Record->notation(FALSE)->join(QString(" ")) ) ); }