Game::checkPlayedWord() now takes a Move instead of a Round

This commit is contained in:
Olivier Teulière 2012-12-23 19:31:03 +01:00
parent 0b9d8ecfbb
commit 8acebbc889
8 changed files with 40 additions and 66 deletions

View file

@ -80,11 +80,9 @@ void Arbitration::search(LimitResults &oResults)
Move Arbitration::checkWord(const wstring &iWord, Move Arbitration::checkWord(const wstring &iWord,
const wstring &iCoords) const const wstring &iCoords) const
{ {
Round round; Move move;
int res = checkPlayedWord(iCoords, iWord, round, true); checkPlayedWord(iCoords, iWord, move, true);
if (res == 0) return move;
return Move(round);
return Move(iWord, iCoords);
} }

View file

@ -71,27 +71,16 @@ int Duplicate::play(const wstring &iCoord, const wstring &iWord)
ASSERT(!hasPlayed(m_currPlayer), "Human player has already played"); ASSERT(!hasPlayed(m_currPlayer), "Human player has already played");
// Perform all the validity checks, and try to fill a round // Perform all the validity checks, and try to fill a round
Round round; Move move;
int res = checkPlayedWord(iCoord, iWord, round); int res = checkPlayedWord(iCoord, iWord, move);
if (res != 0 && Settings::Instance().getBool("duplicate.reject-invalid")) if (res != 0 && Settings::Instance().getBool("duplicate.reject-invalid"))
{ {
return res; return res;
} }
// If we reach this point, either the move is valid and we can use the // If we reach this point, either the move is valid and we can use the
// "round" variable, or it is invalid but played nevertheless // "move" variable, or it is invalid but played nevertheless
if (res == 0) recordPlayerMove(currPlayer, move);
{
// Everything is OK, we can play the word
recordPlayerMove(currPlayer, Move(round));
}
else
{
// Convert the invalid word for display
const wdstring &dispWord = getDic().convertToDisplay(iWord);
// Record the invalid move of the player
recordPlayerMove(currPlayer, Move(dispWord, iCoord));
}
// Little hack to handle duplicate games with only AI players. // Little hack to handle duplicate games with only AI players.
// This will have no effect when there is at least one human player // This will have no effect when there is at least one human player

View file

@ -57,32 +57,16 @@ FreeGame::FreeGame(const GameParams &iParams)
int FreeGame::play(const wstring &iCoord, const wstring &iWord) int FreeGame::play(const wstring &iCoord, const wstring &iWord)
{ {
// Perform all the validity checks, and try to fill a round // Perform all the validity checks, and try to fill a round
Round round; Move move;
int res = checkPlayedWord(iCoord, iWord, round); int res = checkPlayedWord(iCoord, iWord, move);
if (res != 0 && Settings::Instance().getBool("freegame.reject-invalid")) if (res != 0 && Settings::Instance().getBool("freegame.reject-invalid"))
{ {
return res; return res;
} }
// If we reach this point, either the move is valid and we can use the // If we reach this point, either the move is valid and we can use the
// "round" variable, or it is invalid but played nevertheless // "move" variable, or it is invalid but played nevertheless
if (res == 0)
{
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]);
}
else
{
// Convert the invalid word for display
const wdstring &dispWord = getDic().convertToDisplay(iWord);
Move move(dispWord, iCoord);
// Record the invalid move of the player
recordPlayerMove(move, *m_players[m_currPlayer]);
}
// Next turn // Next turn
endTurn(); endTurn();

View file

