Topping: give the score penalty directly with the player move.

This commit also adds a setting to disable the elapsed-time penalty.
This commit is contained in:
Olivier Teulière 2013-01-16 15:51:09 +01:00
parent cdcb5c25b7
commit 83baec368b
11 changed files with 55 additions and 29 deletions

View file

@ -33,8 +33,8 @@
INIT_LOGGER(game, Move); INIT_LOGGER(game, Move);
Move::Move() Move::Move(int iPoints)
:m_score(0) :m_score(iPoints)
{ {
m_type = NO_MOVE; m_type = NO_MOVE;
} }

View file

@ -50,7 +50,7 @@ class Move
/** /**
* Default constructor, corresponding to no move * Default constructor, corresponding to no move
*/ */
Move(); Move(int iPoints = 0);
/** /**
* Constructor taking a (valid) round * Constructor taking a (valid) round

View file

@ -262,9 +262,9 @@ void PublicGame::toppingPlay(const wstring &iWord, const wstring &iCoord, int iE
} }
void PublicGame::toppingTimeOut() void PublicGame::toppingTimeOut(int iElapsed)
{ {
getTypedGame<Topping>(m_game).turnTimeOut(); getTypedGame<Topping>(m_game).turnTimeOut(iElapsed);
} }

View file

@ -226,7 +226,7 @@ public:
void toppingPlay(const wstring &iWord, const wstring &iCoord, int iElapsed); void toppingPlay(const wstring &iWord, const wstring &iCoord, int iElapsed);
void toppingTimeOut(); void toppingTimeOut(int iElapsed);
void toppingAddPenalty(int iPenalty); void toppingAddPenalty(int iPenalty);

View file

@ -255,6 +255,11 @@ Settings::Settings()
// ============== Topping mode options ============== // ============== Topping mode options ==============
Setting &topping = m_conf->getRoot().add("topping", Setting::TypeGroup); Setting &topping = m_conf->getRoot().add("topping", Setting::TypeGroup);
// If true, a score penalty equal to the number of elapsed seconds
// is given to the player at each turn
topping.add("elapsed-penalty", Setting::TypeBoolean) = true;
// Additional penalty points given to the player when the timer expires
topping.add("timeout-penalty", Setting::TypeInt) = 60; topping.add("timeout-penalty", Setting::TypeInt) = 60;
// Try to read the values from the configuration file // Try to read the values from the configuration file
@ -277,6 +282,7 @@ Settings::Settings()
copySetting<int>(tmpConf, *m_conf, "arbitration.solo-value"); copySetting<int>(tmpConf, *m_conf, "arbitration.solo-value");
copySetting<int>(tmpConf, *m_conf, "arbitration.penalty-value"); copySetting<int>(tmpConf, *m_conf, "arbitration.penalty-value");
copySetting<int>(tmpConf, *m_conf, "arbitration.warnings-limit"); copySetting<int>(tmpConf, *m_conf, "arbitration.warnings-limit");
copySetting<int>(tmpConf, *m_conf, "topping.elapsed-penalty");
copySetting<int>(tmpConf, *m_conf, "topping.timeout-penalty"); copySetting<int>(tmpConf, *m_conf, "topping.timeout-penalty");
} }
catch (const std::exception &e) catch (const std::exception &e)
@ -371,7 +377,7 @@ int Settings::getInt(const string &iName) const
return 5; return 5;
else if (iName == "arbitration.warnings-limit") else if (iName == "arbitration.warnings-limit")
return 3; return 3;
else if (iName == "arbitration.timeout-penalty") else if (iName == "topping.timeout-penalty")
return 60; return 60;
return 0; return 0;
#endif #endif

View file

@ -115,21 +115,24 @@ void Topping::tryWord(const wstring &iWord, const wstring &iCoord, int iElapsed)
} }
void Topping::turnTimeOut() void Topping::turnTimeOut(int iElapsed)
{ {
LOG_INFO("Timeout reached, finishing turn automatically"); LOG_INFO("Timeout reached, finishing turn automatically");
m_board.removeTestRound(); m_board.removeTestRound();
// The player didn't find the move // Retrieve some settings
Command *pCmd = new PlayerMoveCmd(*m_players[m_currPlayer], Move()); bool giveElapsedPenalty = Settings::Instance().getBool("topping.elapsed-penalty");
accessNavigation().addAndExecute(pCmd); int timeoutPenalty = Settings::Instance().getInt("topping.timeout-penalty");
// Give a penalty to the player // Compute the points to give to the player
// XXX: should we give the penalty directly in the NO_MOVE move? int points = timeoutPenalty;
int penalty = Settings::Instance().getInt("topping.timeout-penalty"); if (giveElapsedPenalty)
if (penalty > 0) points += iElapsed;
addPenalty(penalty);
// The player didn't find the move
Command *pCmd = new PlayerMoveCmd(*m_players[m_currPlayer], Move(points));
accessNavigation().addAndExecute(pCmd);
// Next turn // Next turn
endTurn(); endTurn();
@ -155,10 +158,14 @@ int Topping::play(const wstring &, const wstring &)
void Topping::recordPlayerMove(const Move &iMove, Player &ioPlayer, int iElapsed) void Topping::recordPlayerMove(const Move &iMove, Player &ioPlayer, int iElapsed)
{ {
// Compute the penalty points to give to the player
bool giveElapsedPenalty = Settings::Instance().getBool("topping.elapsed-penalty");
int points = giveElapsedPenalty ? iElapsed : 0;
ASSERT(iMove.isValid(), "Only valid rounds should be played"); ASSERT(iMove.isValid(), "Only valid rounds should be played");
// Modify the score of the given move, to be the elapsed time // Modify the score of the given move, to be the computed score
Round copyRound = iMove.getRound(); Round copyRound = iMove.getRound();
copyRound.setPoints(iElapsed); copyRound.setPoints(points);
Move newMove(copyRound); Move newMove(copyRound);
// Update the rack and the score of the current player // Update the rack and the score of the current player

View file

@ -82,7 +82,7 @@ public:
* This will play the top on the board, give a points penalty to the player * This will play the top on the board, give a points penalty to the player
* and start the next turn. * and start the next turn.
*/ */
void turnTimeOut(); void turnTimeOut(int iElapsed);
/** /**
* Give an additional penalty to the player (probably because * Give an additional penalty to the player (probably because

View file

@ -101,6 +101,8 @@ PrefsDialog::PrefsDialog(QWidget *iParent)
spinBoxArbitSearchLimit->setToolTip(spinBoxTrainSearchLimit->toolTip()); spinBoxArbitSearchLimit->setToolTip(spinBoxTrainSearchLimit->toolTip());
spinBoxArbitWarnLimit->setToolTip(_q("Maximal number of \"acceptable\" warnings.\n" spinBoxArbitWarnLimit->setToolTip(_q("Maximal number of \"acceptable\" warnings.\n"
"Any additional warning will give a penalty to the player.")); "Any additional warning will give a penalty to the player."));
checkBoxToppingElapsedPenalty->setToolTip(_q("If checked, the player gets, at each turn, a score penalty\n"
"equal to the elapsed time for the turn."));
spinBoxToppingExpPenalty->setToolTip(_q("Number of points added to the player score when the timer expires.\n" spinBoxToppingExpPenalty->setToolTip(_q("Number of points added to the player score when the timer expires.\n"
"Set it to 0 if you don't want any penalty.")); "Set it to 0 if you don't want any penalty."));
@ -162,6 +164,7 @@ PrefsDialog::PrefsDialog(QWidget *iParent)
spinBoxArbitSearchLimit->setValue(Settings::Instance().getInt("arbitration.search-limit")); spinBoxArbitSearchLimit->setValue(Settings::Instance().getInt("arbitration.search-limit"));
// Topping settings // Topping settings
checkBoxToppingElapsedPenalty->setChecked(Settings::Instance().getBool("topping.elapsed-penalty"));
spinBoxToppingExpPenalty->setValue(Settings::Instance().getInt("topping.timeout-penalty")); spinBoxToppingExpPenalty->setValue(Settings::Instance().getInt("topping.timeout-penalty"));
// Confirmations // Confirmations
@ -297,6 +300,8 @@ void PrefsDialog::updateSettings()
spinBoxArbitWarnLimit->value()); spinBoxArbitWarnLimit->value());
// Topping settings // Topping settings
Settings::Instance().setBool("topping.elapsed-penalty",
checkBoxToppingElapsedPenalty->isChecked());
Settings::Instance().setInt("topping.timeout-penalty", Settings::Instance().setInt("topping.timeout-penalty",
spinBoxToppingExpPenalty->value()); spinBoxToppingExpPenalty->value());

View file

@ -378,11 +378,12 @@ void StatsWidget::setModelTurnData(const QModelIndex &iIndex,
const TurnData &iTurn, const TurnData &iGameTurn) const TurnData &iTurn, const TurnData &iGameTurn)
{ {
// Set the text (score for the turn) // Set the text (score for the turn)
if (!iTurn.getMove().isNull())
{
int score = iTurn.getMove().getScore(); int score = iTurn.getMove().getScore();
setModelText(iIndex, QVariant(score), if (score != 0)
score >= iGameTurn.getMove().getScore()); {
bool shouldUseBold = score >= iGameTurn.getMove().getScore()
&& (m_game == 0 || m_game->getMode() != PublicGame::kTOPPING);
setModelText(iIndex, QVariant(score), shouldUseBold);
} }
// Set the background color // Set the background color

View file

@ -254,7 +254,7 @@ void ToppingWidget::timeoutPenalty()
.arg(move.getScore())); .arg(move.getScore()));
// End the turn // End the turn
m_game->toppingTimeOut(); m_game->toppingTimeOut(m_timerModel->getTotalDuration());
emit gameUpdated(); emit gameUpdated();
} }

View file

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>474</width> <width>474</width>
<height>699</height> <height>737</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -495,14 +495,14 @@
<string>_(&quot;Topping mode&quot;)</string> <string>_(&quot;Topping mode&quot;)</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_4"> <layout class="QGridLayout" name="gridLayout_4">
<item row="1" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_11"> <widget class="QLabel" name="label_11">
<property name="text"> <property name="text">
<string>_(&quot;Additional penalty given when the timer expires:&quot;</string> <string>_(&quot;Additional penalty given when the timer expires:&quot;)</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="2" column="1">
<widget class="QSpinBox" name="spinBoxToppingExpPenalty"> <widget class="QSpinBox" name="spinBoxToppingExpPenalty">
<property name="maximum"> <property name="maximum">
<number>9999</number> <number>9999</number>
@ -512,7 +512,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="2"> <item row="0" column="0">
<widget class="QCheckBox" name="checkBoxToppingElapsedPenalty">
<property name="text">
<string>_(&quot;Give a 1 point penalty for each elapsed second&quot;)</string>
</property>
</widget>
</item>
<item row="2" column="2">
<spacer name="horizontalSpacer_5"> <spacer name="horizontalSpacer_5">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>