Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
99 pmbaty 1
/*
2
    Texel - A UCI chess engine.
3
    Copyright (C) 2012  Peter Ă–sterlund, peterosterlund2@gmail.com
4
 
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 3 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License
16
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18
 
19
/*
20
 * uciprotocol.cpp
21
 *
22
 *  Created on: Mar 4, 2012
23
 *      Author: petero
24
 */
25
 
26
#include "uciprotocol.hpp"
27
#include "searchparams.hpp"
28
#include "computerPlayer.hpp"
29
#include "textio.hpp"
30
 
31
#include <iostream>
32
 
33
 
34
void
35
UCIProtocol::main(bool autoStart) {
36
    UCIProtocol uciProt;
37
    uciProt.mainLoop(std::cin, std::cout, autoStart);
38
}
39
 
40
UCIProtocol::UCIProtocol()
41
    : pos(TextIO::readFEN(TextIO::startPosFEN)),
42
      quit(false)
43
{
44
}
45
 
46
void
47
UCIProtocol::mainLoop(std::istream& is, std::ostream& os, bool autoStart) {
48
    if (autoStart)
49
        handleCommand("uci", os);
50
    std::string line;
51
    while (true) {
52
        getline(is, line);
53
        if (!is.good()) {
54
            if (engine)
55
                engine->stopSearch();
56
            break;
57
        }
58
        handleCommand(line, os);
59
        if (quit)
60
            break;
61
    }
62
}
63
 
64
void
65
UCIProtocol::handleCommand(const std::string& cmdLine, std::ostream& os) {
66
    std::vector<std::string> tokens;
67
    tokenize(cmdLine, tokens);
68
    const int nTok = (int)tokens.size();
69
    if (nTok == 0)
70
        return;
71
    try {
72
        std::string cmd = tokens[0];
73
        if (cmd == "uci") {
74
            os << "id name " << ComputerPlayer::engineName << std::endl;
75
            os << "id author Peter Osterlund" << std::endl;
76
            EngineControl::printOptions(os);
77
            os << "uciok" << std::endl;
78
        } else if (cmd == "isready") {
79
            initEngine(os);
80
            os << "readyok" << std::endl;
81
        } else if (cmd == "setoption") {
82
            initEngine(os);
83
            std::string optionName;
84
            std::string optionValue;
85
            if (nTok < 2)
86
                return;
87
            if (tokens[1] == "name") {
88
                int idx = 2;
89
                while ((idx < nTok) && (tokens[idx] != "value")) {
90
                    optionName += toLowerCase(tokens[idx++]);
91
                    optionName += ' ';
92
                }
93
                if ((idx < nTok) && (tokens[idx++] == "value")) {
94
                    while ((idx < nTok)) {
95
                        optionValue += toLowerCase(tokens[idx++]);
96
                        optionValue += ' ';
97
                    }
98
                }
99
                engine->setOption(trim(optionName), trim(optionValue), true);
100
            }
101
        } else if (cmd == "ucinewgame") {
102
            if (engine)
103
                engine->newGame();
104
        } else if (cmd ==  "position") {
105
            std::string fen;
106
            int idx = 1;
107
            if (nTok < 2)
108
                return;
109
            if (tokens[idx] == "startpos") {
110
                idx++;
111
                fen = TextIO::startPosFEN;
112
            } else if (tokens[idx] == "fen") {
113
                idx++;
114
                std::string sb;
115
                while ((idx < nTok) && (tokens[idx] != "moves")) {
116
                    sb += tokens[idx++];
117
                    sb += ' ';
118
                }
119
                fen = trim(sb);
120
            }
121
            if (fen.length() > 0) {
122
                pos = TextIO::readFEN(fen);
123
                moves.clear();
124
                if ((idx < nTok) && (tokens[idx++] == "moves")) {
125
                    for (int i = idx; i < nTok; i++) {
126
                        Move m = TextIO::uciStringToMove(tokens[i]);
127
                        if (m.isEmpty())
128
                            break;
129
                        moves.push_back(m);
130
                    }
131
                }
132
            }
133
        } else if (cmd == "go") {
134
            initEngine(os);
135
            int idx = 1;
136
            SearchParams sPar;
137
            bool ponder = false;
138
            while (idx < nTok) {
139
                std::string subCmd = tokens[idx++];
140
                if (subCmd == "searchmoves") {
141
                    while (idx < nTok) {
142
                        Move m = TextIO::uciStringToMove(tokens[idx]);
143
                        if (m.isEmpty())
144
                            break;
145
                        sPar.searchMoves.push_back(m);
146
                        idx++;
147
                    }
148
                } else if (subCmd == "ponder") {
149
                    ponder = true;
150
                } else if (subCmd == "wtime") {
151
                    if (idx < nTok)
152
                        str2Num(tokens[idx++], sPar.wTime);
153
                } else if (subCmd == "btime") {
154
                    if (idx < nTok)
155
                        str2Num(tokens[idx++], sPar.bTime);
156
                } else if (subCmd == "winc") {
157
                    if (idx < nTok)
158
                        str2Num(tokens[idx++], sPar.wInc);
159
                } else if (subCmd == "binc") {
160
                    if (idx < nTok)
161
                        str2Num(tokens[idx++], sPar.bInc);
162
                } else if (subCmd == "movestogo") {
163
                    if (idx < nTok)
164
                        str2Num(tokens[idx++], sPar.movesToGo);
165
                } else if (subCmd == "depth") {
166
                    if (idx < nTok)
167
                        str2Num(tokens[idx++], sPar.depth);
168
                } else if (subCmd == "nodes") {
169
                    if (idx < nTok)
170
                        str2Num(tokens[idx++], sPar.nodes);
171
                } else if (subCmd == "mate") {
172
                    if (idx < nTok)
173
                        str2Num(tokens[idx++], sPar.mate);
174
                } else if (subCmd == "movetime") {
175
                    if (idx < nTok)
176
                        str2Num(tokens[idx++], sPar.moveTime);
177
                } else if (subCmd == "infinite") {
178
                    sPar.infinite = true;
179
                }
180
            }
181
            if (ponder) {
182
                engine->startPonder(pos, moves, sPar);
183
            } else {
184
                engine->startSearch(pos, moves, sPar);
185
            }
186
        } else if (cmd == "stop") {
187
            if (engine)
188
                engine->stopSearch();
189
        } else if (cmd == "ponderhit") {
190
            engine->ponderHit();
191
        } else if (cmd == "quit") {
192
            if (engine)
193
                engine->stopSearch();
194
            quit = true;
195
        }
196
    } catch (const ChessParseError&) {
197
    }
198
}
199
 
200
void
201
UCIProtocol::initEngine(std::ostream& os) {
202
    if (!engine)
203
        engine = std::make_shared<EngineControl>(os);
204
}
205
 
206
/** Convert a string to tokens by splitting at whitespace characters. */
207
void
208
UCIProtocol::tokenize(const std::string& cmdLine, std::vector<std::string>& tokens) {
209
    tokens.clear();
210
    std::string tmp = trim(cmdLine);
211
    int start = 0;
212
    bool inWord = true;
213
    for (int i = 0; i < (int)tmp.size(); i++) {
214
        if (inWord) {
215
            if (isspace(tmp[i])) {
216
                tokens.push_back(tmp.substr(start, i - start));
217
                inWord = false;
218
            }
219
        } else {
220
            if (!isspace(tmp[i])) {
221
                start = i;
222
                inWord = true;
223
            }
224
        }
225
    }
226
    if (inWord)
227
        tokens.push_back(tmp.substr(start, tmp.size() - start));
228
}