00001 #ifndef GAME_HPP
00002 #define GAME_HPP
00003
00004 #include "AbstractGame.hpp"
00005 #include "History.hpp"
00006 #include "HistoryLoader.hpp"
00007 #include "HistorySaver.hpp"
00008 #include "Controlers/Controler.hpp"
00009
00010 #include "Utils/Notifier.hpp"
00011 #include "Utils/Listener.hpp"
00012 #include "Renderers/Renderer.hpp"
00013
00014 #include <vector>
00015 #include <iostream>
00016 #include <cassert>
00017
00018 template <typename GameBoard,typename GameRules>
00019 class Game : public AbstractGame
00020 {
00021 typedef typename GameBoard::Coords Coords;
00022
00023 private:
00024
00025 GameBoard m_board;
00026 GameRules m_rules;
00027
00028
00029 std::vector<Controler<GameBoard>*> m_controlers;
00030
00031 Notifier<Move<Coords> > m_gameNotifier;
00032 Notifier<Move<Coords> > m_statusNotifier;
00033
00034 History<Move<Coords> > m_history;
00035
00036 int moves;
00038 int m_victoriousColor;
00039 bool m_draw;
00041 bool m_inited;
00048 void playMove(Move<Coords>& move)
00049 {
00050 int color = getCurrentColorTurn();
00051
00052 std::cout << "Legal move : " << move.isLegal();
00053 if ( move.isLegal() && m_rules.check(m_board,move) )
00054 {
00055 std::cout << "Move accepted" << std::endl;
00056
00057 m_rules.move(m_board,move);
00058 m_board.move(move);
00059
00060 m_gameNotifier.notify(move);
00061
00062 m_history.add(move);
00063 m_draw = m_rules.checkDraw(m_history);
00064 if ( m_rules.checkVictory(m_board,color) )
00065 {
00066 m_victoriousColor = color;
00067 }
00068
00069 moves++;
00070 }
00071 else
00072 {
00073 move.invalidate();
00074 }
00075
00076 m_statusNotifier.notify(move);
00077 }
00078
00085 bool init()
00086 {
00087 if ( m_inited == false )
00088 {
00089 if ( m_controlers.size() != GameRules::NB_PLAYERS)
00090 {
00091
00092 return false;
00093 }
00094
00095 m_rules.init(m_board);
00096
00097 m_statusNotifier.notify(Move<typename GameBoard::Coords>());
00098 }
00099
00100 m_inited = true;
00101
00102 return true;
00103 }
00104
00105 public:
00106
00109 Game()
00110 :moves(0),m_victoriousColor(-1),m_draw(false),m_inited(false)
00111 {
00112 }
00113
00115 ~Game()
00116 {
00117 for ( typename std::vector<Controler<GameBoard>*>::const_iterator itCont = m_controlers.begin() ; itCont != m_controlers.end() ; ++itCont )
00118 {
00119 delete *itCont;
00120 }
00121 }
00122
00126 const GameBoard* getBoard() {return &m_board; }
00127
00131 const GameRules* getRules() {return &m_rules; }
00132
00137 bool addControler(Controler<GameBoard>* pControler)
00138 {
00139 assert(pControler);
00140
00141 size_t nbControlers = m_controlers.size();
00142
00143 if ( nbControlers < GameRules::NB_PLAYERS )
00144 {
00145 pControler->setColorControled(nbControlers);
00146 m_controlers.push_back(pControler);
00147 m_gameNotifier.addListener(pControler);
00148
00149 return true;
00150 }
00151
00152 return false;
00153 }
00154
00159 bool addStatusListener(Listener<Move<Coords> >* pListener)
00160 {
00161 assert(pListener);
00162
00163 m_statusNotifier.addListener(pListener);
00164
00165 return true;
00166 }
00167
00168 bool checkMove()
00169 {
00170 return m_rules.check(m_board);
00171 }
00172
00177 bool play()
00178 {
00179 if ( init() == false )
00180 {
00181 return false;
00182 }
00183
00184 do
00185 {
00186 int color = getCurrentColorTurn();
00187
00188
00189 Move<typename GameBoard::Coords> m = m_controlers[color]->getMove();
00190 playMove(m);
00191
00192
00193 }while(m_victoriousColor == -1 && m_draw == false);
00194
00195
00196
00197
00198
00199 return true;
00200 }
00201
00205 int getCurrentColorTurn()const
00206 {
00207 return (moves % GameRules::NB_PLAYERS);
00208 }
00209
00210 int getVictoriousColor()const
00211 {
00212 return m_victoriousColor;
00213 }
00214
00215 bool isVictory()const
00216 {
00217 return m_victoriousColor != -1;
00218 }
00219
00220 bool isDraw()const
00221 {
00222 return m_draw;
00223 }
00224
00225 bool loadHistory(const std::string& fileName)
00226 {
00227 bool error = false;
00228
00229 m_history = HistoryLoader<Move<Coords> >::load(fileName,error);
00230 if ( error == false )
00231 {
00232 if ( init() == false )
00233 {
00234 return false;
00235 }
00236
00237 size_t nbElem = m_history.size();
00238 for ( size_t i = 0 ; i < nbElem ; i++ )
00239 {
00240 std::pair<Move<ChessBoard::Coords>,Move<ChessBoard::Coords> > tdata = m_history.get(i);
00241 playMove(tdata.first);
00242 playMove(tdata.second);
00243 }
00244 }
00245
00246 return error;
00247 }
00248
00249 bool saveHistory(const std::string& fileName)
00250 {
00251 return HistorySaver<Move<Coords> >::save(fileName, m_history);
00252 }
00253 };
00254
00268 #endif