Replaced all std::cout with kDebug.
[tagua/yd.git] / src / entities / icsentity.cpp
blob4a8582a10bbfc3747ea7e7d002cedc322f17d892
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 "icsentity.h"
12 #include <KDebug>
13 #include "game.h"
14 #include "icsconnection.h"
15 #include "positioninfo.h"
16 #include "poolinfo.h"
17 #include "icsapi.h"
19 using namespace boost;
21 class ICSTurnPolicy : public TurnPolicy::Abstract {
22 const ICSEntity* m_entity;
23 public:
24 ICSTurnPolicy(const ICSEntity* entity);
26 virtual bool check() const;
29 ICSTurnPolicy::ICSTurnPolicy(const ICSEntity* entity)
30 : m_entity(entity) { }
32 bool ICSTurnPolicy::check() const {
33 return m_entity->canEdit();
36 class ICSPremovePolicy : public TurnPolicy::Premove {
37 const ICSEntity* m_entity;
38 public:
39 ICSPremovePolicy(const ICSEntity* entity);
41 virtual bool check() const;
44 ICSPremovePolicy::ICSPremovePolicy(const ICSEntity* entity)
45 : m_entity(entity) { }
47 bool ICSPremovePolicy::check() const {
48 return !m_entity->canEdit();
52 ICSEntity::ICSEntity(const VariantPtr& variant, const shared_ptr<Game>& game,
53 int side, int gameNumber,
54 const shared_ptr<ICSConnection>& connection, AgentGroup* group)
55 : Entity(game)
56 , m_variant(variant)
57 , m_icsapi(variant->icsAPI())
58 , m_connection(connection)
59 , m_side(side)
60 , m_game_number(gameNumber)
61 , m_editing_mode(false)
62 , m_dispatcher(group, this) {
63 Q_ASSERT(m_icsapi);
66 AbstractPosition::Ptr ICSEntity::position() const {
67 return m_game->position();
70 void ICSEntity::executeMove(AbstractMove::Ptr) { }
72 void ICSEntity::updateGame(const Index& index, AbstractMove::Ptr icsMove,
73 AbstractPosition::Ptr icsPos) {
74 if (index > 0 && m_game->containsIndex(index.prev()) && icsMove) {
75 if (AbstractPosition::Ptr position = m_game->position(index.prev())) {
76 position = position->clone();
78 if (position->testMove(icsMove)) {
79 position->move(icsMove);
81 icsPos->copyPoolFrom(position);
83 if (!position->equals(icsPos))
84 kDebug() << "[inconsistency] computed position differs from expected!";
86 else
87 kDebug() << "[inconsistency] invalid move from server!";
91 if (m_game->lastMainlineIndex() > index)
92 m_game->truncate(index);
94 m_game->insert(icsMove, icsPos, index);
95 m_game->goTo(index);
96 m_dispatcher.move(index);
99 ICSEntity::UpdateType ICSEntity::getUpdate(const Index& index) {
100 std::pair<int, int> steps = m_game->index().stepsTo(index);
101 if (steps.first == 0) {
102 if (steps.second == 0) return NoMove;
103 else if (steps.second == 1) return MoveForward;
104 else return Forward;
106 else if (steps.first == 1 && steps.second == 0) return MoveBack;
107 else if (steps.second == 0) return Back;
109 return NonComparableIndexes;
112 void ICSEntity::notifyStyle12(const PositionInfo& style12, bool is_starting) {
113 if (style12.gameNumber != m_game_number) return;
115 m_dispatcher.clockUpdate(style12.whiteTime, style12.blackTime);
117 // get last move verbose notation
118 AbstractMove::Ptr last_move;
119 if (!is_starting)
120 last_move = m_icsapi->parseVerbose(style12.lastMove, style12.position);
122 if (style12.index() > 0 && m_game->containsIndex(style12.index() - 1)
123 && last_move && m_variant->name() != "Dummy") {
124 AbstractPosition::Ptr position = m_game->position(style12.index() - 1);
125 if (position) {
126 AbstractMove::Ptr mv = position->getMove(style12.lastMoveSAN);
127 if (!mv || !mv->equals(last_move)) {
128 kDebug() <<
129 "[server inconsistency] SAN for last move is different from verbose notation"
135 if (style12.index() > 0 && m_variant->name() != "Dummy"
136 && (!m_game->containsIndex(style12.index() - 1) || !m_game->position(style12.index() - 1)) )
137 requestMoves();
139 updateGame(style12.index(), last_move, style12.position);
142 void ICSEntity::notifyPool(const PoolInfo& pi) {
143 if (pi.m_game_num != m_game_number)
144 return;
146 return; // BROKEN
147 if (m_game->containsIndex(pi.m_pos_index)) {
148 AbstractPosition::Ptr p = m_game->position(pi.m_pos_index);
149 //BROKEN
150 //p->setPool(pi.m_pool);
151 m_game->insert(m_game->move(pi.m_pos_index), p, pi.m_pos_index );
155 void ICSEntity::notifyMoveList(int num, AbstractPosition::Ptr pos, const PGN& pgn) {
156 if (m_game_number != num) return;
158 if(pos->variant() != m_variant->name()) {
159 kDebug() << "Mismatch for move list, this variant is \"" << m_variant->name() << "\",\n"
160 " got move list for \"" << pos->variant() << "\"";
161 return;
164 Game g;
165 g.reset(pos);
166 g.load(pgn);
168 for(int i=0;i<=g.lastMainlineIndex().num_moves;i++) {
169 m_game->insert(g.move(i), g.position(i), i);
171 //m_game->load(pos, pgn);
174 bool ICSEntity::canDetach() const {
175 // TODO: ask whether abort or resign...
176 return true;
180 bool ICSEntity::attach() {
181 // an ICS player can attach only if no move for that side has been made
182 //kDebug() << "[ICS attach] index = " << m_game->lastMainlineIndex();
183 if (m_game->lastMainlineIndex() == 0) return true;
184 if (m_game->lastMainlineIndex() == 1 && m_side == 1) {
185 // white already played, inform black
186 m_dispatcher.move(0);
187 return true;
189 return false;
192 void ICSEntity::notifyMove(const Index& index) {
193 if (!canEdit()) {
194 m_connection->sendText(m_game->move(index)->toString(
195 "simple", m_game->position(index.prev())));
199 void ICSEntity::requestMoves() {
200 m_connection->sendText(QString("moves %1").arg(m_game_number));
203 bool ICSEntity::canEdit() const {
204 return canEdit(m_game->index());
207 bool ICSEntity::canEdit(const Index& index) const {
208 return m_editing_mode || index != m_game->lastMainlineIndex();
211 void ICSEntity::setupTurnTest(TurnTest& test) const {
212 test.setPolicy(m_side, shared_ptr<TurnPolicy::Abstract>(new ICSTurnPolicy(this)));
213 test.setPremovePolicy(shared_ptr<TurnPolicy::Premove>(new ICSPremovePolicy(this)));
217 ObservingEntity::ObservingEntity(const VariantPtr& variant, const shared_ptr<Game>& game,
218 int gameNumber,const shared_ptr<ICSConnection>& connection, AgentGroup* group)
219 : ICSEntity(variant, game, -1, gameNumber, connection, group)
220 , m_attached(true) { }
222 void ObservingEntity::detach() {
223 m_attached = false;
226 ObservingEntity::~ObservingEntity() {
227 if (m_attached)
228 m_connection->sendText(QString("unobs %1").arg(m_game_number));