Update for doxygen 1.5.5, graph generation, and match current code.
[tagua/yd.git] / src / xboardengine.cpp
blobc671e4dfbd1c6e76d839256e44e5666e383ac477
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 "xboardengine.h"
13 #include <KDebug>
14 #include <QFileInfo>
15 #include <QRegExp>
17 #include <core/moveserializer.h>
19 #include "components.h"
20 #include "enginenotifier.h"
21 #include "foreach.h"
23 using namespace boost;
25 QRegExp XBoardEngine::m_move_pattern("My move is: (.*)");
27 XBoardEngine::XBoardEngine(Components* components,
28 const QString& path,
29 const QStringList& arguments)
30 : Engine(path, arguments)
31 , m_analysing(false)
32 , m_components(components)
33 , m_serializer(0) {
34 // set default features
35 m_features.ping = false;
36 m_features.setboard = false;
37 m_features.playother = false;
38 m_features.san = false;
39 m_features.usermove = false;
40 m_features.time = true;
41 m_features.draw = true;
42 m_features.sigint = true;
43 m_features.sigterm = true;
44 m_features.reuse = true;
45 m_features.analyze = true;
46 m_features.colors = true;
47 m_features.ics = false;
48 m_features.name = false;
49 m_features.pause = false;
51 m_features.myname = QFileInfo(m_path).baseName();
53 connect(this, SIGNAL(receivedCommand(const QString&)),
54 this, SLOT(processCommand(const QString&)));
57 XBoardEngine::~XBoardEngine() {
58 kDebug() << "[debug] destroying engine";
59 stop();
60 m_engine.kill();
63 void XBoardEngine::initializeEngine() {
64 // set up in xboard mode
65 sendCommand("xboard");
67 // we're using xboard protocol version 2
68 sendCommand("protover 2");
70 // don't flood me!
71 sendCommand("nopost");
74 void XBoardEngine::reset() {
75 sendCommand("new"); // start a new game
76 sendCommand("force"); // do not think
79 void XBoardEngine::play() {
80 sendCommand("go"); // start playing
83 void XBoardEngine::stop() {
84 sendCommand("quit");
85 if (m_features.sigterm)
86 m_engine.kill();
89 void XBoardEngine::processCommand(const QString& command) {
90 QStringList arg_list = command.split(QRegExp("\\s+"));
91 QString cmd = arg_list.takeFirst();
93 if (cmd == "feature") {
94 QRegExp feature("(\\S+)=(\\S+)");
95 foreach (QString arg, arg_list) {
96 if (feature.indexIn(arg) == 0) {
97 bool rejected = false;
99 QString key = feature.cap(1);
100 QString value = feature.cap(2);
102 if (key == "ping")
103 m_features.ping = value == "1";
104 else if (key == "setboard")
105 m_features.setboard = value == "1";
106 else if (key == "playother")
107 m_features.playother = value == "1";
108 else if (key == "san")
109 m_features.san = value == "1";
110 else if (key == "usermove")
111 m_features.usermove = value == "1";
112 else if (key == "time")
113 m_features.time = value == "1";
114 else if (key == "draw")
115 m_features.draw = value == "1";
116 else if (key == "sigint")
117 m_features.sigint = value == "1";
118 else if (key == "sigterm")
119 m_features.sigterm = value == "1";
120 else if (key == "reuse")
121 m_features.reuse = value == "1";
122 else if (key == "analyze")
123 m_features.analyze = value == "1";
124 else if (key == "myname")
125 m_features.myname = value.mid(1, value.length() - 2);
126 else if (key == "variants")
127 m_features.variants = value.mid(1, value.length() - 2);
128 else if (key == "colors")
129 m_features.colors = value == "1";
130 else if (key == "ics")
131 m_features.ics = value == "1";
132 else if (key == "name")
133 m_features.name = value == "1";
134 else if (key == "pause")
135 m_features.pause = value == "1";
136 else if (key == "done")
137 m_features.done = value == "1";
138 else
139 rejected = true;
141 if (rejected)
142 sendCommand("rejected " + key);
143 else
144 sendCommand("accepted " + key);
148 else if (cmd == "move") {
149 if (shared_ptr<EngineNotifier> notifier = m_notifier.lock())
150 notifier->notifyEngineMove(arg_list[0]);
152 else if (m_move_pattern.indexIn(command) == 0) {
153 if (shared_ptr<EngineNotifier> notifier = m_notifier.lock())
154 notifier->notifyEngineMove(m_move_pattern.cap(1));
157 m_serializer = m_components->moveSerializer(m_features.san ? "san" : "simple");
160 void XBoardEngine::sendMove(const Move& move, const StatePtr& ref) {
161 if (m_serializer) {
162 QString move_str = m_serializer->serialize(move, ref.get());
163 if (m_features.usermove)
164 move_str = "usermove " + move_str;
165 sendCommand(move_str);
169 void XBoardEngine::backUp(const StatePtr&) {
170 sendCommand("undo");
173 void XBoardEngine::startAnalysis() {
174 sendCommand("post");
175 sendCommand("analyze");
176 m_analysing = true;
179 void XBoardEngine::stopAnalysis() {
180 sendCommand("exit");
181 m_analysing = false;
184 void XBoardEngine::setBoard(const StatePtr&) {
185 #if 0
186 if (m_features.setboard) {
187 sendCommand(QString("setboard %1").arg(pos->fen(halfmove, fullmove)));
189 else {
190 // this is pretty meaningless for generic variants
191 if (pos->turn() != 0) {
192 sendCommand("new");
193 sendCommand("a2a3");
196 sendCommand("edit");
197 sendCommand("#");
198 Point size = pos->size();
199 for (int i = 0; i < size.x; i++) {
200 for (int j = 0; j < size.y; j++) {
201 Point p(i, j);
202 AbstractPiece::Ptr piece = pos->get(p);
203 if (piece) sendCommand(QString("%1%2")
204 .arg(piece->type())
205 .arg(p.toString(8)));
208 sendCommand(".");
210 #endif