00001 /***************************************************************************** 00002 * Copyright (C) 2005 Eliot 00003 * Authors: Olivier Teuliere <ipkiss@via.ecp.fr> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 *****************************************************************************/ 00019 00020 #ifndef _DUPLICATE_H_ 00021 #define _DUPLICATE_H_ 00022 00023 #include "game.h" 00024 00025 using std::string; 00026 00027 00028 /** 00029 * This class handles the logic specific to a duplicate game. 00030 * The trick in this mode is that the players will not necessarily play they 00031 * word always in the same order, so we need to implement a "synchronization": 00032 * - when a human player wants to play a word, he plays it, and its score 00033 * and rack are updated. He cannot change his word afterwards. 00034 * - if there is still a human player who has not played for the current 00035 * turn, we wait for him 00036 * - if all the human players have played, it's the turn to the AI players 00037 * (currently handled in a loop, but we could imagine that they are running 00038 * in their own thread). 00039 * - once all the players have played, we can really end the turn: 00040 * the best word is played on the board, the history of the game is 00041 * updated, and the new rack is chosen. 00042 * 00043 * AI players play after human ones, because with the current implementation 00044 * of the interfaces it is too easy for a player to see the rack of other 00045 * players, and in particular a human player could take advantage of that to 00046 * have more clues about the best word. 00047 * TODO: better isolation of the players... 00048 */ 00049 class Duplicate: public Game 00050 { 00051 friend class GameFactory; 00052 public: 00053 virtual GameMode getMode() const { return kDUPLICATE; } 00054 virtual string getModeAsString() const { return "Duplicate"; } 00055 00056 /************************* 00057 * Game handling 00058 *************************/ 00059 virtual int start(); 00060 virtual int setRackRandom(int, bool, set_rack_mode); 00061 virtual int play(const string &iCoord, const string &iWord); 00062 virtual int endTurn(); 00063 00064 int setPlayer(int); 00065 // Switch to the previous human player who has not played yet 00066 void prevHumanPlayer(); 00067 // Switch to the next human player who has not played yet 00068 void nextHumanPlayer(); 00069 00070 private: 00071 // Private constructor and destructor to force using the GameFactory class 00072 Duplicate(const Dictionary &iDic); 00073 virtual ~Duplicate(); 00074 00075 void playRound(const Round &iRound, int n); 00076 int endTurnForReal(); 00077 void end(); 00078 void duplicateAI(int n); 00079 00080 // m_hasPlayed[p] is true iff player p has played for this turn 00081 map<int, bool> m_hasPlayed; 00082 }; 00083 00084 #endif /* _DUPLICATE_H_ */ 00085 00086 /// Local Variables: 00087 /// mode: c++ 00088 /// mode: hs-minor 00089 /// c-basic-offset: 4 00090 /// indent-tabs-mode: nil 00091 /// End: