mirror of
git://git.savannah.nongnu.org/eliot.git
synced 2025-01-13 20:03:23 +01:00
Topping: keep track of the player score
This commit is contained in:
parent
0ea56cc442
commit
7e9dab2e9b
6 changed files with 104 additions and 20 deletions
|
@ -31,10 +31,11 @@ INIT_LOGGER(game, PlayerEventCmd);
|
||||||
PlayerEventCmd::PlayerEventCmd(Player &ioPlayer, EventType iEvent, int iPoints)
|
PlayerEventCmd::PlayerEventCmd(Player &ioPlayer, EventType iEvent, int iPoints)
|
||||||
: m_player(ioPlayer), m_eventType(iEvent), m_points(iPoints)
|
: m_player(ioPlayer), m_eventType(iEvent), m_points(iPoints)
|
||||||
{
|
{
|
||||||
ASSERT(iEvent == PENALTY || iEvent == END_GAME || iPoints >= 0,
|
// Solos and warnings are always positive
|
||||||
"Negative points not allowed");
|
ASSERT(iEvent != SOLO || iPoints >= 0, "Negative points not allowed");
|
||||||
ASSERT(iEvent != PENALTY || iPoints <= 0,
|
ASSERT(iEvent != WARNING || iPoints >= 0, "Negative points not allowed");
|
||||||
"Positive points not allowed");
|
// Penalties are negative in arbitration mode, but positive in topping mode
|
||||||
|
// End game points are positive for one player and negative for all the other players
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -262,6 +262,18 @@ void PublicGame::toppingPlay(const wstring &iWord, const wstring &iCoord, int iE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PublicGame::toppingTimeOut()
|
||||||
|
{
|
||||||
|
getTypedGame<Topping>(m_game).turnTimeOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PublicGame::toppingAddPenalty(int iPenalty)
|
||||||
|
{
|
||||||
|
getTypedGame<Topping>(m_game).addPenalty(iPenalty);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
vector<Move> PublicGame::toppingGetTriedMoves() const
|
vector<Move> PublicGame::toppingGetTriedMoves() const
|
||||||
{
|
{
|
||||||
return getTypedGame<Topping>(m_game).getTriedMoves();
|
return getTypedGame<Topping>(m_game).getTriedMoves();
|
||||||
|
|
|
@ -226,6 +226,10 @@ public:
|
||||||
|
|
||||||
void toppingPlay(const wstring &iWord, const wstring &iCoord, int iElapsed);
|
void toppingPlay(const wstring &iWord, const wstring &iCoord, int iElapsed);
|
||||||
|
|
||||||
|
void toppingTimeOut();
|
||||||
|
|
||||||
|
void toppingAddPenalty(int iPenalty);
|
||||||
|
|
||||||
vector<Move> toppingGetTriedMoves() const;
|
vector<Move> toppingGetTriedMoves() const;
|
||||||
|
|
||||||
Move toppingGetTopMove() const;
|
Move toppingGetTopMove() const;
|
||||||
|
|
|
@ -38,7 +38,9 @@
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "turn.h"
|
#include "turn.h"
|
||||||
#include "cmd/topping_move_cmd.h"
|
#include "cmd/topping_move_cmd.h"
|
||||||
|
#include "cmd/player_rack_cmd.h"
|
||||||
#include "cmd/player_move_cmd.h"
|
#include "cmd/player_move_cmd.h"
|
||||||
|
#include "cmd/player_event_cmd.h"
|
||||||
#include "cmd/game_move_cmd.h"
|
#include "cmd/game_move_cmd.h"
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
|
|
||||||
|
@ -105,8 +107,7 @@ void Topping::tryWord(const wstring &iWord, const wstring &iCoord, int iElapsed)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// End the turn
|
// End the turn
|
||||||
// FIXME
|
recordPlayerMove(move, *m_players[m_currPlayer], iElapsed);
|
||||||
recordPlayerMove(move, *m_players[m_currPlayer]);
|
|
||||||
|
|
||||||
// Next turn
|
// Next turn
|
||||||
endTurn();
|
endTurn();
|
||||||
|
@ -114,6 +115,38 @@ void Topping::tryWord(const wstring &iWord, const wstring &iCoord, int iElapsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Topping::turnTimeOut()
|
||||||
|
{
|
||||||
|
LOG_INFO("Timeout reached, finishing turn automatically");
|
||||||
|
|
||||||
|
m_board.removeTestRound();
|
||||||
|
|
||||||
|
// Commented out, because the player already has
|
||||||
|
// an empty move by default
|
||||||
|
#if 0
|
||||||
|
// The player didn't find the move
|
||||||
|
Command *pCmd = new PlayerMoveCmd(*m_players[m_currPlayer], Move());
|
||||||
|
accessNavigation().addAndExecute(pCmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Give a penalty to the player
|
||||||
|
// XXX: should we give the penalty directly in the NO_MOVE move?
|
||||||
|
// TODO: get the value from the preferences instead of hard-coding
|
||||||
|
addPenalty(180);
|
||||||
|
|
||||||
|
// Next turn
|
||||||
|
endTurn();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Topping::addPenalty(int iPenalty)
|
||||||
|
{
|
||||||
|
Command *pCmd = new PlayerEventCmd(*m_players[m_currPlayer],
|
||||||
|
PlayerEventCmd::PENALTY, iPenalty);
|
||||||
|
accessNavigation().addAndExecute(pCmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int Topping::play(const wstring &, const wstring &)
|
int Topping::play(const wstring &, const wstring &)
|
||||||
{
|
{
|
||||||
ASSERT(false, "The play() method should not be called in topping mode");
|
ASSERT(false, "The play() method should not be called in topping mode");
|
||||||
|
@ -123,15 +156,19 @@ int Topping::play(const wstring &, const wstring &)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Topping::recordPlayerMove(const Move &iMove, Player &ioPlayer)
|
void Topping::recordPlayerMove(const Move &iMove, Player &ioPlayer, int iElapsed)
|
||||||
{
|
{
|
||||||
// FIXME: the score of the player should not be the score of the move in topping mode
|
ASSERT(iMove.isValid(), "Only valid rounds should be played");
|
||||||
LOG_INFO("Player " << ioPlayer.getId() << " plays: " << lfw(iMove.toString()));
|
// Modify the score of the given move, to be the elapsed time
|
||||||
|
Round copyRound = iMove.getRound();
|
||||||
|
copyRound.setPoints(iElapsed);
|
||||||
|
Move newMove(copyRound);
|
||||||
|
|
||||||
// Update the rack and the score of the current player
|
// Update the rack and the score of the current player
|
||||||
// PlayerMoveCmd::execute() must be called before Game::helperPlayMove()
|
// PlayerMoveCmd::execute() must be called before Game::helperPlayMove()
|
||||||
// (called in this class in endTurn()).
|
// (called in this class in endTurn()).
|
||||||
// See the big comment in game.cpp, line 96
|
// See the big comment in game.cpp, line 96
|
||||||
Command *pCmd = new PlayerMoveCmd(ioPlayer, iMove);
|
Command *pCmd = new PlayerMoveCmd(ioPlayer, newMove);
|
||||||
accessNavigation().addAndExecute(pCmd);
|
accessNavigation().addAndExecute(pCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,12 +181,18 @@ bool Topping::isFinished() const
|
||||||
|
|
||||||
void Topping::endTurn()
|
void Topping::endTurn()
|
||||||
{
|
{
|
||||||
// Play the word on the board
|
// Play the top move on the board
|
||||||
const Move &move = m_players[m_currPlayer]->getLastMove();
|
const Move &move = getTopMove();
|
||||||
Command *pCmd = new GameMoveCmd(*this, move, m_currPlayer);
|
Command *pCmd = new GameMoveCmd(*this, move, m_currPlayer);
|
||||||
accessNavigation().addAndExecute(pCmd);
|
accessNavigation().addAndExecute(pCmd);
|
||||||
accessNavigation().newTurn();
|
accessNavigation().newTurn();
|
||||||
|
|
||||||
|
// Make sure that the player has the correct rack
|
||||||
|
// (in case he didn't find the top, or not the same one)
|
||||||
|
Command *pCmd2 = new PlayerRackCmd(*m_players[m_currPlayer],
|
||||||
|
getHistory().getCurrentRack());
|
||||||
|
accessNavigation().addAndExecute(pCmd2);
|
||||||
|
|
||||||
// Start next turn...
|
// Start next turn...
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
|
@ -174,7 +217,7 @@ void Topping::addPlayer(Player *iPlayer)
|
||||||
Move Topping::getTopMove() const
|
Move Topping::getTopMove() const
|
||||||
{
|
{
|
||||||
BestResults results;
|
BestResults results;
|
||||||
results.search(getDic(), getBoard(), m_players[0]->getCurrentRack().getRack(),
|
results.search(getDic(), getBoard(), getHistory().getCurrentRack().getRack(),
|
||||||
getHistory().beforeFirstRound());
|
getHistory().beforeFirstRound());
|
||||||
ASSERT(results.size() != 0, "No top move found");
|
ASSERT(results.size() != 0, "No top move found");
|
||||||
return Move(results.get(0));
|
return Move(results.get(0));
|
||||||
|
|
|
@ -77,12 +77,25 @@ public:
|
||||||
*/
|
*/
|
||||||
Move getTopMove() const;
|
Move getTopMove() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate that the player didn't find the top in the allocated time.
|
||||||
|
* This will play the top on the board, give a points penalty to the player
|
||||||
|
* and start the next turn.
|
||||||
|
*/
|
||||||
|
void turnTimeOut();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give an additional penalty to the player (probably because
|
||||||
|
* he used a hint)
|
||||||
|
*/
|
||||||
|
void addPenalty(int iPenalty);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Private constructor and destructor to force using the GameFactory class
|
/// Private constructor and destructor to force using the GameFactory class
|
||||||
Topping(const GameParams &iParams, const Game *iMasterGame);
|
Topping(const GameParams &iParams, const Game *iMasterGame);
|
||||||
|
|
||||||
/// Record a player move
|
/// Record a player move
|
||||||
void recordPlayerMove(const Move &iMove, Player &ioPlayer);
|
void recordPlayerMove(const Move &iMove, Player &ioPlayer, int iElapsed);
|
||||||
|
|
||||||
void endTurn();
|
void endTurn();
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include <QtGui/QStandardItemModel>
|
#include <QtGui/QStandardItemModel>
|
||||||
#include <QtGui/QMenu>
|
#include <QtGui/QMenu>
|
||||||
#include <QtGui/QHeaderView>
|
#include <QtGui/QMessageBox>
|
||||||
#include <QtGui/QSortFilterProxyModel>
|
#include <QtGui/QSortFilterProxyModel>
|
||||||
|
|
||||||
#include "topping_widget.h"
|
#include "topping_widget.h"
|
||||||
|
@ -60,7 +60,7 @@ ToppingWidget::ToppingWidget(QWidget *parent, PlayModel &iPlayModel,
|
||||||
|
|
||||||
TimerWidget *timerWidget = new TimerWidget(this, iTimerModel);
|
TimerWidget *timerWidget = new TimerWidget(this, iTimerModel);
|
||||||
timerWidget->setEnabled(false);
|
timerWidget->setEnabled(false);
|
||||||
iTimerModel.setChronoMode(true);
|
//iTimerModel.setChronoMode(true);
|
||||||
QObject::connect(&iTimerModel, SIGNAL(expired()),
|
QObject::connect(&iTimerModel, SIGNAL(expired()),
|
||||||
this, SLOT(timeoutPenalty()));
|
this, SLOT(timeoutPenalty()));
|
||||||
layout->addWidget(timerWidget);
|
layout->addWidget(timerWidget);
|
||||||
|
@ -228,15 +228,26 @@ void ToppingWidget::playWord(const wstring &iWord, const wstring &iCoord)
|
||||||
|
|
||||||
void ToppingWidget::hintUsed(const AbstractHint &iHint)
|
void ToppingWidget::hintUsed(const AbstractHint &iHint)
|
||||||
{
|
{
|
||||||
// TODO
|
LOG_INFO("Hint '" << iHint.getName() << "' used for a cost of " << iHint.getCost());
|
||||||
LOG_INFO("Hint " << iHint.getName() << " used for a cost of " << iHint.getCost());
|
m_game->toppingAddPenalty(iHint.getCost());
|
||||||
|
emit gameUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ToppingWidget::timeoutPenalty()
|
void ToppingWidget::timeoutPenalty()
|
||||||
{
|
{
|
||||||
// TODO
|
// Show the solution to the player in a dialog box
|
||||||
LOG_INFO("Timeout penalty given");
|
const Move &move = m_game->toppingGetTopMove();
|
||||||
|
QMessageBox::information(this, "Eliot - " + _q("End of turn"),
|
||||||
|
_q("The allocated time for the turn has expired.\n"
|
||||||
|
"The top is %1 at %2 for %3 points.")
|
||||||
|
.arg(qfw(move.getRound().getWord()))
|
||||||
|
.arg(qfw(move.getRound().getCoord().toString()))
|
||||||
|
.arg(move.getScore()));
|
||||||
|
|
||||||
|
// End the turn
|
||||||
|
m_game->toppingTimeOut();
|
||||||
|
emit gameUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue