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 icsPos
->copyPoolFrom(position
);
48 if (!position
->equals(icsPos
))
49 std::cout
<< "[inconsistency] computed position differs from expected!" << std::endl
;
52 std::cout
<< "[inconsistency] invalid move from server!" << std::endl
;
56 if (m_game
->lastMainlineIndex() > index
)
57 m_game
->truncate(index
);
59 m_game
->insert(icsMove
, icsPos
, index
);
61 m_dispatcher
.move(index
);
64 ICSEntity::UpdateType
ICSEntity::getUpdate(const Index
& index
) {
65 std::pair
<int, int> steps
= m_game
->index().stepsTo(index
);
66 if (steps
.first
== 0) {
67 if (steps
.second
== 0) return NoMove
;
68 else if (steps
.second
== 1) return MoveForward
;
71 else if (steps
.first
== 1 && steps
.second
== 0) return MoveBack
;
72 else if (steps
.second
== 0) return Back
;
74 return NonComparableIndexes
;
77 void ICSEntity::notifyStyle12(const PositionInfo
& style12
, bool is_starting
) {
78 if (style12
.gameNumber
!= m_game_number
) return;
80 m_dispatcher
.clockUpdate(style12
.whiteTime
, style12
.blackTime
);
82 // get last move verbose notation
83 AbstractMove::Ptr last_move
;
84 VerboseNotation
last_move_verbose_notation(style12
.lastMove
, style12
.position
->size().y
);
85 if (!is_starting
&& last_move_verbose_notation
.valid())
86 last_move
= m_variant
->getVerboseMove(
87 style12
.position
->previousTurn(),
88 last_move_verbose_notation
);
90 if (style12
.index() > 0 && m_game
->containsIndex(style12
.index() - 1)
91 && last_move
&& m_variant
->name() != "Dummy") {
92 AbstractPosition::Ptr position
= m_game
->position(style12
.index() - 1);
94 AlgebraicNotation
last_move_alg_notation(style12
.lastMoveSAN
, style12
.position
->size().y
);
95 AbstractMove::Ptr mv
= position
->getMove(last_move_alg_notation
);
96 if (!mv
|| !mv
->equals(last_move
)) {
98 "[server inconsistency] SAN for last move is different from verbose notation"
104 if (style12
.index() > 0 && m_variant
->name() != "Dummy"
105 && (!m_game
->containsIndex(style12
.index() - 1) || !m_game
->position(style12
.index() - 1)) )
108 updateGame(style12
.index(), last_move
, style12
.position
);
111 void ICSEntity::notifyPool(const PoolInfo
& pi
) {
112 if (pi
.m_game_num
!= m_game_number
)
116 if (m_game
->containsIndex(pi
.m_pos_index
)) {
117 AbstractPosition::Ptr p
= m_game
->position(pi
.m_pos_index
);
119 //p->setPool(pi.m_pool);
120 m_game
->insert(m_game
->move(pi
.m_pos_index
), p
, pi
.m_pos_index
);
124 void ICSEntity::notifyMoveList(int num
, AbstractPosition::Ptr pos
, const PGN
& pgn
) {
125 if (m_game_number
!= num
) return;
127 if(pos
->variant() != m_variant
->name()) {
128 std::cout
<< "Mismatch for move list, this variant is \"" << m_variant
->name() << "\",\n"
129 " got move list for \"" << pos
->variant() << "\"" << std::endl
;
137 for(int i
=0;i
<=g
.lastMainlineIndex().num_moves
;i
++) {
138 m_game
->insert(g
.move(i
), g
.position(i
), i
);
140 //m_game->load(pos, pgn);
143 bool ICSEntity::canDetach() const {
144 // TODO: ask whether abort or resign...
149 bool ICSEntity::attach() {
150 // an ICS player can attach only if no move for that side has been made
151 //std::cout << "[ICS attach] index = " << m_game->lastMainlineIndex() << std::endl;
152 if (m_game
->lastMainlineIndex() == 0) return true;
153 if (m_game
->lastMainlineIndex() == 1 && m_side
== 1) {
154 // white already played, inform black
155 m_dispatcher
.move(0);
161 void ICSEntity::notifyMove(const Index
& index
) {
162 //Use coordinates bacause FICS is stupid and would consider bxc6 ambiguous (Bxc6)
163 m_connection
->sendText(m_game
->move(index
)->toString(m_game
->position(index
.prev())));
164 //m_connection->sendText(move->SAN(ref));
167 void ICSEntity::requestMoves() {
168 m_connection
->sendText(QString("moves %1").arg(m_game_number
));
172 ObservingEntity::ObservingEntity(VariantInfo
* variant
, const shared_ptr
<Game
>& game
,
173 int gameNumber
,const shared_ptr
<ICSConnection
>& connection
, AgentGroup
* group
)
174 : ICSEntity(variant
, game
, -1, gameNumber
, connection
, group
)
175 , m_attached(true) { }
177 void ObservingEntity::detach() {
181 ObservingEntity::~ObservingEntity() {
183 m_connection
->sendText(QString("unobs %1").arg(m_game_number
));