Added pool copying API. Crazyhouse works on ICS.
[tagua/yd.git] / src / entities / icsentity.cpp
blob1f9e622277a8f9729c8080e56c422af0b7d93195
1 /*
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.
9 */
11 #include "icsentity.h"
12 #include "game.h"
13 #include "algebraicnotation.h"
14 #include "icsconnection.h"
15 #include "positioninfo.h"
16 #include "poolinfo.h"
17 #include <iostream>
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)
24 : Entity(game)
25 , m_variant(variant)
26 , m_connection(connection)
27 , m_side(side)
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;
47 icsPos->dump();
48 icsPos->copyPoolFrom(position);
49 std::cout << "after copying pools" << std::endl;
50 icsPos->dump();
52 if (!position->equals(icsPos))
53 std::cout << "[inconsistency] computed position differs from expected!" << std::endl;
55 else
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);
64 m_game->goTo(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;
73 else return Forward;
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);
99 if (position) {
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)) {
103 std::cout <<
104 "[server inconsistency] SAN for last move is different from verbose notation"
105 << std::endl;
110 if (style12.index() > 0 && m_variant->name() != "Dummy"
111 && (!m_game->containsIndex(style12.index() - 1) || !m_game->position(style12.index() - 1)) )
112 requestMoves();
114 updateGame(style12.index(), last_move, style12.position);
117 void ICSEntity::notifyPool(const PoolInfo& pi) {
118 if (pi.m_game_num != m_game_number)
119 return;
121 return; // BROKEN
122 if (m_game->containsIndex(pi.m_pos_index)) {
123 AbstractPosition::Ptr p = m_game->position(pi.m_pos_index);
124 //BROKEN
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;
136 return;
139 Game g;
140 g.reset(pos);
141 g.load(pgn);
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...
151 return true;
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));
162 return true;
164 return false;
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() {
184 m_attached = false;
187 ObservingEntity::~ObservingEntity() {
188 if (m_attached)
189 m_connection->sendText(QString("unobs %1").arg(m_game_number));