Replaced all std::cout with kDebug.
[tagua/yd.git] / src / controllers / editgame.cpp
blobcddedcc88eaf967b6a5b2e7813f81428b2a1ad14
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@gmail.com>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #include "editgame.h"
12 #include <KDebug>
13 #include "graphicalgame.h"
14 #include "graphicalsystem.h"
15 #include "xboardengine.h"
16 #include "entities/engineentity.h"
17 #include "entities/gameentity.h"
18 #include "entities/icsentity.h"
19 #include "entities/examinationentity.h"
20 #include "movelist_table.h"
21 #include "console.h"
22 #include "icsconnection.h"
23 #include "chesstable.h"
24 #include "foreach.h"
25 #include "actioncollection.h"
26 #include "ui.h"
28 using namespace boost;
30 class ClockAgent : public Agent {
31 ChessTable* m_view;
32 shared_ptr<Game> m_game;
33 public:
34 ClockAgent(ChessTable* view, const shared_ptr<Game>& game)
35 : m_view(view)
36 , m_game(game) { }
38 virtual void notifyClockUpdate(int, int) { }
39 virtual void notifyMove(const Index& index) {
40 // start clock after the first 2 moves
41 if (index.totalNumMoves() >= 2)
42 m_view->run();
44 m_view->changeClock(m_game->position(index)->turn());
46 virtual void notifyBack() { }
47 virtual void notifyForward() { }
48 virtual void notifyGotoFirst() { }
49 virtual void notifyGotoLast() { }
50 virtual void stop() {
51 Agent::stop();
52 m_view->stopClocks();
56 class ClockUpdateAgent : public Agent {
57 ChessTable* m_view;
58 public:
59 ClockUpdateAgent(ChessTable* view)
60 : m_view(view) { }
62 virtual void notifyClockUpdate(int white, int black) {
63 m_view->updateTime(white, black);
65 virtual void notifyMove(const Index&) { }
66 virtual void notifyBack() { }
67 virtual void notifyForward() { }
68 virtual void notifyGotoFirst() { }
69 virtual void notifyGotoLast() { }
72 EditGameController::EditGameController(ChessTable* view,
73 const VariantPtr& variant,
74 AbstractPosition::Ptr startingPosition)
75 : Controller(view) , m_variant(variant) {
77 AbstractPosition::Ptr position;
78 if (!startingPosition) {
79 position = m_variant->createPosition();
80 position->setup();
82 else position = startingPosition;
84 m_graphical = shared_ptr<GraphicalSystem>(new GraphicalSystem(m_view, position, m_variant));
86 m_game = shared_ptr<GraphicalGame>(new GraphicalGame(m_graphical.get(),
87 m_view->moveListTable()));
88 m_game->reset(position);
90 m_entity = shared_ptr<GameEntity>(new GameEntity(m_variant, m_game, m_view->board(), &m_agents));
91 m_entity->enableEditingTools(true);
93 m_graphical->setup(m_entity);
94 m_game->setEntity(m_entity);
97 init(AbstractPosition::Ptr());
100 EditGameController::~EditGameController() { }
102 void EditGameController::init(AbstractPosition::Ptr startingPosition) {
103 m_players[0] = m_entity;
104 m_players[1] = m_entity;
105 m_entity->turnTest().setSimplePolicy(0, true);
106 m_entity->turnTest().setSimplePolicy(1, true);
108 if (startingPosition) {
109 // TODO update to the starting position
112 // add user agent
113 m_agents.addAgent(m_entity);
115 m_clock_agent = shared_ptr<Agent>(new ClockAgent(m_view, m_game));
116 m_update_agent = shared_ptr<Agent>(new ClockUpdateAgent(m_view));
118 // add clock update agent
119 m_agents.addAgent(m_update_agent);
122 ActionCollection* EditGameController::variantActions() const {
123 return m_variant->actions();
126 QString EditGameController::variant() const {
127 PositionPtr pos = m_game->position();
128 if (pos)
129 return pos->variant();
130 else
131 return QString();
134 void EditGameController::onNavigation() { }
136 EntityToken EditGameController::addPlayingEngine(int side, const shared_ptr<Engine>& engine) {
137 Q_ASSERT(side == 0 || side == 1);
138 if (!engine)
139 return EntityToken();
141 if (m_players[side]->canDetach()) {
142 shared_ptr<EngineEntity> entity(new EngineEntity(m_variant, m_game, side,
143 engine, &m_agents));
144 entity->setup();
146 m_agents.addAgent(entity);
147 m_players[side] = entity;
149 // the user cannot move the entity's pieces
150 m_entity->turnTest().setSimplePolicy(side, false);
152 return EntityToken(entity);
154 else {
155 kDebug() << "** could not detach entity playing " << side << "**";
158 return EntityToken();
161 // EntityToken EditGameController::addAnalysingEngine(const shared_ptr<Engine>& engine) {
162 // Q_ASSERT(engine.use_count() == 1);
163 // shared_ptr<EngineEntity> entity(new EngineEntity(m_variant, m_game, -1, engine, &m_agents));
164 // m_agents.addAgent(entity);
165 // EntityToken res(m_entities.insert(entity).first);
167 // engine->setNotifier(entity);
168 // engine->start();
169 // engine->setBoard(m_game->position(), 0, 0);
170 // engine->startAnalysis();
172 // return res;
173 // }
175 void EditGameController::removeEntity(const EntityToken& token) {
176 shared_ptr<Entity> entity = token.entity();
177 if (entity) {
178 // check players
179 for (int i = 0; i < 2; i++) {
180 if (entity == m_players[i]) {
181 m_players[i] = m_entity;
182 m_entity->turnTest().setSimplePolicy(i, true);
186 // check other entities
187 std::set<boost::shared_ptr<Entity> >::iterator it = m_entities.find(entity);
188 if (it != m_entities.end()) {
189 m_entities.erase(it);
192 kDebug() << "there are " << m_entities.size() << " entities left";
195 bool EditGameController::addICSPlayer(int side, int game_number, const shared_ptr<ICSConnection>& connection) {
196 Q_ASSERT(side == 0 || side == 1);
197 if (m_players[side]->canDetach()) {
198 shared_ptr<ICSEntity> entity(new ICSEntity(m_variant, m_game,
199 side, game_number, connection, &m_agents));
201 if (entity->attach()) {
202 kDebug() << "added ICS agent " << entity.get();
203 m_agents.addAgent(entity);
205 m_players[side] = entity;
206 connection->setListener(game_number, entity);
208 entity->setupTurnTest(m_entity->turnTest());
209 m_view->flip(m_players[1] == m_entity); // flip if we're black!
211 m_agents.addAgent(m_clock_agent);
213 else {
214 kDebug() << "** could not attach ics entity **";
215 return false;
218 else {
219 kDebug() << "** could not detach entity playing " << side << "**";
220 return false;
223 return true;
226 bool EditGameController::setExaminationMode(int game_number, const shared_ptr<ICSConnection>& connection) {
227 kDebug() << "[controller " << this << "] setting examination mode";
228 if (m_players[0]->canDetach() &&
229 m_players[1]->canDetach()) {
230 shared_ptr<ExaminationEntity> entity(new ExaminationEntity(m_variant, m_game,
231 game_number, connection, &m_agents));
232 if (entity->attach()) {
233 m_entity = entity;
234 m_view->setEntity(entity);
235 m_agents.addAgent(entity);
236 m_players[0] = entity;
237 m_players[1] = entity;
239 connection->setListener(game_number, entity);
240 m_view->flip(false);
241 m_entity->turnTest().clear();
243 return true;
245 else
246 kDebug() << "** could not attach examination entity **";
248 else
249 kDebug() << "** could not detach entity **";
251 return false;
254 bool EditGameController::setObserveMode(int game_number, const shared_ptr<ICSConnection>& connection) {
255 if (m_players[0]->canDetach() &&
256 m_players[1]->canDetach()) {
257 shared_ptr<ICSEntity> entity(new ObservingEntity(m_variant, m_game,
258 game_number, connection, &m_agents));
260 if (entity->attach()) {
261 m_agents.addAgent(entity);
262 m_players[0] = entity;
263 m_players[1] = entity;
265 connection->setListener(game_number, entity);
266 m_view->flip(false);
267 m_entity->turnTest().clear();
268 return true;
270 else
271 kDebug() << "** could not attach ics entity for observe mode ** ";
273 else
274 kDebug() << "** could not detach entity **";
276 return false;
279 void EditGameController::loadPGN(const PGN& pgn) {
280 end();
281 m_view->resetClock();
282 entity()->loadPGN(pgn);
285 void EditGameController::createCtrlAction() {
286 m_game->createCtrlAction();
289 void EditGameController::destroyCtrlAction() {
290 m_game->destroyCtrlAction();
293 void EditGameController::detach() {
294 m_entity->detach();
295 m_players[0]->detach();
296 m_players[1]->detach();
298 foreach (shared_ptr<Entity> entity, m_entities)
299 entity->detach();
302 shared_ptr<Controller> EditGameController::end() {
303 // stop clocks
304 if (m_clock_agent) {
305 m_clock_agent->stop();
306 m_clock_agent = shared_ptr<Agent>(new ClockAgent(m_view, m_game));
309 // return to edit game mode
310 m_players[0] = m_entity;
311 m_players[1] = m_entity;
312 m_entity->turnTest().setSimplePolicy(0, true);
313 m_entity->turnTest().setSimplePolicy(1, true);
315 return Controller::end();
318 void EditGameController::reloadSettings() {
319 m_graphical->settingsChanged();
322 void EditGameController::setUI(UI& ui) {
323 m_game->setActionStateObserver(ui.createActionStateObserver(shared_from_this()));
324 m_game->onActionStateChange();
327 void EditGameController::activate() {
328 m_game->onActionStateChange();