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.
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"
22 #include "icsconnection.h"
23 #include "chesstable.h"
25 #include "actioncollection.h"
29 using namespace boost
;
31 class ClockAgent
: public Agent
{
33 shared_ptr
<Game
> m_game
;
35 ClockAgent(ChessTable
* view
, const shared_ptr
<Game
>& game
)
39 virtual void notifyClockUpdate(int, int) { }
40 virtual void notifyMove(const Index
& index
) {
41 // start clock after the first 2 moves
42 if (index
.totalNumMoves() >= 2)
45 m_view
->changeClock(m_game
->position(index
)->turn());
47 virtual void notifyBack() { }
48 virtual void notifyForward() { }
49 virtual void notifyGotoFirst() { }
50 virtual void notifyGotoLast() { }
57 class ClockUpdateAgent
: public Agent
{
60 ClockUpdateAgent(ChessTable
* view
)
63 virtual void notifyClockUpdate(int white
, int black
) {
64 m_view
->updateTime(white
, black
);
66 virtual void notifyMove(const Index
&) { }
67 virtual void notifyBack() { }
68 virtual void notifyForward() { }
69 virtual void notifyGotoFirst() { }
70 virtual void notifyGotoLast() { }
73 EditGameController::EditGameController(ChessTable
* view
,
74 const VariantPtr
& variant
,
75 AbstractPosition::Ptr startingPosition
)
76 : Controller(view
) , m_variant(variant
) {
78 AbstractPosition::Ptr position
;
79 if (!startingPosition
) {
80 position
= m_variant
->createPosition();
83 else position
= startingPosition
;
85 m_graphical
= shared_ptr
<GraphicalSystem
>(new GraphicalSystem(m_view
, position
, m_variant
));
87 m_game
= shared_ptr
<GraphicalGame
>(new GraphicalGame(m_graphical
.get(),
88 m_view
->moveListTable()));
89 m_game
->reset(position
);
91 m_entity
= shared_ptr
<GameEntity
>(new GameEntity(m_variant
, m_game
, m_view
->board(), &m_agents
));
92 m_entity
->enableEditingTools(true);
94 m_graphical
->setup(m_entity
);
95 m_game
->setEntity(m_entity
);
98 init(AbstractPosition::Ptr());
101 EditGameController::~EditGameController() { }
103 void EditGameController::init(AbstractPosition::Ptr startingPosition
) {
104 m_players
[0] = m_entity
;
105 m_players
[1] = m_entity
;
106 m_entity
->turnTest().setSimplePolicy(0, true);
107 m_entity
->turnTest().setSimplePolicy(1, true);
109 if (startingPosition
) {
110 // TODO update to the starting position
114 m_agents
.addAgent(m_entity
);
116 m_clock_agent
= shared_ptr
<Agent
>(new ClockAgent(m_view
, m_game
));
117 m_update_agent
= shared_ptr
<Agent
>(new ClockUpdateAgent(m_view
));
119 // add clock update agent
120 m_agents
.addAgent(m_update_agent
);
123 ActionCollection
* EditGameController::variantActions() const {
124 return m_variant
->actions();
127 QString
EditGameController::variant() const {
128 PositionPtr pos
= m_game
->position();
130 return pos
->variant();
135 void EditGameController::onNavigation() { }
137 EntityToken
EditGameController::addPlayingEngine(int side
, const shared_ptr
<Engine
>& engine
) {
138 Q_ASSERT(side
== 0 || side
== 1);
140 return EntityToken();
142 if (m_players
[side
]->canDetach()) {
143 shared_ptr
<EngineEntity
> entity(new EngineEntity(m_variant
, m_game
, side
,
147 m_agents
.addAgent(entity
);
148 m_players
[side
] = entity
;
150 // the user cannot move the entity's pieces
151 m_entity
->turnTest().setSimplePolicy(side
, false);
153 return EntityToken(entity
);
156 std::cout
<< "** could not detach entity playing " << side
<< "**" << std::endl
;
159 return EntityToken();
162 // EntityToken EditGameController::addAnalysingEngine(const shared_ptr<Engine>& engine) {
163 // Q_ASSERT(engine.use_count() == 1);
164 // shared_ptr<EngineEntity> entity(new EngineEntity(m_variant, m_game, -1, engine, &m_agents));
165 // m_agents.addAgent(entity);
166 // EntityToken res(m_entities.insert(entity).first);
168 // engine->setNotifier(entity);
170 // engine->setBoard(m_game->position(), 0, 0);
171 // engine->startAnalysis();
176 void EditGameController::removeEntity(const EntityToken
& token
) {
177 shared_ptr
<Entity
> entity
= token
.entity();
180 for (int i
= 0; i
< 2; i
++) {
181 if (entity
== m_players
[i
]) {
182 m_players
[i
] = m_entity
;
183 m_entity
->turnTest().setSimplePolicy(i
, true);
187 // check other entities
188 std::set
<boost::shared_ptr
<Entity
> >::iterator it
= m_entities
.find(entity
);
189 if (it
!= m_entities
.end()) {
190 m_entities
.erase(it
);
193 std::cout
<< "there are " << m_entities
.size() << " entities left" << std::endl
;
196 bool EditGameController::addICSPlayer(int side
, int game_number
, const shared_ptr
<ICSConnection
>& connection
) {
197 Q_ASSERT(side
== 0 || side
== 1);
198 if (m_players
[side
]->canDetach()) {
199 shared_ptr
<ICSEntity
> entity(new ICSEntity(m_variant
, m_game
,
200 side
, game_number
, connection
, &m_agents
));
202 if (entity
->attach()) {
203 std::cout
<< "added ICS agent " << entity
.get() << std::endl
;
204 m_agents
.addAgent(entity
);
206 m_players
[side
] = entity
;
207 connection
->setListener(game_number
, entity
);
209 entity
->setupTurnTest(m_entity
->turnTest());
210 m_view
->flip(m_players
[1] == m_entity
); // flip if we're black!
212 m_agents
.addAgent(m_clock_agent
);
215 std::cout
<< "** could not attach ics entity **" << std::endl
;
220 std::cout
<< "** could not detach entity playing " << side
<< "**" << std::endl
;
227 bool EditGameController::setExaminationMode(int game_number
, const shared_ptr
<ICSConnection
>& connection
) {
228 std::cout
<< "[controller " << this << "] setting examination mode" << std::endl
;
229 if (m_players
[0]->canDetach() &&
230 m_players
[1]->canDetach()) {
231 shared_ptr
<ExaminationEntity
> entity(new ExaminationEntity(m_variant
, m_game
,
232 game_number
, connection
, &m_agents
));
233 if (entity
->attach()) {
235 m_view
->setEntity(entity
);
236 m_agents
.addAgent(entity
);
237 m_players
[0] = entity
;
238 m_players
[1] = entity
;
240 connection
->setListener(game_number
, entity
);
242 m_entity
->turnTest().clear();
247 std::cout
<< "** could not attach examination entity **" << std::endl
;
250 std::cout
<< "** could not detach entity **" << std::endl
;
255 bool EditGameController::setObserveMode(int game_number
, const shared_ptr
<ICSConnection
>& connection
) {
256 if (m_players
[0]->canDetach() &&
257 m_players
[1]->canDetach()) {
258 shared_ptr
<ICSEntity
> entity(new ObservingEntity(m_variant
, m_game
,
259 game_number
, connection
, &m_agents
));
261 if (entity
->attach()) {
262 m_agents
.addAgent(entity
);
263 m_players
[0] = entity
;
264 m_players
[1] = entity
;
266 connection
->setListener(game_number
, entity
);
268 m_entity
->turnTest().clear();
272 std::cout
<< "** could not attach ics entity for observe mode ** " << std::endl
;
275 std::cout
<< "** could not detach entity **" << std::endl
;
280 void EditGameController::loadPGN(const PGN
& pgn
) {
282 m_view
->resetClock();
283 entity()->loadPGN(pgn
);
286 void EditGameController::createCtrlAction() {
287 m_game
->createCtrlAction();
290 void EditGameController::destroyCtrlAction() {
291 m_game
->destroyCtrlAction();
294 void EditGameController::detach() {
296 m_players
[0]->detach();
297 m_players
[1]->detach();
299 foreach (shared_ptr
<Entity
> entity
, m_entities
)
303 shared_ptr
<Controller
> EditGameController::end() {
306 m_clock_agent
->stop();
307 m_clock_agent
= shared_ptr
<Agent
>(new ClockAgent(m_view
, m_game
));
310 // return to edit game mode
311 m_players
[0] = m_entity
;
312 m_players
[1] = m_entity
;
313 m_entity
->turnTest().setSimplePolicy(0, true);
314 m_entity
->turnTest().setSimplePolicy(1, true);
316 return Controller::end();
319 void EditGameController::reloadSettings() {
320 m_graphical
->settingsChanged();
323 void EditGameController::setUI(UI
& ui
) {
324 m_game
->setActionStateObserver(ui
.createActionStateObserver(shared_from_this()));
325 m_game
->onActionStateChange();
328 void EditGameController::activate() {
329 m_game
->onActionStateChange();