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 
8 const std::string osl::psn::
9 show(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 
20 show(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 
38 const std::string osl::psn::
39 show(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 
57 const std::string osl::psn::
58 showXP(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 
87 strToMove(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 
115 strToPos(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 
126 charToPtype(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 
145 const std::string osl::usi::
146 show(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 
157 const std::string osl::usi::
158 show(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 
172 const std::string osl::usi::
173 show(Piece p)
174 {
175  return show(p.ptypeO());
176 }
177 
178 const std::string osl::usi::
179 show(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 
226 strToMove(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 
246 charToPtypeO(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 
255 void 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 
301 void 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 
312 osl::NumEffectState osl::usi::makeState(const std::string& line){
313  NumEffectState state;
314  parse(line,state);
315  return state;
316 }
317 
318 void 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:
osl::Square
Definition: basic_type.h:532
osl::NumEffectState::makeMove
void makeMove(Move move)
Definition: numEffectState.cc:201
osl::Move::isInvalid
bool isInvalid() const
state に apply 可能でない場合にtrue
Definition: basic_type.h:1202
osl::WHITE
@ WHITE
Definition: basic_type.h:10
osl::NumEffectState::copyFrom
void copyFrom(const NumEffectState &src)
主要部分を高速にコピーする.
Definition: numEffectState.cc:932
osl::csa::strToPos
const Square strToPos(const std::string &s)
Definition: csa.cc:28
osl::promote
Ptype promote(Ptype ptype)
promote可能なptypeに対して,promote後の型を返す promote不可のptypeを与えてはいけない.
Definition: basic_type.h:173
osl::usi::parseBoard
void parseBoard(const std::string &board, NumEffectState &)
盤面を取得する.
Definition: usi.cc:255
osl::getPtype
Ptype getPtype(PtypeO ptypeO)
Definition: basic_type.h:217
osl::Move
圧縮していない moveの表現 .
Definition: basic_type.h:1052
osl::Piece::ptypeO
PtypeO ptypeO() const
Definition: basic_type.h:824
osl::SimpleState
Definition: simpleState.h:35
osl::SimpleState::setPiece
void setPiece(Player player, Square sq, Ptype ptype)
Definition: simpleState.cc:114
osl::newPtypeO
PtypeO newPtypeO(Player player, Ptype ptype)
Definition: basic_type.h:211
osl::getOwner
Player getOwner(PtypeO ptypeO)
Definition: basic_type.h:256
osl::psn::show
const std::string show(Move)
Definition: usi.cc:39
osl::SimpleState::setTurn
void setTurn(Player player)
Definition: simpleState.h:217
osl::Ptype
Ptype
駒の種類を4ビットでコード化する
Definition: basic_type.h:84
osl::csa::show
const std::string show(Move)
Definition: csa.cc:133
osl::LANCE
@ LANCE
Definition: basic_type.h:96
osl::SimpleState::initPawnMask
void initPawnMask()
Definition: simpleState.cc:20
osl::Move::promoteMask
int promoteMask() const
pieceに使うためのmaskなので
Definition: basic_type.h:1143
osl::Piece
駒.
Definition: basic_type.h:788
osl::GOLD
@ GOLD
Definition: basic_type.h:94
osl::eval::max
int max(Player p, int v1, int v2)
Definition: evalTraits.h:84
osl::SimpleState::pieceOnBoard
const Piece pieceOnBoard(Square sq) const
Definition: simpleState.h:170
osl::Square::isPieceStand
bool isPieceStand() const
Definition: basic_type.h:576
osl::usi::show
const std::string show(Move)
Definition: usi.cc:146
osl::KING
@ KING
Definition: basic_type.h:93
osl::usi::ParseError
Definition: usi.h:24
osl::usi::makeState
NumEffectState makeState(const std::string &line)
Definition: usi.cc:312
osl::BISHOP
@ BISHOP
Definition: basic_type.h:99
osl::Move::capturePtype
Ptype capturePtype() const
Definition: basic_type.h:1180
osl::usi::charToPtypeO
PtypeO charToPtypeO(char)
Definition: usi.cc:246
osl::PAWN
@ PAWN
Definition: basic_type.h:95
osl::indexToPlayer
constexpr Player indexToPlayer(int n)
Definition: basic_type.h:19
osl::usi::parse
void parse(const std::string &line, NumEffectState &)
[sfen <sfenstring> | startpos ] moves <move1> ...
Definition: usi.cc:301
osl::csa::strToMove
const Move strToMove(const std::string &s, const SimpleState &st)
Definition: csa.cc:48
osl::Move::isNormal
bool isNormal() const
INVALID でも PASS でもない.
Definition: basic_type.h:1088
osl::Move::from
const Square from() const
Definition: basic_type.h:1125
osl::Square::x
int x() const
将棋としてのX座標を返す.
Definition: basic_type.h:563
usi.h
osl::HIRATE
@ HIRATE
Definition: simpleState.h:21
osl::PtypeO
PtypeO
Player + Ptype [-15, 15] PtypeO の O は Owner の O.
Definition: basic_type.h:199
osl::captured
PtypeO captured(PtypeO ptypeO)
unpromoteすると共に,ownerを反転する.
Definition: basic_type.h:264
osl::NumEffectState
利きを持つ局面
Definition: numEffectState.h:34
osl::SimpleState::isValidMove
bool isValidMove(Move move, bool show_error=true) const
合法手かどうかを検査する. isValidMoveByRule, isAlmostValidMove をおこなう. 玉の素抜きや王手を防いでいるか, 千日手,打歩詰かどうかは検査しない.
Definition: simpleState.cc:435
osl::psn::strToPos
const Square strToPos(const std::string &)
Definition: usi.cc:115
osl::psn::strToMove
const Move strToMove(const std::string &, const SimpleState &)
Definition: usi.cc:87
osl::psn::ParseError
Definition: usi.h:52
osl::ROOK
@ ROOK
Definition: basic_type.h:100
osl::Square::canPromote
bool canPromote() const
Definition: basic_type.h:659
osl::isPiece
constexpr bool isPiece(Ptype ptype)
ptypeが空白やEDGEでないかのチェック
Definition: basic_type.h:120
osl::Square::y
int y() const
将棋としてのY座標を返す.
Definition: basic_type.h:567
osl::isPromoted
bool isPromoted(Ptype ptype)
ptypeがpromote後の型かどうかのチェック
Definition: basic_type.h:137
osl::Piece::ptype
Ptype ptype() const
Definition: basic_type.h:821
osl::usi::strToMove
const Move strToMove(const std::string &, const NumEffectState &)
Definition: usi.cc:226
osl::Piece::isEmpty
bool isEmpty() const
Definition: basic_type.h:913
osl::Move::isPass
bool isPass() const
Definition: basic_type.h:1092
osl::Move::ptype
Ptype ptype() const
Definition: basic_type.h:1155
osl::BLACK
@ BLACK
Definition: basic_type.h:9
osl::canPromote
bool canPromote(Ptype ptype)
ptypeがpromote可能な型かどうかのチェック promote済みの場合はfalseを返す
Definition: basic_type.h:147
osl::SILVER
@ SILVER
Definition: basic_type.h:98
osl::psn::showXP
const std::string showXP(Move)
decorate capture by 'x', promote by '+', and unpromote by '='
Definition: usi.cc:58
osl::PTYPE_EMPTY
@ PTYPE_EMPTY
Definition: basic_type.h:85
osl::SimpleState::turn
Player turn() const
Definition: simpleState.h:220
osl::Player
Player
Definition: basic_type.h:8
osl::SimpleState::init
void init()
盤面が空の状態に初期化
Definition: simpleState.cc:44
osl::Move::to
const Square to() const
Definition: basic_type.h:1132
osl::Move::isPromotion
bool isPromotion() const
Definition: basic_type.h:1147
osl::SimpleState::countPiecesOnStand
int countPiecesOnStand(Player pl, Ptype ptype) const
持駒の枚数を数える
Definition: simpleState.h:182
osl::Move::player
Player player() const
Definition: basic_type.h:1195
osl::unpromote
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に,promote前の型を返す. promoteしていない型の時はそのまま返す
Definition: basic_type.h:157
osl::KNIGHT
@ KNIGHT
Definition: basic_type.h:97
osl::psn::charToPtype
Ptype charToPtype(char)
Definition: usi.cc:126