Rough PGN save support.
[tagua/yd.git] / src / xboardengine.cpp
blob0319d62b3b5bd38185719d732d444566e6692403
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 <QFileInfo>
14 #include <QRegExp>
15 #include <iostream>
17 #include "enginenotifier.h"
18 #include "foreach.h"
20 using namespace boost;
22 QRegExp XBoardEngine::m_move_pattern("My move is: (.*)");
24 XBoardEngine::XBoardEngine(const QString& path, const QStringList& arguments)
25 : Engine(path, arguments)
26 , m_analysing(false) {
27 // set default features
28 m_features.ping = false;
29 m_features.setboard = false;
30 m_features.playother = false;
31 m_features.san = false;
32 m_features.usermove = false;
33 m_features.time = true;
34 m_features.draw = true;
35 m_features.sigint = true;
36 m_features.sigterm = true;
37 m_features.reuse = true;
38 m_features.analyze = true;
39 m_features.colors = true;
40 m_features.ics = false;
41 m_features.name = false;
42 m_features.pause = false;
44 m_features.myname = QFileInfo(m_path).baseName();
46 connect(this, SIGNAL(receivedCommand(const QString&)),
47 this, SLOT(processCommand(const QString&)));
50 XBoardEngine::~XBoardEngine() {
51 std::cout << "[debug] destroying engine" << std::endl;
52 stop();
53 m_engine.kill();
56 void XBoardEngine::initializeEngine() {
57 // set up in xboard mode
58 sendCommand("xboard");
60 // we're using xboard protocol version 2
61 sendCommand("protover 2");
63 // don't flood me!
64 sendCommand("nopost");
67 void XBoardEngine::reset() {
68 sendCommand("new"); // start a new game
69 sendCommand("force"); // do not think
72 void XBoardEngine::play() {
73 sendCommand("go"); // start playing
76 void XBoardEngine::stop() {
77 sendCommand("quit");
78 if (m_features.sigterm)
79 m_engine.kill();
82 void XBoardEngine::processCommand(const QString& command) {
83 QStringList arg_list = command.split(QRegExp("\\s+"));
84 QString cmd = arg_list.takeFirst();
86 if (cmd == "feature") {
87 QRegExp feature("(\\S+)=(\\S+)");
88 foreach (QString arg, arg_list) {
89 if (feature.indexIn(arg) == 0) {
90 bool rejected = false;
92 QString key = feature.cap(1);
93 QString value = feature.cap(2);
95 if (key == "ping")
96 m_features.ping = value == "1";
97 else if (key == "setboard")
98 m_features.setboard = value == "1";
99 else if (key == "playother")
100 m_features.playother = value == "1";
101 else if (key == "san")
102 m_features.san = value == "1";
103 else if (key == "usermove")
104 m_features.usermove = value == "1";
105 else if (key == "time")
106 m_features.time = value == "1";
107 else if (key == "draw")
108 m_features.draw = value == "1";
109 else if (key == "sigint")
110 m_features.sigint = value == "1";
111 else if (key == "sigterm")
112 m_features.sigterm = value == "1";
113 else if (key == "reuse")
114 m_features.reuse = value == "1";
115 else if (key == "analyze")
116 m_features.analyze = value == "1";
117 else if (key == "myname")
118 m_features.myname = value.mid(1, value.length() - 2);
119 else if (key == "variants")
120 m_features.variants = value.mid(1, value.length() - 2);
121 else if (key == "colors")
122 m_features.colors = value == "1";
123 else if (key == "ics")
124 m_features.ics = value == "1";
125 else if (key == "name")
126 m_features.name = value == "1";
127 else if (key == "pause")
128 m_features.pause = value == "1";
129 else if (key == "done")
130 m_features.done = value == "1";
131 else
132 rejected = true;
134 if (rejected)
135 sendCommand("rejected " + key);
136 else
137 sendCommand("accepted " + key);
141 else if (cmd == "move") {
142 if (shared_ptr<EngineNotifier> notifier = m_notifier.lock())
143 notifier->notifyEngineMove(arg_list[0]);
145 else if (m_move_pattern.indexIn(command) == 0) {
146 if (shared_ptr<EngineNotifier> notifier = m_notifier.lock())
147 notifier->notifyEngineMove(m_move_pattern.cap(1));
151 void XBoardEngine::sendMove(AbstractMove::Ptr move, AbstractPosition::Ptr ref) {
152 QString move_str = move->toString(m_features.san ? "compact" : "simple", ref);
153 if (m_features.usermove)
154 move_str = "usermove " + move_str;
155 sendCommand(move_str);
158 void XBoardEngine::backUp(AbstractPosition::Ptr) {
159 sendCommand("undo");
162 void XBoardEngine::startAnalysis() {
163 sendCommand("post");
164 sendCommand("analyze");
165 m_analysing = true;
168 void XBoardEngine::stopAnalysis() {
169 sendCommand("exit");
170 m_analysing = false;
173 void XBoardEngine::setBoard(AbstractPosition::Ptr, int, int) {
174 #if 0
175 if (m_features.setboard) {
176 sendCommand(QString("setboard %1").arg(pos->fen(halfmove, fullmove)));
178 else {
179 // this is pretty meaningless for generic variants
180 if (pos->turn() != 0) {
181 sendCommand("new");
182 sendCommand("a2a3");
185 sendCommand("edit");
186 sendCommand("#");
187 Point size = pos->size();
188 for (int i = 0; i < size.x; i++) {
189 for (int j = 0; j < size.y; j++) {
190 Point p(i, j);
191 AbstractPiece::Ptr piece = pos->get(p);
192 if (piece) sendCommand(QString("%1%2")
193 .arg(piece->type())
194 .arg(p.toString(8)));
197 sendCommand(".");
199 #endif