@ -526,17 +526,21 @@ void Game::nextPlayer()
int Game::checkPlayedWord(const wstring &iCoord, int Game::checkPlayedWord(const wstring &iCoord,
const wstring &iWord, const wstring &iWord,
Round &oRound, bool checkRack) const Move &oMove, bool checkRack) const
{ {
ASSERT(getNPlayers() != 0, "Expected at least one player"); ASSERT(getNPlayers() != 0, "Expected at least one player");
// Assume that the move is invalid by default
const wdstring &dispWord = getDic().convertToDisplay(iWord);
oMove = Move(dispWord, iCoord);
if (!getDic().validateLetters(iWord)) if (!getDic().validateLetters(iWord))
return 1; return 1;
// Init the round with the given coordinates // Init the round with the given coordinates
oRound = Round(); Round round;
oRound.accessCoord().setFromString(iCoord); round.accessCoord().setFromString(iCoord);
if (!oRound.getCoord().isValid()) if (!round.getCoord().isValid())
{ {
return 2; return 2;
} }
@ -556,11 +560,11 @@ int Game::checkPlayedWord(const wstring &iCoord,
{ {
tiles.push_back(Tile(iWord[i])); tiles.push_back(Tile(iWord[i]));
} }
oRound.setWord(tiles); round.setWord(tiles);
// Check the word position, compute its points, // Check the word position, compute its points,
// and specify the origin of each letter (board or rack) // and specify the origin of each letter (board or rack)
int res = m_board.checkRound(oRound); int res = m_board.checkRound(round);
if (res != 0) if (res != 0)
return res + 4; return res + 4;
// In duplicate mode, the first word must be horizontal // In duplicate mode, the first word must be horizontal
@ -568,7 +572,7 @@ int Game::checkPlayedWord(const wstring &iCoord,
(getMode() == GameParams::kDUPLICATE || (getMode() == GameParams::kDUPLICATE ||
getMode() == GameParams::kARBITRATION)) getMode() == GameParams::kARBITRATION))
{ {
if (oRound.getCoord().getDir() == Coord::VERTICAL) if (round.getCoord().getDir() == Coord::VERTICAL)
return 10; return 10;
} }
@ -581,14 +585,14 @@ int Game::checkPlayedWord(const wstring &iCoord,
Rack rack = player->getCurrentRack().getRack(); Rack rack = player->getCurrentRack().getRack();
Tile t; Tile t;
for (unsigned int i = 0; i < oRound.getWordLen(); i++) for (unsigned int i = 0; i < round.getWordLen(); i++)
{ {
if (oRound.isPlayedFromRack(i)) if (round.isPlayedFromRack(i))
{ {
if (oRound.isJoker(i)) if (round.isJoker(i))
t = Tile::Joker(); t = Tile::Joker();
else else
t = oRound.getTile(i); t = round.getTile(i);
if (!rack.in(t)) if (!rack.in(t))
{ {
@ -599,6 +603,9 @@ int Game::checkPlayedWord(const wstring &iCoord,
} }
} }
// The move is valid
oMove = Move(round);
return 0; return 0;
} }

View file

@ -171,7 +171,7 @@ public:
/** /**
* This function checks whether it is legal to play the given word at the * This function checks whether it is legal to play the given word at the
* given coordinates. If so, the function fills a Round object, also given * given coordinates. If so, the function fills a Move object, also given
* as a parameter. * as a parameter.
* Possible return values: same as the play() method * Possible return values: same as the play() method
* If checkRack is false, the return value 4 is impossible to get * If checkRack is false, the return value 4 is impossible to get
@ -179,7 +179,7 @@ public:
*/ */
int checkPlayedWord(const wstring &iCoord, int checkPlayedWord(const wstring &iCoord,
const wstring &iWord, const wstring &iWord,
Round &oRound, Move &oMove,
bool checkRack = true) const; bool checkRack = true) const;
private: private:

View file

@ -161,11 +161,11 @@ int PublicGame::play(const wstring &iWord, const wstring &iCoord)
int PublicGame::computePoints(const wstring &iWord, const wstring &iCoord) const int PublicGame::computePoints(const wstring &iWord, const wstring &iCoord) const
{ {
Round round; Move move;
int res = m_game.checkPlayedWord(iCoord, iWord, round); int res = m_game.checkPlayedWord(iCoord, iWord, move);
if (res > 0) if (res > 0)
return -res; return -res;
return round.getPoints(); return move.getScore();
} }

View file

@ -89,18 +89,14 @@ void Training::setRackManual(bool iCheck, const wstring &iLetters)
int Training::play(const wstring &iCoord, const wstring &iWord) int Training::play(const wstring &iCoord, const wstring &iWord)
{ {
// Perform all the validity checks, and fill a round
Round round;
m_board.removeTestRound(); m_board.removeTestRound();
int res = checkPlayedWord(iCoord, iWord, round); // Perform all the validity checks, and fill a move
Move move;
int res = checkPlayedWord(iCoord, iWord, move);
if (res != 0) if (res != 0)
{
return res; return res;
}
Move move(round);
recordPlayerMove(move, *m_players[m_currPlayer]); recordPlayerMove(move, *m_players[m_currPlayer]);
// Next turn // Next turn

View file

@ -134,15 +134,15 @@ static Move buildMove(const Game &iGame, map<string, string> &attr,
if (type == "valid") if (type == "valid")
{ {
wstring word = iGame.getDic().convertFromInput(fromUtf8(attr["word"])); wstring word = iGame.getDic().convertFromInput(fromUtf8(attr["word"]));
Round round; Move move;
int res = iGame.checkPlayedWord(fromUtf8(attr["coord"]), int res = iGame.checkPlayedWord(fromUtf8(attr["coord"]),
word, round, checkRack); word, move, checkRack);
if (res != 0) if (res != 0)
{ {
throw LoadGameException(FMT2(_("Invalid move marked as valid: %1% (%2%)"), throw LoadGameException(FMT2(_("Invalid move marked as valid: %1% (%2%)"),
attr["word"], attr["coord"])); attr["word"], attr["coord"]));
} }
return Move(round); return move;
} }
else if (type == "invalid") else if (type == "invalid")
{ {