mirror of
git://git.savannah.nongnu.org/eliot.git
synced 2025-01-29 20:34:56 +01:00
Added auto-execution of commands when clearing future commands.
The goal is to automatically replay commands involving AI, so that the user cannot be 'blocked'.
This commit is contained in:
parent
59345dbbdf
commit
67306bec3e
10 changed files with 48 additions and 12 deletions
|
@ -23,7 +23,7 @@
|
|||
|
||||
|
||||
Command::Command()
|
||||
: m_executed(false)
|
||||
: m_executed(false), m_autoExecution(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,17 @@ class Command
|
|||
*/
|
||||
bool isExecuted() const { return m_executed; }
|
||||
|
||||
/**
|
||||
* Mark the command as auto-executable, which means that it will
|
||||
* be automatically executed if the commands history is cleared
|
||||
* just before this command.
|
||||
* Auto-executable commands correspond to commands for AI players,
|
||||
* for which the user cannot change the behaviour.
|
||||
*/
|
||||
void setAutoExecution(bool autoExec) { m_autoExecution = autoExec; }
|
||||
/// Return true if the command is auto-executable
|
||||
virtual bool isAutoExecution() const { return m_autoExecution; }
|
||||
|
||||
/**
|
||||
* Description of the command, for debugging purposes
|
||||
*/
|
||||
|
@ -69,6 +80,7 @@ class Command
|
|||
|
||||
private:
|
||||
bool m_executed;
|
||||
bool m_autoExecution;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,12 +61,12 @@ int Duplicate::play(const wstring &iCoord, const wstring &iWord)
|
|||
if (res == 0)
|
||||
{
|
||||
// Everything is OK, we can play the word
|
||||
recordPlayerMove(Move(round), currPlayer);
|
||||
recordPlayerMove(Move(round), currPlayer, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Record the invalid move of the player
|
||||
recordPlayerMove(Move(iWord, iCoord), currPlayer);
|
||||
recordPlayerMove(Move(iWord, iCoord), currPlayer, true);
|
||||
}
|
||||
|
||||
// Little hack to handle duplicate games with only AI players.
|
||||
|
@ -93,7 +93,7 @@ void Duplicate::playAI(unsigned int p)
|
|||
ASSERT(false, "AI tried to cheat!");
|
||||
}
|
||||
|
||||
recordPlayerMove(move, *player);
|
||||
recordPlayerMove(move, *player, false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -164,12 +164,14 @@ void Duplicate::tryEndTurn()
|
|||
}
|
||||
|
||||
|
||||
void Duplicate::recordPlayerMove(const Move &iMove, Player &ioPlayer)
|
||||
void Duplicate::recordPlayerMove(const Move &iMove, Player &ioPlayer, bool isForHuman)
|
||||
{
|
||||
Command *pCmd = new PlayerMoveCmd(ioPlayer, iMove);
|
||||
pCmd->setAutoExecution(!isForHuman);
|
||||
accessNavigation().addAndExecute(pCmd);
|
||||
|
||||
Command *pCmd2 = new MarkPlayedCmd(*this, ioPlayer.getId(), true);
|
||||
pCmd2->setAutoExecution(!isForHuman);
|
||||
accessNavigation().addAndExecute(pCmd2);
|
||||
}
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ private:
|
|||
Duplicate(const Dictionary &iDic);
|
||||
|
||||
/// Record a player move
|
||||
void recordPlayerMove(const Move &iMove, Player &ioPlayer);
|
||||
void recordPlayerMove(const Move &iMove, Player &ioPlayer, bool isForHuman);
|
||||
|
||||
/// Make the AI player whose ID is p play its turn
|
||||
void playAI(unsigned int p);
|
||||
|
|
|
@ -66,14 +66,14 @@ int FreeGame::play(const wstring &iCoord, const wstring &iWord)
|
|||
Move move(round);
|
||||
|
||||
// Update the rack and the score of the current player
|
||||
recordPlayerMove(move, *m_players[m_currPlayer]);
|
||||
recordPlayerMove(move, *m_players[m_currPlayer], true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Move move(iWord, iCoord);
|
||||
|
||||
// Record the invalid move of the player
|
||||
recordPlayerMove(move, *m_players[m_currPlayer]);
|
||||
recordPlayerMove(move, *m_players[m_currPlayer], true);
|
||||
}
|
||||
|
||||
// Next turn
|
||||
|
@ -100,15 +100,17 @@ void FreeGame::playAI(unsigned int p)
|
|||
}
|
||||
|
||||
// Update the rack and the score of the current player
|
||||
recordPlayerMove(move, *player);
|
||||
recordPlayerMove(move, *player, false);
|
||||
|
||||
endTurn();
|
||||
}
|
||||
|
||||
|
||||
void FreeGame::recordPlayerMove(const Move &iMove, Player &ioPlayer)
|
||||
void FreeGame::recordPlayerMove(const Move &iMove, Player &ioPlayer,
|
||||
bool isForHuman)
|
||||
{
|
||||
Command *pCmd = new PlayerMoveCmd(ioPlayer, iMove);
|
||||
pCmd->setAutoExecution(!isForHuman);
|
||||
accessNavigation().addAndExecute(pCmd);
|
||||
}
|
||||
|
||||
|
@ -275,7 +277,7 @@ int FreeGame::pass(const wstring &iToChange)
|
|||
|
||||
Move move(iToChange);
|
||||
// End the player's turn
|
||||
recordPlayerMove(move, player);
|
||||
recordPlayerMove(move, player, true);
|
||||
|
||||
// Next game turn
|
||||
endTurn();
|
||||
|
|
|
@ -86,7 +86,7 @@ private:
|
|||
void playAI(unsigned int p);
|
||||
|
||||
/// Record a player move
|
||||
void recordPlayerMove(const Move &iMove, Player &ioPlayer);
|
||||
void recordPlayerMove(const Move &iMove, Player &ioPlayer, bool isForHuman);
|
||||
|
||||
/// Finish the current turn
|
||||
int endTurn();
|
||||
|
|
|
@ -145,6 +145,11 @@ void Navigation::lastTurn()
|
|||
|
||||
void Navigation::clearFuture()
|
||||
{
|
||||
// Replay the auto-execution turns
|
||||
// (i.e. turns where only the AI was involved)
|
||||
while (!isLastTurn() && m_turnCommands[m_currTurn]->isAutoExecution())
|
||||
nextTurn();
|
||||
|
||||
// When there is no future, don't do anything
|
||||
if (isLastTurn())
|
||||
return;
|
||||
|
|
|
@ -59,6 +59,7 @@ void Training::setRackRandom(bool iCheck, set_rack_mode mode)
|
|||
const PlayedRack &newRack =
|
||||
helperSetRackRandom(getCurrentPlayer().getCurrentRack(), iCheck, mode);
|
||||
Command *pCmd = new PlayerRackCmd(*m_players[m_currPlayer], newRack);
|
||||
pCmd->setAutoExecution(false);
|
||||
accessNavigation().addAndExecute(pCmd);
|
||||
}
|
||||
|
||||
|
@ -130,6 +131,7 @@ void Training::recordPlayerMove(const Move &iMove, Player &ioPlayer)
|
|||
// (called in this class in endTurn()).
|
||||
// See the big comment in game.cpp, line 96
|
||||
Command *pCmd = new PlayerMoveCmd(ioPlayer, iMove);
|
||||
pCmd->setAutoExecution(false);
|
||||
accessNavigation().addAndExecute(pCmd);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,17 @@ void TurnCmd::doUndo()
|
|||
}
|
||||
|
||||
|
||||
bool TurnCmd::isAutoExecution() const
|
||||
{
|
||||
BOOST_FOREACH(Command *cmd, m_commands)
|
||||
{
|
||||
if (!cmd->isAutoExecution())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
wstring TurnCmd::toString() const
|
||||
{
|
||||
wostringstream oss;
|
||||
|
|
|
@ -46,6 +46,8 @@ class TurnCmd: public Command
|
|||
|
||||
bool isEmpty() const { return m_commands.empty(); }
|
||||
|
||||
virtual bool isAutoExecution() const;
|
||||
|
||||
virtual wstring toString() const;
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Add table
Reference in a new issue