diff --git a/game/duplicate.h b/game/duplicate.h index 57b996d..cfaef18 100644 --- a/game/duplicate.h +++ b/game/duplicate.h @@ -58,7 +58,6 @@ class Duplicate: public Game friend class GameFactory; friend class MarkPlayedCmd; public: - virtual GameMode getMode() const { return kDUPLICATE; } virtual string getModeAsString() const { return "Duplicate"; } /************************* diff --git a/game/freegame.h b/game/freegame.h index d60ff92..8633755 100644 --- a/game/freegame.h +++ b/game/freegame.h @@ -46,7 +46,6 @@ class FreeGame: public Game DEFINE_LOGGER(); friend class GameFactory; public: - virtual GameMode getMode() const { return kFREEGAME; } virtual string getModeAsString() const { return "Free game"; } /************************* diff --git a/game/game.cpp b/game/game.cpp index 87795be..eba87ad 100644 --- a/game/game.cpp +++ b/game/game.cpp @@ -91,7 +91,7 @@ void Game::realBag(Bag &ioBag) const vector tiles; // The real content of the bag depends on the game mode - if (getMode() == kFREEGAME) + if (getMode() == GameParams::kFREEGAME) { // In freegame mode, take the letters from all the racks BOOST_FOREACH(const Player *player, m_players) @@ -550,7 +550,7 @@ int Game::checkPlayedWord(const wstring &iCoord, if (res != 0) return res + 4; // In duplicate mode, the first word must be horizontal - if (getMode() == kDUPLICATE && m_board.isVacant(8, 8)) + if (getMode() == GameParams::kDUPLICATE && m_board.isVacant(8, 8)) { if (oRound.getCoord().getDir() == Coord::VERTICAL) return 10; diff --git a/game/game.h b/game/game.h index cc7d708..1e48ad3 100644 --- a/game/game.h +++ b/game/game.h @@ -58,14 +58,7 @@ public: * Game type ***************/ - /// Game mode: each one of these modes is implemented in an inherited class - enum GameMode - { - kTRAINING, - kFREEGAME, - kDUPLICATE - }; - virtual GameMode getMode() const = 0; + GameParams::GameMode getMode() const { return m_params.getMode(); } virtual string getModeAsString() const = 0; /*************** diff --git a/game/game_factory.cpp b/game/game_factory.cpp index 686bfdf..2cbd954 100644 --- a/game/game_factory.cpp +++ b/game/game_factory.cpp @@ -78,30 +78,28 @@ void GameFactory::Destroy() } -Training *GameFactory::createTraining(const Dictionary &iDic, - const GameParams &iParams) +Game *GameFactory::createGame(const Dictionary &iDic, + const GameParams &iParams) { - LOG_INFO("Creating a training game"); - Training *game = new Training(iDic, iParams); - return game; -} - - -FreeGame *GameFactory::createFreeGame(const Dictionary &iDic, - const GameParams &iParams) -{ - LOG_INFO("Creating a free game"); - FreeGame *game = new FreeGame(iDic, iParams); - return game; -} - - -Duplicate *GameFactory::createDuplicate(const Dictionary &iDic, - const GameParams &iParams) -{ - LOG_INFO("Creating a duplicate game"); - Duplicate *game = new Duplicate(iDic, iParams); - return game; + if (iParams.getMode() == GameParams::kTRAINING) + { + LOG_INFO("Creating a training game"); + Training *game = new Training(iDic, iParams); + return game; + } + if (iParams.getMode() == GameParams::kFREEGAME) + { + LOG_INFO("Creating a free game"); + FreeGame *game = new FreeGame(iDic, iParams); + return game; + } + if (iParams.getMode() == GameParams::kDUPLICATE) + { + LOG_INFO("Creating a duplicate game"); + Duplicate *game = new Duplicate(iDic, iParams); + return game; + } + throw GameException("Unknown game type"); } @@ -199,25 +197,21 @@ Game *GameFactory::createFromCmdLine(int argc, char **argv) variant |= GameParams::kJOKER_VARIANT; // 5) Try to create a game object - Game *game = NULL; + GameParams::GameMode mode; if (m_modeStr == "training" || m_modeStr == "t") - { - game = createTraining(*m_dic, GameParams(variant)); - } + mode = GameParams::kTRAINING; else if (m_modeStr == "freegame" || m_modeStr == "f") - { - game = createFreeGame(*m_dic, GameParams(variant)); - } + mode = GameParams::kFREEGAME; else if (m_modeStr == "duplicate" || m_modeStr == "d") - { - game = createDuplicate(*m_dic, GameParams(variant)); - } + mode = GameParams::kDUPLICATE; else { cerr << "Invalid game mode '" << m_modeStr << "'" << endl; return NULL; } + Game *game = createGame(*m_dic, GameParams(mode, variant)); + // 6) Add the players for (unsigned int i = 0; i < m_players.size(); ++i) { diff --git a/game/game_factory.h b/game/game_factory.h index 623ab79..8da7073 100644 --- a/game/game_factory.h +++ b/game/game_factory.h @@ -33,9 +33,6 @@ using std::pair; class Dictionary; class GameParams; class Game; -class Training; -class FreeGame; -class Duplicate; /** @@ -52,18 +49,14 @@ public: static void Destroy(); /** - * Functions to create and destroy a game + * Create a game * The dictionary does not belong to the * game (ie: it won't be destroyed by ~Game) */ - Training *createTraining(const Dictionary &iDic, const GameParams &iParams); - FreeGame *createFreeGame(const Dictionary &iDic, const GameParams &iParams); - Duplicate *createDuplicate(const Dictionary &iDic, const GameParams &iParams); + Game *createGame(const Dictionary &iDic, const GameParams &iParams); /** * load() returns the loaded game, or NULL if there was a problem - * load() might need some more work to be robust enough to - * handle "hand written" files */ Game *load(const string &iFileName, const Dictionary &iDic); diff --git a/game/game_io.cpp b/game/game_io.cpp index 0dc734a..b96ff00 100644 --- a/game/game_io.cpp +++ b/game/game_io.cpp @@ -108,7 +108,7 @@ Game* Game::gameLoadFormat_14(FILE *fin, const Dictionary& iDic) char *token; Game *pGame = NULL; - pGame = GameFactory::Instance()->createTraining(iDic, GameParams()); + pGame = GameFactory::Instance()->createGame(iDic, GameParams(GameParams::kTRAINING)); pGame->addPlayer(new HumanPlayer); pGame->start(); @@ -205,25 +205,17 @@ Game* Game::gameLoadFormat_15(FILE *fin, const Dictionary& iDic) return NULL; } // Create the correct Game object + GameParams::GameMode mode; if (strstr(buff, "Training")) - { - pGame = GameFactory::Instance()->createTraining(iDic, GameParams()); - break; - } + mode = GameParams::kTRAINING; else if (strstr(buff, "Free game")) - { - pGame = GameFactory::Instance()->createFreeGame(iDic, GameParams()); - break; - } + mode = GameParams::kFREEGAME; else if (strstr(buff, "Duplicate")) - { - pGame = GameFactory::Instance()->createDuplicate(iDic, GameParams()); - break; - } + mode = GameParams::kDUPLICATE; else - { throw GameException("Unknown game type"); - } + + pGame = GameFactory::Instance()->createGame(iDic, GameParams(mode)); } } @@ -247,7 +239,7 @@ Game* Game::gameLoadFormat_15(FILE *fin, const Dictionary& iDic) } else if (string(type) == "Computer") { - if (pGame->getMode() == kTRAINING) + if (pGame->getMode() == GameParams::kTRAINING) { break; } diff --git a/game/game_params.h b/game/game_params.h index 999f6ec..fa738ac 100644 --- a/game/game_params.h +++ b/game/game_params.h @@ -32,6 +32,15 @@ class GameParams { public: + + /// Game mode + enum GameMode + { + kTRAINING, + kFREEGAME, + kDUPLICATE + }; + /** * Game variants: they slightly modifies the rules of the game. * Note that the Joker and Explosive variants are incompatible. @@ -41,8 +50,8 @@ class GameParams static const unsigned int kEXPLOSIVE_VARIANT = 2; // "Explosive" game static const unsigned int k7AMONG8_VARIANT = 4; // Play up to 7 letters from a rack containing 8 - GameParams(unsigned int variants = 0) - : m_variants(variants) + GameParams(GameMode iMode, unsigned int iVariants = 0) + : m_mode(iMode), m_variants(iVariants) { // Set default values m_rackSize = hasVariant(k7AMONG8_VARIANT) ? 8 : 7; @@ -55,12 +64,14 @@ class GameParams } // Getters + GameMode getMode() const { return m_mode; } bool hasVariant(unsigned int iVariant) const { return m_variants & iVariant; } int getRackSize() const { return m_rackSize; } int getLettersToPlay() const { return m_lettersToPlay; } int getBonusPoints() const { return m_bonusPoints; } private: + GameMode m_mode; unsigned int m_variants; int m_rackSize; int m_lettersToPlay; diff --git a/game/training.h b/game/training.h index 530e40b..4bab32c 100644 --- a/game/training.h +++ b/game/training.h @@ -48,7 +48,6 @@ class Training: public Game DEFINE_LOGGER(); friend class GameFactory; public: - virtual GameMode getMode() const { return kTRAINING; } virtual string getModeAsString() const { return "Training"; } /************************* diff --git a/game/xml_reader.cpp b/game/xml_reader.cpp index ec880ba..9f3c43e 100644 --- a/game/xml_reader.cpp +++ b/game/xml_reader.cpp @@ -207,7 +207,14 @@ void XmlReader::endElement(const string& namespaceURI, throw LoadGameException("The 'Mode' tag should be the first one to be closed"); // Differ game creation until after we have read the variant - m_attributes["mode"] = m_data; + if (m_data == "duplicate") + m_mode = GameParams::kDUPLICATE; + else if (m_data == "freegame") + m_mode = GameParams::kFREEGAME; + else if (m_data == "training") + m_mode = GameParams::kTRAINING; + else + throw GameException("Invalid game mode: " + m_data); return; } @@ -231,18 +238,10 @@ void XmlReader::endElement(const string& namespaceURI, // Create the game if (m_game == NULL) { - const string &mode = m_attributes["mode"]; - if (mode == "duplicate") - m_game = GameFactory::Instance()->createDuplicate(m_dic, GameParams(m_variants)); - else if (mode == "freegame") - m_game = GameFactory::Instance()->createFreeGame(m_dic, GameParams(m_variants)); - else if (mode == "training") - m_game = GameFactory::Instance()->createTraining(m_dic, GameParams(m_variants)); - else - throw LoadGameException("Invalid game mode: " + mode); + m_game = GameFactory::Instance()->createGame(m_dic, GameParams(m_mode, m_variants)); } - else if (m_context == "Player") + if (m_context == "Player") { if (tag == "Name") m_attributes["name"] = m_data; diff --git a/game/xml_reader.h b/game/xml_reader.h index c129d36..d5195c3 100644 --- a/game/xml_reader.h +++ b/game/xml_reader.h @@ -78,6 +78,7 @@ private: string m_data; map m_players; map m_attributes; + GameParams::GameMode m_mode; unsigned int m_variants; // Private constructor, because we only want the read() method diff --git a/game/xml_writer.cpp b/game/xml_writer.cpp index 2f79d90..db10ee7 100644 --- a/game/xml_writer.cpp +++ b/game/xml_writer.cpp @@ -101,9 +101,9 @@ void XmlWriter::write(const Game &iGame, const string &iFileName) addIndent(indent); // Game type out << indent << ""; - if (iGame.getMode() == Game::kDUPLICATE) + if (iGame.getMode() == GameParams::kDUPLICATE) out << "duplicate"; - else if (iGame.getMode() == Game::kFREEGAME) + else if (iGame.getMode() == GameParams::kFREEGAME) out << "freegame"; else out << "training"; diff --git a/qt/new_game.cpp b/qt/new_game.cpp index d1a050b..521bc3c 100644 --- a/qt/new_game.cpp +++ b/qt/new_game.cpp @@ -121,6 +121,14 @@ NewGame::NewGame(QWidget *iParent) PublicGame * NewGame::createGame(const Dictionary &iDic) const { // Game parameters + GameParams::GameMode mode; + if (radioButtonTraining->isChecked()) + mode = GameParams::kTRAINING; + else if (radioButtonFreeGame->isChecked()) + mode = GameParams::kFREEGAME; + else + mode = GameParams::kDUPLICATE; + unsigned int variants = GameParams::kNO_VARIANT; if (checkBoxJoker->isChecked()) variants |= GameParams::kJOKER_VARIANT; @@ -130,13 +138,7 @@ PublicGame * NewGame::createGame(const Dictionary &iDic) const variants |= GameParams::k7AMONG8_VARIANT; // Create the game - Game *tmpGame = NULL; - if (radioButtonTraining->isChecked()) - tmpGame = GameFactory::Instance()->createTraining(iDic, GameParams(variants)); - else if (radioButtonFreeGame->isChecked()) - tmpGame = GameFactory::Instance()->createFreeGame(iDic, GameParams(variants)); - else - tmpGame = GameFactory::Instance()->createDuplicate(iDic, GameParams(variants)); + Game *tmpGame = GameFactory::Instance()->createGame(iDic, GameParams(mode, variants)); PublicGame *game = new PublicGame(*tmpGame); // Add the players diff --git a/utils/eliottxt.cpp b/utils/eliottxt.cpp index b109af5..1d08161 100644 --- a/utils/eliottxt.cpp +++ b/utils/eliottxt.cpp @@ -44,15 +44,15 @@ #include "game_params.h" #include "game_factory.h" #include "public_game.h" -#include "training.h" -#include "duplicate.h" -#include "freegame.h" +#include "game.h" #include "player.h" #include "ai_percent.h" #include "encoding.h" #include "game_exception.h" #include "settings.h" +class Game; + // Use a more friendly type name for the tokenizer typedef boost::tokenizer, @@ -199,7 +199,7 @@ wstring checkCrossToken(const vector &tokens, uint8_t index) return wstr; } -GameParams readParams(const wstring &iToken) +GameParams readParams(GameParams::GameMode mode, const wstring &iToken) { unsigned int variants = GameParams::kNO_VARIANT; for (unsigned int i = 1; i < iToken.size(); ++i) @@ -211,7 +211,7 @@ GameParams readParams(const wstring &iToken) else if (iToken[i] == L'8') variants |= GameParams::k7AMONG8_VARIANT; } - return GameParams(variants); + return GameParams(mode, variants); } void helpTraining() @@ -911,8 +911,8 @@ void mainLoop(const Dictionary &iDic) case L'e': { // New training game - const GameParams ¶ms = readParams(tokens[0]); - Training *tmpGame = GameFactory::Instance()->createTraining(iDic, params); + const GameParams ¶ms = readParams(GameParams::kTRAINING, tokens[0]); + Game *tmpGame = GameFactory::Instance()->createGame(iDic, params); tmpGame->addPlayer(new HumanPlayer); PublicGame *game = new PublicGame(*tmpGame); game->start(); @@ -936,8 +936,8 @@ void mainLoop(const Dictionary &iDic) break; } // New duplicate game - const GameParams ¶ms = readParams(tokens[0]); - Duplicate *tmpGame = GameFactory::Instance()->createDuplicate(iDic, params); + const GameParams ¶ms = readParams(GameParams::kDUPLICATE, tokens[0]); + Game *tmpGame = GameFactory::Instance()->createGame(iDic, params); PublicGame *game = new PublicGame(*tmpGame); for (int i = 0; i < wtoi(nbHuman.c_str()); ++i) game->addPlayer(new HumanPlayer); @@ -964,8 +964,8 @@ void mainLoop(const Dictionary &iDic) break; } // New free game - const GameParams ¶ms = readParams(tokens[0]); - FreeGame *tmpGame = GameFactory::Instance()->createFreeGame(iDic, params); + const GameParams ¶ms = readParams(GameParams::kFREEGAME, tokens[0]); + Game *tmpGame = GameFactory::Instance()->createGame(iDic, params); PublicGame *game = new PublicGame(*tmpGame); for (int i = 0; i < wtoi(nbHuman.c_str()); i++) game->addPlayer(new HumanPlayer);