2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@sns.it>
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"
28 using namespace boost
;
30 class ClockAgent
: public Agent
{
32 shared_ptr
<Game
> m_game
;
34 ClockAgent(ChessTable
* view
, const shared_ptr
<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)
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() { }
56 class ClockUpdateAgent
: public Agent
{
59 ClockUpdateAgent(ChessTable
* 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();
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() {
101 delete m_variant_actions
;
104 void EditGameController::init(AbstractPosition::Ptr startingPosition
) {
105 m_players
[0] = m_entity
;
106 m_players
[1] = m_entity
;
107 m_entity
->turnTest().setSimplePolicy(0, true);
108 m_entity
->turnTest().setSimplePolicy(1, true);
110 if (startingPosition
) {
111 // TODO update to the starting position
115 m_agents
.addAgent(m_entity
);
117 m_clock_agent
= shared_ptr
<Agent
>(new ClockAgent(m_view
, m_game
));
118 m_update_agent
= shared_ptr
<Agent
>(new ClockUpdateAgent(m_view
));
120 // add clock update agent
121 m_agents
.addAgent(m_update_agent
);
123 // setup variant actions
124 m_variant_actions
= new ActionCollection
;
125 m_variant
->setupActions(m_variant_actions
);
128 QString
EditGameController::variant() const {
129 PositionPtr pos
= m_game
->position();
131 return pos
->variant();
136 void EditGameController::setPromotionType(int type
) {
137 m_entity
->changePromotionType(type
);
140 void EditGameController::onNavigation() { }
142 EntityToken
EditGameController::addPlayingEngine(int side
, const shared_ptr
<Engine
>& engine
) {
143 Q_ASSERT(side
== 0 || side
== 1);
145 return EntityToken();
147 if (m_players
[side
]->canDetach()) {
148 shared_ptr
<EngineEntity
> entity(new EngineEntity(m_variant
, m_game
, side
,
152 m_agents
.addAgent(entity
);
153 m_players
[side
] = entity
;
155 // the user cannot move the entity's pieces
156 m_entity
->turnTest().setSimplePolicy(side
, false);
158 return EntityToken(entity
);
161 std::cout
<< "** could not detach entity playing " << side
<< "**" << std::endl
;
164 return EntityToken();
167 // EntityToken EditGameController::addAnalysingEngine(const shared_ptr<Engine>& engine) {
168 // Q_ASSERT(engine.use_count() == 1);
169 // shared_ptr<EngineEntity> entity(new EngineEntity(m_variant, m_game, -1, engine, &m_agents));
170 // m_agents.addAgent(entity);
171 // EntityToken res(m_entities.insert(entity).first);
173 // engine->setNotifier(entity);
175 // engine->setBoard(m_game->position(), 0, 0);
176 // engine->startAnalysis();
181 void EditGameController::removeEntity(const EntityToken
& token
) {
182 shared_ptr
<Entity
> entity
= token
.entity();
185 for (int i
= 0; i
< 2; i
++) {
186 if (entity
== m_players
[i
]) {
187 m_players
[i
] = m_entity
;
188 m_entity
->turnTest().setSimplePolicy(i
, true);
192 // check other entities
193 std::set
<boost::shared_ptr
<Entity
> >::iterator it
= m_entities
.find(entity
);
194 if (it
!= m_entities
.end()) {
195 m_entities
.erase(it
);
198 std::cout
<< "there are " << m_entities
.size() << " entities left" << std::endl
;
201 bool EditGameController::addICSPlayer(int side
, int game_number
, const shared_ptr
<ICSConnection
>& connection
) {
202 Q_ASSERT(side
== 0 || side
== 1);
203 if (m_players
[side
]->canDetach()) {
204 shared_ptr
<ICSEntity
> entity(new ICSEntity(m_variant
, m_game
,
205 side
, game_number
, connection
, &m_agents
));
207 if (entity
->attach()) {
208 std::cout
<< "added ICS agent " << entity
.get() << std::endl
;
209 m_agents
.addAgent(entity
);
211 m_players
[side
] = entity
;
212 connection
->setListener(game_number
, entity
);
214 entity
->setupTurnTest(m_entity
->turnTest());
215 m_view
->flip(m_players
[1] == m_entity
); // flip if we're black!
217 m_agents
.addAgent(m_clock_agent
);
220 std::cout
<< "** could not attach ics entity **" << std::endl
;
225 std::cout
<< "** could not detach entity playing " << side
<< "**" << std::endl
;
232 bool EditGameController::setExaminationMode(int game_number
, const shared_ptr
<ICSConnection
>& connection
) {
233 std::cout
<< "[controller " << this << "] setting examination mode" << std::endl
;
234 if (m_players
[0]->canDetach() &&
235 m_players
[1]->canDetach()) {
236 shared_ptr
<ExaminationEntity
> entity(new ExaminationEntity(m_variant
, m_game
,
237 game_number
, connection
, &m_agents
));
238 if (entity
->attach()) {
240 m_view
->setEntity(entity
);
241 m_agents
.addAgent(entity
);
242 m_players
[0] = entity
;
243 m_players
[1] = entity
;
245 connection
->setListener(game_number
, entity
);
247 m_entity
->turnTest().clear();
252 std::cout
<< "** could not attach examination entity **" << std::endl
;
255 std::cout
<< "** could not detach entity **" << std::endl
;
260 bool EditGameController::setObserveMode(int game_number
, const shared_ptr
<ICSConnection
>& connection
) {
261 if (m_players
[0]->canDetach() &&
262 m_players
[1]->canDetach()) {
263 shared_ptr
<ICSEntity
> entity(new ObservingEntity(m_variant
, m_game
,
264 game_number
, connection
, &m_agents
));
266 if (entity
->attach()) {
267 m_agents
.addAgent(entity
);
268 m_players
[0] = entity
;
269 m_players
[1] = entity
;
271 connection
->setListener(game_number
, entity
);
273 m_entity
->turnTest().clear();
277 std::cout
<< "** could not attach ics entity for observe mode ** " << std::endl
;
280 std::cout
<< "** could not detach entity **" << std::endl
;
285 void EditGameController::loadPGN(const PGN
& pgn
) {
287 m_view
->resetClock();
288 entity()->loadPGN(pgn
);
291 void EditGameController::createCtrlAction() {
292 m_game
->createCtrlAction();
295 void EditGameController::destroyCtrlAction() {
296 m_game
->destroyCtrlAction();
299 void EditGameController::detach() {
301 m_players
[0]->detach();
302 m_players
[1]->detach();
304 foreach (shared_ptr
<Entity
> entity
, m_entities
)
308 shared_ptr
<Controller
> EditGameController::end() {
311 m_clock_agent
->stop();
312 m_clock_agent
= shared_ptr
<Agent
>(new ClockAgent(m_view
, m_game
));
315 // return to edit game mode
316 m_players
[0] = m_entity
;
317 m_players
[1] = m_entity
;
318 m_entity
->turnTest().setSimplePolicy(0, true);
319 m_entity
->turnTest().setSimplePolicy(1, true);
321 return Controller::end();