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.
11 #include "icsentity.h"
13 #include "algebraicnotation.h"
14 #include "icsconnection.h"
15 #include "positioninfo.h"
19 using namespace boost
;
21 ICSEntity::ICSEntity(VariantInfo
* variant
, const shared_ptr
<Game
>& game
,
22 int side
, int gameNumber
,
23 const shared_ptr
<ICSConnection
>& connection
, AgentGroup
* group
)
26 , m_connection(connection
)
28 , m_game_number(gameNumber
)
29 , m_dispatcher(group
, this) { }
31 AbstractPosition::Ptr
ICSEntity::position() const {
32 return m_game
->position();
35 void ICSEntity::executeMove(AbstractMove::Ptr
) { }
37 void ICSEntity::updateGame(const Index
& index
, AbstractMove::Ptr icsMove
,
38 AbstractPosition::Ptr icsPos
) {
39 if (index
> 0 && m_game
->containsIndex(index
.prev()) && icsMove
) {
40 if (AbstractPosition::Ptr position
= m_game
->position(index
.prev())) {
41 position
= position
->clone();
43 if (position
->testMove(icsMove
)) {
44 position
->move(icsMove
);
46 std::cout
<< "before copying pools" << std::endl
;
48 icsPos
->copyPoolFrom(position
);
49 std::cout
<< "after copying pools" << std::endl
;
52 if (!position
->equals(icsPos
))
53 std::cout
<< "[inconsistency] computed position differs from expected!" << std::endl
;
56 std::cout
<< "[inconsistency] invalid move from server!" << std::endl
;
60 if (m_game
->lastMainlineIndex() > index
)
61 m_game
->truncate(index
);
63 m_game
->insert(icsMove
, icsPos
, index
);
65 m_dispatcher
.move(icsMove
, icsPos
);
68 ICSEntity::UpdateType
ICSEntity::getUpdate(const Index
& index
) {
69 std::pair
<int, int> steps
= m_game
->index().stepsTo(index
);
70 if (steps
.first
== 0) {
71 if (steps
.second
== 0) return NoMove
;
72 else if (steps
.second
== 1) return MoveForward
;
75 else if (steps
.first
== 1 && steps
.second
== 0) return MoveBack
;
76 else if (steps
.second
== 0) return Back
;
78 return NonComparableIndexes
;
81 void ICSEntity::notifyStyle12(const PositionInfo
& style12
, bool is_starting
) {
82 if (style12
.gameNumber
!= m_game_number
) return;
84 m_dispatcher
.clockUpdate(style12
.whiteTime
, style12
.blackTime
);
86 // get last move verbose notation
87 AbstractMove::Ptr last_move
;
88 VerboseNotation
last_move_verbose_notation(style12
.lastMove
, style12
.position
->size().y
);
89 if (!is_starting
&& last_move_verbose_notation
.valid())
90 last_move
= m_variant
->getVerboseMove(
91 style12
.position
->previousTurn(),
92 last_move_verbose_notation
);
94 std::cout
<< "index = " << style12
.index() << std::endl
;
96 if (style12
.index() > 0 && m_game
->containsIndex(style12
.index() - 1)
97 && last_move
&& m_variant
->name() != "Dummy") {
98 AbstractPosition::Ptr position
= m_game
->position(style12
.index() - 1);
100 AlgebraicNotation
last_move_alg_notation(style12
.lastMoveSAN
, style12
.position
->size().y
);
101 AbstractMove::Ptr mv
= position
->getMove(last_move_alg_notation
);
102 if (!mv
|| !mv
->equals(last_move
)) {
104 "[server inconsistency] SAN for last move is different from verbose notation"
110 if (style12
.index() > 0 && m_variant
->name() != "Dummy"
111 && (!m_game
->containsIndex(style12
.index() - 1) || !m_game
->position(style12
.index() - 1)) )
114 updateGame(style12
.index(), last_move
, style12
.position
);
117 void ICSEntity::notifyPool(const PoolInfo
& pi
) {
118 if (pi
.m_game_num
!= m_game_number
)
122 if (m_game
->containsIndex(pi
.m_pos_index
)) {
123 AbstractPosition::Ptr p
= m_game
->position(pi
.m_pos_index
);
125 //p->setPool(pi.m_pool);
126 m_game
->insert(m_game
->move(pi
.m_pos_index
), p
, pi
.m_pos_index
);
130 void ICSEntity::notifyMoveList(int num
, AbstractPosition::Ptr pos
, const PGN
& pgn
) {
131 if (m_game_number
!= num
) return;
133 if(pos
->variant() != m_variant
->name()) {
134 std::cout
<< "Mismatch for move list, this variant is \"" << m_variant
->name() << "\",\n"
135 " got move list for \"" << pos
->variant() << "\"" << std::endl
;
143 for(int i
=0;i
<=g
.lastMainlineIndex().num_moves
;i
++) {
144 m_game
->insert(g
.move(i
), g
.position(i
), i
);
146 //m_game->load(pos, pgn);
149 bool ICSEntity::canDetach() const {
150 // TODO: ask whether abort or resign...
155 bool ICSEntity::attach() {
156 // an ICS player can attach only if no move for that side has been made
157 //std::cout << "[ICS attach] index = " << m_game->lastMainlineIndex() << std::endl;
158 if (m_game
->lastMainlineIndex() == 0) return true;
159 if (m_game
->lastMainlineIndex() == 1 && m_side
== 1) {
160 // white already played, inform black
161 m_dispatcher
.move(m_game
->move(0), m_game
->position(0));
167 void ICSEntity::notifyMove(AbstractMove::Ptr move
, AbstractPosition::Ptr ref
) {
168 //Use coordinates bacause FICS is stupid and would consider bxc6 ambiguous (Bxc6)
169 m_connection
->sendText(move
->toString(ref
));
170 //m_connection->sendText(move->SAN(ref));
173 void ICSEntity::requestMoves() {
174 m_connection
->sendText(QString("moves %1").arg(m_game_number
));
178 ObservingEntity::ObservingEntity(VariantInfo
* variant
, const shared_ptr
<Game
>& game
,
179 int gameNumber
,const shared_ptr
<ICSConnection
>& connection
, AgentGroup
* group
)
180 : ICSEntity(variant
, game
, -1, gameNumber
, connection
, group
)
181 , m_attached(true) { }
183 void ObservingEntity::detach() {
187 ObservingEntity::~ObservingEntity() {
189 m_connection
->sendText(QString("unobs %1").arg(m_game_number
));