My Project
usi.cc
Go to the documentation of this file.
1/* usi.cc
2 */
3#include "osl/usi.h"
4#include <iostream>
5#include <sstream>
6#include <cctype>
7
8const std::string osl::psn::
9show(Square pos)
10{
11 const int x = pos.x();
12 const int y = pos.y();
13 std::string result = "XX";
14 result[0] = x + '0';
15 result[1] = y + 'a' - 1;
16 return result;
17}
18
20show(Ptype ptype)
21{
22 switch (ptype)
23 {
24 case PAWN: return 'P';
25 case LANCE: return 'L';
26 case KNIGHT: return 'N';
27 case SILVER: return 'S';
28 case GOLD: return 'G';
29 case BISHOP: return 'B';
30 case ROOK: return 'R';
31 case KING: return 'K';
32 default:
33 assert("unsupported ptype" == 0);
34 return '!';
35 }
36}
37
38const std::string osl::psn::
39show(Move m)
40{
41 const Square from = m.from();
42 const Square to = m.to();
43 if (from.isPieceStand())
44 {
45 std::string result = "X*";
46 result[0] = show(m.ptype());
47 result += show(to);
48 return result;
49 }
50 std::string result = show(from);
51 result += show(to);
52 if (m.promoteMask())
53 result += '+';
54 return result;
55}
56
57const std::string osl::psn::
58showXP(Move m)
59{
60 if (m.isInvalid())
61 return "resign";
62 if (m.isPass())
63 return "pass";
64 const Square from = m.from();
65 const Square to = m.to();
66 if (from.isPieceStand())
67 {
68 std::string result = "X*";
69 result[0] = show(m.ptype());
70 result += show(to);
71 return result;
72 }
73 std::string result = show(from);
74 if (m.capturePtype() != PTYPE_EMPTY)
75 result += 'x';
76 result += show(to);
77 if (m.isPromotion())
78 result += '+';
79 else if (canPromote(m.ptype())
80 && (from.canPromote(m.player()) || to.canPromote(m.player())))
81 result += '=';
82 return result;
83}
84
85
87strToMove(const std::string& str, const SimpleState& s)
88{
89 if (str.size() < 4)
90 throw ParseError("Invalid move string: " + str);
91
92 const Square to = strToPos(str.substr(2,2));
93 if (str[1] == '*')
94 {
95 const Ptype ptype = charToPtype(str[0]);
96 return Move(to, ptype, s.turn());
97 }
98
99 const Square from = strToPos(str.substr(0,2));
100 const Ptype ptype = s.pieceOnBoard(from).ptype();
101 const Ptype captured = s.pieceOnBoard(to).ptype();
102 if (! isPiece(ptype))
103 throw ParseError("No piece on square: " + str);
104 bool promotion = false;
105 if (str.size() > 4)
106 {
107 assert(str[4] == '+');
108 promotion = true;
109 }
110 return Move(from, to, (promotion ? promote(ptype) : ptype),
111 captured, promotion, s.turn());
112}
113
115strToPos(const std::string& str)
116{
117 assert(str.size() == 2);
118 const int x = str[0] - '0';
119 const int y = str[1] - 'a' + 1;
120 if (x <= 0 || x > 9 || y <= 0 || y > 9)
121 throw ParseError("Invalid square character: " + str);
122 return Square(x, y);
123}
124
126charToPtype(char c)
127{
128 switch (c)
129 {
130 case 'P': return PAWN;
131 case 'L': return LANCE;
132 case 'N': return KNIGHT;
133 case 'S': return SILVER;
134 case 'G': return GOLD;
135 case 'B': return BISHOP;
136 case 'R': return ROOK;
137 case 'K': return KING;
138 default:
139 return PTYPE_EMPTY;
140 }
141}
142
143/* ------------------------------------------------------------------------- */
144
145const std::string osl::usi::
146show(Move m)
147{
148 if (m.isPass())
149 return "pass";
150 if (m == Move::DeclareWin())
151 return "win";
152 if (! m.isNormal())
153 return "resign";
154 return psn::show(m);
155}
156
157const std::string osl::usi::
158show(PtypeO ptypeo)
159{
160 if (! isPiece(ptypeo))
161 return "";
162
163 char c = psn::show(unpromote(getPtype(ptypeo)));
164 if (getOwner(ptypeo) == WHITE)
165 c = tolower(c);
166 std::string ret(1,c);
167 if (isPromoted(ptypeo))
168 ret = "+" + ret;
169 return ret;
170}
171
172const std::string osl::usi::
173show(Piece p)
174{
175 return show(p.ptypeO());
176}
177
178const std::string osl::usi::
179show(const NumEffectState& state)
180{
181 std::ostringstream ret;
182 if (state == SimpleState(HIRATE)) {
183 ret << "startpos";
184 return ret.str();
185 }
186 ret << "sfen ";
187 for (int y=1; y<=9; ++y) {
188 int empty_count = 0;
189 for (int x=9; x>=1; --x) {
190 const Piece p = state.pieceOnBoard(Square(x,y));
191 if (p.isEmpty()) {
192 ++empty_count;
193 continue;
194 }
195 if (empty_count) {
196 ret << empty_count;
197 empty_count = 0;
198 }
199 ret << show(p);
200 }
201 if (empty_count)
202 ret << empty_count;
203 if (y < 9) ret << "/";
204 }
205 ret << " " << "bw"[state.turn() == WHITE] << " ";
206 bool has_any = false;
207 for (int z=0; z<2; ++z) {
208 const Player player = indexToPlayer(z);
209 for (Ptype ptype: PieceStand::order) {
210 const int count = state.countPiecesOnStand(player, ptype);
211 if (count == 0)
212 continue;
213 if (count > 1)
214 ret << count;
215 ret << show(newPtypeO(player, ptype));
216 has_any = true;
217 }
218 }
219 if (! has_any)
220 ret << "-";
221 ret << " 1";
222 return ret.str();
223}
224
226strToMove(const std::string& str, const NumEffectState& s)
227{
228 if (str == "win")
229 return Move::DeclareWin();
230 if (str == "pass")
231 return Move::PASS(s.turn());
232 if (str == "resign")
233 return Move::INVALID();
234 try {
235 return psn::strToMove(str, s);
236 }
237 catch (std::exception& e) {
238 throw ParseError("usi::strToMove failed for " + str + " by "+ e.what());
239 }
240 catch (...) {
241 throw ParseError("usi::strToMove failed for " + str);
242 }
243}
244
246charToPtypeO(char c)
247{
248 const Ptype ptype = psn::charToPtype(toupper(c));
249 if (ptype == PTYPE_EMPTY)
250 throw ParseError("Invalid piece character: " + std::string(1,c));
251 const Player pl = isupper(c) ? BLACK : WHITE;
252 return newPtypeO(pl, ptype);
253}
254
255void osl::usi::parseBoard(const std::string& word, NumEffectState& out)
256{
257 if (word.empty())
258 throw ParseError(word);
259
260 SimpleState state;
261 state.init();
262 int x=9, y=1;
263 for (size_t i=0; i<word.size(); ++i) {
264 const char c = word[i];
265 if (isalpha(c)) {
266 const PtypeO ptypeo = charToPtypeO(c);
267 state.setPiece(getOwner(ptypeo), Square(x,y), getPtype(ptypeo));
268 --x;
269 } else if (c == '+') {
270 if ( (i+1) >= word.size() )
271 throw ParseError(word);
272 const char next = word[i+1];
273 if (!isalpha(next))
274 throw ParseError(word);
275 const PtypeO ptypeo = charToPtypeO(next);
276 if (!canPromote(ptypeo))
277 throw ParseError(word);
278 const PtypeO promoted = promote(ptypeo);
279 state.setPiece(getOwner(promoted), Square(x,y), getPtype(promoted));
280 --x;
281 ++i;
282 } else if (c == '/') {
283 if (x != 0)
284 throw ParseError(word);
285 x = 9;
286 ++y;
287 } else if (isdigit(c)) {
288 const int n = c - '0';
289 if (n == 0)
290 throw ParseError(word);
291 x -= n;
292 } else {
293 throw ParseError("usi: unknown input " + std::string(1,c));
294 }
295 if (x < 0 || x > 9 || y < 0 || y > 9)
296 throw ParseError(word);
297 }
298 out = NumEffectState(state);
299}
300
301void osl::usi::parse(const std::string& line, NumEffectState& state)
302{
303 NumEffectState board;
304 std::vector<Move> moves;
305 parse(line, board, moves);
306 state.copyFrom(board);
307 for (Move move: moves) {
308 state.makeMove(move);
309 }
310}
311
313 NumEffectState state;
314 parse(line,state);
315 return state;
316}
317
318void osl::usi::parse(const std::string& line, NumEffectState& state, std::vector<Move>& moves)
319{
320 moves.clear();
321 std::istringstream is(line);
322 std::string word;
323 is >> word;
324 if (word == "position")
325 is >> word;
326 if (word == "startpos")
327 state.init(HIRATE);
328 else {
329 if (word != "sfen")
330 throw ParseError("sfen not found "+word);
331 is >> word;
332 parseBoard(word, state);
333 is >> word;
334 if (word != "b" && word != "w")
335 throw ParseError(" turn error "+word);
336 state.setTurn((word == "b") ? BLACK : WHITE);
337 is >> word;
338 if (word != "-") {
339 int prefix = 0;
340 for (char c: word) {
341 if (isalpha(c)) {
342 PtypeO ptypeo = charToPtypeO(c);
343 for (int j=0; j<std::max(1, prefix); ++j)
344 state.setPiece(getOwner(ptypeo), Square::STAND(), getPtype(ptypeo));
345 prefix = 0;
346 }
347 else {
348 if (!isdigit(c))
349 throw ParseError(word);
350 prefix = (c - '0') + prefix*10;
351 if (prefix == 0)
352 throw ParseError(word);
353 }
354 }
355 }
356 state.initPawnMask();
357 int move_number; // will not be used
358 if (! (is >> move_number))
359 return;
360 assert(is);
361 }
362 if (! (is >> word))
363 return;
364 if (word != "moves")
365 throw ParseError("moves not found "+word);
366 NumEffectState state_copy(state);
367 while (is >> word) {
368 Move m = strToMove(word, state_copy);
369 moves.push_back(m);
370 if (! m.isNormal() || ! state_copy.isValidMove(m))
371 throw ParseError("invalid move "+word);
372 state_copy.makeMove(m);
373 }
374}
375
376
377/* ------------------------------------------------------------------------- */
378// ;;; Local Variables:
379// ;;; mode:c++
380// ;;; c-basic-offset:2
381// ;;; End:
圧縮していない moveの表現 .
Definition: basic_type.h:1052
bool isInvalid() const
state に apply 可能でない場合にtrue
Definition: basic_type.h:1202
bool isPromotion() const
Definition: basic_type.h:1147
Ptype ptype() const
Definition: basic_type.h:1155
Player player() const
Definition: basic_type.h:1195
bool isPass() const
Definition: basic_type.h:1092
Ptype capturePtype() const
Definition: basic_type.h:1180
bool isNormal() const
INVALID でも PASS でもない.
Definition: basic_type.h:1088
int promoteMask() const
pieceに使うためのmaskなので
Definition: basic_type.h:1143
const Square to() const
Definition: basic_type.h:1132
const Square from() const
Definition: basic_type.h:1125
利きを持つ局面
void makeMove(Move move)
void copyFrom(const NumEffectState &src)
主要部分を高速にコピーする.
PtypeO ptypeO() const
Definition: basic_type.h:824
Ptype ptype() const
Definition: basic_type.h:821
bool isEmpty() const
Definition: basic_type.h:913
const Piece pieceOnBoard(Square sq) const
Definition: simpleState.h:170
bool isValidMove(Move move, bool show_error=true) const
合法手かどうかを検査する. isValidMoveByRule, isAlmostValidMove をおこなう. 玉の素抜きや王手を防いでいるか, 千日手,打歩詰かどうかは検査しない.
Definition: simpleState.cc:435
void setTurn(Player player)
Definition: simpleState.h:217
void init()
盤面が空の状態に初期化
Definition: simpleState.cc:44
Player turn() const
Definition: simpleState.h:220
void setPiece(Player player, Square sq, Ptype ptype)
Definition: simpleState.cc:114
int countPiecesOnStand(Player pl, Ptype ptype) const
持駒の枚数を数える
Definition: simpleState.h:182
bool isPieceStand() const
Definition: basic_type.h:576
int y() const
将棋としてのY座標を返す.
Definition: basic_type.h:567
bool canPromote() const
Definition: basic_type.h:659
int x() const
将棋としてのX座標を返す.
Definition: basic_type.h:563
const Square strToPos(const std::string &s)
Definition: csa.cc:28
const std::string show(Move)
Definition: csa.cc:133
const Move strToMove(const std::string &s, const SimpleState &st)
Definition: csa.cc:48
int max(Player p, int v1, int v2)
Definition: evalTraits.h:84
const Square strToPos(const std::string &)
Definition: usi.cc:115
const std::string showXP(Move)
decorate capture by 'x', promote by '+', and unpromote by '='
Definition: usi.cc:58
const std::string show(Move)
Definition: usi.cc:39
Ptype charToPtype(char)
Definition: usi.cc:126
const Move strToMove(const std::string &, const SimpleState &)
Definition: usi.cc:87
const Move strToMove(const std::string &, const NumEffectState &)
Definition: usi.cc:226
NumEffectState makeState(const std::string &line)
Definition: usi.cc:312
PtypeO charToPtypeO(char)
Definition: usi.cc:246
void parse(const std::string &line, NumEffectState &)
[sfen <sfenstring> | startpos ] moves <move1> ... <movei>
Definition: usi.cc:301
void parseBoard(const std::string &board, NumEffectState &)
盤面を取得する.
Definition: usi.cc:255
const std::string show(Move)
Definition: usi.cc:146
Ptype
駒の種類を4ビットでコード化する
Definition: basic_type.h:84
@ ROOK
Definition: basic_type.h:100
@ BISHOP
Definition: basic_type.h:99
@ PAWN
Definition: basic_type.h:95
@ KING
Definition: basic_type.h:93
@ KNIGHT
Definition: basic_type.h:97
@ PTYPE_EMPTY
Definition: basic_type.h:85
@ SILVER
Definition: basic_type.h:98
@ GOLD
Definition: basic_type.h:94
@ LANCE
Definition: basic_type.h:96
Ptype getPtype(PtypeO ptypeO)
Definition: basic_type.h:217
constexpr Player indexToPlayer(int n)
Definition: basic_type.h:19
bool canPromote(Ptype ptype)
ptypeがpromote可能な型かどうかのチェック promote済みの場合はfalseを返す
Definition: basic_type.h:147
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に,promote前の型を返す. promoteしていない型の時はそのまま返す
Definition: basic_type.h:157
Player getOwner(PtypeO ptypeO)
Definition: basic_type.h:256
bool isPromoted(Ptype ptype)
ptypeがpromote後の型かどうかのチェック
Definition: basic_type.h:137
Player
Definition: basic_type.h:8
@ WHITE
Definition: basic_type.h:10
@ BLACK
Definition: basic_type.h:9
constexpr bool isPiece(Ptype ptype)
ptypeが空白やEDGEでないかのチェック
Definition: basic_type.h:120
@ HIRATE
Definition: simpleState.h:21
PtypeO
Player + Ptype [-15, 15] PtypeO の O は Owner の O.
Definition: basic_type.h:199
PtypeO newPtypeO(Player player, Ptype ptype)
Definition: basic_type.h:211
Ptype promote(Ptype ptype)
promote可能なptypeに対して,promote後の型を返す promote不可のptypeを与えてはいけない.
Definition: basic_type.h:173
PtypeO captured(PtypeO ptypeO)
unpromoteすると共に,ownerを反転する.
Definition: basic_type.h:264