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"
27 using namespace boost
;
29 class ClockAgent
: public Agent
{
31 shared_ptr
<Game
> m_game
;
33 ClockAgent(ChessTable
* view
, const shared_ptr
<Game
>& game
)
37 virtual void notifyClockUpdate(int, int) { }
38 virtual void notifyMove(const Index
& index
) {
39 // start clock after the first 2 moves
40 if (index
.totalNumMoves() >= 2)
43 m_view
->changeClock(m_game
->position(index
)->turn());
45 virtual void notifyBack() { }
46 virtual void notifyForward() { }
47 virtual void notifyGotoFirst() { }
48 virtual void notifyGotoLast() { }
55 class ClockUpdateAgent
: public Agent
{
58 ClockUpdateAgent(ChessTable
* view
)
61 virtual void notifyClockUpdate(int white
, int black
) {
62 m_view
->updateTime(white
, black
);
64 virtual void notifyMove(const Index
&) { }
65 virtual void notifyBack() { }
66 virtual void notifyForward() { }
67 virtual void notifyGotoFirst() { }
68 virtual void notifyGotoLast() { }
71 EditGameController::EditGameController(ChessTable
* view
,
73 AbstractPosition::Ptr startingPosition
)
74 : Controller(view
) , m_variant(variant
) {
76 AbstractPosition::Ptr position
;
77 if (!startingPosition
) {
78 position
= m_variant
->createPosition();
81 else position
= startingPosition
;
83 m_graphical
= shared_ptr
<GraphicalSystem
>(new GraphicalSystem(m_view
, position
, m_variant
));
85 m_game
= shared_ptr
<GraphicalGame
>(new GraphicalGame(m_graphical
.get(),
86 m_view
->moveListTable()));
87 m_game
->reset(position
);
89 m_entity
= shared_ptr
<GameEntity
>(new GameEntity(m_variant
, m_game
, m_view
->board(), &m_agents
));
90 m_entity
->enableEditingTools(true);
92 m_graphical
->setup(m_entity
);
93 m_game
->setEntity(m_entity
);
96 init(AbstractPosition::Ptr());
99 void EditGameController::init(AbstractPosition::Ptr startingPosition
) {
100 m_players
[0] = m_entity
;
101 m_players
[1] = m_entity
;
102 m_entity
->turnTest().setSimplePolicy(0, true);
103 m_entity
->turnTest().setSimplePolicy(1, true);
105 if (startingPosition
) {
106 // TODO update to the starting position
110 m_agents
.addAgent(m_entity
);
112 m_clock_agent
= shared_ptr
<Agent
>(new ClockAgent(m_view
, m_game
));
113 m_update_agent
= shared_ptr
<Agent
>(new ClockUpdateAgent(m_view
));
115 // add clock update agent
116 m_agents
.addAgent(m_update_agent
);
119 QString
EditGameController::variant() const {
120 PositionPtr pos
= m_game
->position();
122 return pos
->variant();
127 void EditGameController::setPromotionType(int type
) {
128 m_entity
->changePromotionType(type
);
131 void EditGameController::onNavigation() { }
133 EntityToken
EditGameController::addPlayingEngine(int side
, const shared_ptr
<Engine
>& engine
) {
134 Q_ASSERT(side
== 0 || side
== 1);
136 return EntityToken();
138 if (m_players
[side
]->canDetach()) {
139 shared_ptr
<EngineEntity
> entity(new EngineEntity(m_variant
, m_game
, side
,
143 m_agents
.addAgent(entity
);
144 m_players
[side
] = entity
;
146 // the user cannot move the entity's pieces
147 m_entity
->turnTest().setSimplePolicy(side
, false);
149 return EntityToken(entity
);
152 std::cout
<< "** could not detach entity playing " << side
<< "**" << std::endl
;
155 return EntityToken();
158 // EntityToken EditGameController::addAnalysingEngine(const shared_ptr<Engine>& engine) {
159 // Q_ASSERT(engine.use_count() == 1);
160 // shared_ptr<EngineEntity> entity(new EngineEntity(m_variant, m_game, -1, engine, &m_agents));
161 // m_agents.addAgent(entity);
162 // EntityToken res(m_entities.insert(entity).first);
164 // engine->setNotifier(entity);
166 // engine->setBoard(m_game->position(), 0, 0);
167 // engine->startAnalysis();
172 void EditGameController::removeEntity(const EntityToken
& token
) {
173 shared_ptr
<Entity
> entity
= token
.entity();
176 for (int i
= 0; i
< 2; i
++) {
177 if (entity
== m_players
[i
]) {
178 m_players
[i
] = m_entity
;
179 m_entity
->turnTest().setSimplePolicy(i
, true);
183 // check other entities
184 std::set
<boost::shared_ptr
<Entity
> >::iterator it
= m_entities
.find(entity
);
185 if (it
!= m_entities
.end()) {
186 m_entities
.erase(it
);
189 std::cout
<< "there are " << m_entities
.size() << " entities left" << std::endl
;
192 bool EditGameController::addICSPlayer(int side
, int game_number
, const shared_ptr
<ICSConnection
>& connection
) {
193 Q_ASSERT(side
== 0 || side
== 1);
194 if (m_players
[side
]->canDetach()) {
195 shared_ptr
<ICSEntity
> entity(new ICSEntity(m_variant
, m_game
,
196 side
, game_number
, connection
, &m_agents
));
198 if (entity
->attach()) {
199 std::cout
<< "added ICS agent " << entity
.get() << std::endl
;
200 m_agents
.addAgent(entity
);
202 m_players
[side
] = entity
;
203 connection
->setListener(game_number
, entity
);
205 entity
->setupTurnTest(m_entity
->turnTest());
206 m_view
->flip(m_players
[1] == m_entity
); // flip if we're black!
208 m_agents
.addAgent(m_clock_agent
);
211 std::cout
<< "** could not attach ics entity **" << std::endl
;
216 std::cout
<< "** could not detach entity playing " << side
<< "**" << std::endl
;
223 bool EditGameController::setExaminationMode(int game_number
, const shared_ptr
<ICSConnection
>& connection
) {
224 std::cout
<< "[controller " << this << "] setting examination mode" << std::endl
;
225 if (m_players
[0]->canDetach() &&
226 m_players
[1]->canDetach()) {
227 shared_ptr
<ExaminationEntity
> entity(new ExaminationEntity(m_variant
, m_game
,
228 game_number
, connection
, &m_agents
));
229 if (entity
->attach()) {
231 m_view
->setEntity(entity
);
232 m_agents
.addAgent(entity
);
233 m_players
[0] = entity
;
234 m_players
[1] = entity
;
236 connection
->setListener(game_number
, entity
);
238 m_entity
->turnTest().clear();
243 std::cout
<< "** could not attach examination entity **" << std::endl
;
246 std::cout
<< "** could not detach entity **" << std::endl
;
251 bool EditGameController::setObserveMode(int game_number
, const shared_ptr
<ICSConnection
>& connection
) {
252 if (m_players
[0]->canDetach() &&
253 m_players
[1]->canDetach()) {
254 shared_ptr
<ICSEntity
> entity(new ObservingEntity(m_variant
, m_game
,
255 game_number
, connection
, &m_agents
));
257 if (entity
->attach()) {
258 m_agents
.addAgent(entity
);
259 m_players
[0] = entity
;
260 m_players
[1] = entity
;
262 connection
->setListener(game_number
, entity
);
264 m_entity
->turnTest().clear();
268 std::cout
<< "** could not attach ics entity for observe mode ** " << std::endl
;
271 std::cout
<< "** could not detach entity **" << std::endl
;
276 void EditGameController::loadPGN(const PGN
& pgn
) {
278 m_view
->resetClock();
279 entity()->loadPGN(pgn
);
282 void EditGameController::createCtrlAction() {
283 m_game
->createCtrlAction();
286 void EditGameController::destroyCtrlAction() {
287 m_game
->destroyCtrlAction();
290 void EditGameController::detach() {
292 m_players
[0]->detach();
293 m_players
[1]->detach();
295 foreach (shared_ptr
<Entity
> entity
, m_entities
)
299 shared_ptr
<Controller
> EditGameController::end() {
302 m_clock_agent
->stop();
303 m_clock_agent
= shared_ptr
<Agent
>(new ClockAgent(m_view
, m_game
));
306 // return to edit game mode
307 m_players
[0] = m_entity
;
308 m_players
[1] = m_entity
;
309 m_entity
->turnTest().setSimplePolicy(0, true);
310 m_entity
->turnTest().setSimplePolicy(1, true);
312 return Controller::end();