usi.cc
Go to the documentation of this file.
/* usi.cc
*/
#include "osl/usi.h"
#include <iostream>
#include <sstream>
#include <cctype>
const std::string osl::psn::
show(Square pos)
{
const int x = pos.x();
const int y = pos.y();
std::string result = "XX";
result[0] = x + '0';
result[1] = y + 'a' - 1;
return result;
}
char osl::psn::
show(Ptype ptype)
{
switch (ptype)
{
case PAWN: return 'P';
case LANCE: return 'L';
case KNIGHT: return 'N';
case SILVER: return 'S';
case GOLD: return 'G';
case BISHOP: return 'B';
case ROOK: return 'R';
case KING: return 'K';
default:
assert("unsupported ptype" == 0);
return '!';
}
}
const std::string osl::psn::
show(Move m)
{
const Square from = m.from();
const Square to = m.to();
if (from.isPieceStand())
{
std::string result = "X*";
result[0] = show(m.ptype());
result += show(to);
return result;
}
std::string result = show(from);
result += show(to);
if (m.promoteMask())
result += '+';
return result;
}
const std::string osl::psn::
showXP(Move m)
{
if (m.isInvalid())
return "resign";
if (m.isPass())
return "pass";
const Square from = m.from();
const Square to = m.to();
if (from.isPieceStand())
{
std::string result = "X*";
result[0] = show(m.ptype());
result += show(to);
return result;
}
std::string result = show(from);
if (m.capturePtype() != PTYPE_EMPTY)
result += 'x';
result += show(to);
if (m.isPromotion())
result += '+';
else if (canPromote(m.ptype())
&& (from.canPromote(m.player()) || to.canPromote(m.player())))
result += '=';
return result;
}
const osl::Move osl::psn::
strToMove(const std::string& str, const SimpleState& s)
{
if (str.size() < 4)
throw ParseError("Invalid move string: " + str);
const Square to = strToPos(str.substr(2,2));
if (str[1] == '*')
{
const Ptype ptype = charToPtype(str[0]);
return Move(to, ptype, s.turn());
}
const Square from = strToPos(str.substr(0,2));
const Ptype ptype = s.pieceOnBoard(from).ptype();
const Ptype captured = s.pieceOnBoard(to).ptype();
if (! isPiece(ptype))
throw ParseError("No piece on square: " + str);
bool promotion = false;
if (str.size() > 4)
{
assert(str[4] == '+');
promotion = true;
}
return Move(from, to, (promotion ? promote(ptype) : ptype),
captured, promotion, s.turn());
}
const osl::Square osl::psn::
strToPos(const std::string& str)
{
assert(str.size() == 2);
const int x = str[0] - '0';
const int y = str[1] - 'a' + 1;
if (x <= 0 || x > 9 || y <= 0 || y > 9)
throw ParseError("Invalid square character: " + str);
return Square(x, y);
}
osl::Ptype osl::psn::
charToPtype(char c)
{
switch (c)
{
case 'P': return PAWN;
case 'L': return LANCE;
case 'N': return KNIGHT;
case 'S': return SILVER;
case 'G': return GOLD;
case 'B': return BISHOP;
case 'R': return ROOK;
case 'K': return KING;
default:
return PTYPE_EMPTY;
}
}
/* ------------------------------------------------------------------------- */
const std::string osl::usi::
show(Move m)
{
if (m.isPass())
return "pass";
if (m == Move::DeclareWin())
return "win";
if (! m.isNormal())
return "resign";
return psn::show(m);
}
const std::string osl::usi::
show(PtypeO ptypeo)
{
if (! isPiece(ptypeo))
return "";
char c = psn::show(unpromote(getPtype(ptypeo)));
if (getOwner(ptypeo) == WHITE)
c = tolower(c);
std::string ret(1,c);
if (isPromoted(ptypeo))
ret = "+" + ret;
return ret;
}
const std::string osl::usi::
show(Piece p)
{
return show(p.ptypeO());
}
const std::string osl::usi::
show(const NumEffectState& state)
{
std::ostringstream ret;
if (state == SimpleState(HIRATE)) {
ret << "startpos";
return ret.str();
}
ret << "sfen ";
for (int y=1; y<=9; ++y) {
int empty_count = 0;
for (int x=9; x>=1; --x) {
const Piece p = state.pieceOnBoard(Square(x,y));
if (p.isEmpty()) {
++empty_count;
continue;
}
if (empty_count) {
ret << empty_count;
empty_count = 0;
}
ret << show(p);
}
if (empty_count)
ret << empty_count;
if (y < 9) ret << "/";
}
ret << " " << "bw"[state.turn() == WHITE] << " ";
bool has_any = false;
for (int z=0; z<2; ++z) {
const Player player = indexToPlayer(z);
for (Ptype ptype: PieceStand::order) {
const int count = state.countPiecesOnStand(player, ptype);
if (count == 0)
continue;
if (count > 1)
ret << count;
ret << show(newPtypeO(player, ptype));
has_any = true;
}
}
if (! has_any)
ret << "-";
ret << " 1";
return ret.str();
}
const osl::Move osl::usi::
strToMove(const std::string& str, const NumEffectState& s)
{
if (str == "win")
return Move::DeclareWin();
if (str == "pass")
return Move::PASS(s.turn());
if (str == "resign")
return Move::INVALID();
try {
return psn::strToMove(str, s);
}
catch (std::exception& e) {
throw ParseError("usi::strToMove failed for " + str + " by "+ e.what());
}
catch (...) {
throw ParseError("usi::strToMove failed for " + str);
}
}
osl::PtypeO osl::usi::
charToPtypeO(char c)
{
const Ptype ptype = psn::charToPtype(toupper(c));
if (ptype == PTYPE_EMPTY)
throw ParseError("Invalid piece character: " + std::string(1,c));
const Player pl = isupper(c) ? BLACK : WHITE;
return newPtypeO(pl, ptype);
}
void osl::usi::parseBoard(const std::string& word, NumEffectState& out)
{
if (word.empty())
throw ParseError(word);
SimpleState state;
state.init();
int x=9, y=1;
for (size_t i=0; i<word.size(); ++i) {
const char c = word[i];
if (isalpha(c)) {
const PtypeO ptypeo = charToPtypeO(c);
state.setPiece(getOwner(ptypeo), Square(x,y), getPtype(ptypeo));
--x;
} else if (c == '+') {
if ( (i+1) >= word.size() )
throw ParseError(word);
const char next = word[i+1];
if (!isalpha(next))
throw ParseError(word);
const PtypeO ptypeo = charToPtypeO(next);
if (!canPromote(ptypeo))
throw ParseError(word);
const PtypeO promoted = promote(ptypeo);
state.setPiece(getOwner(promoted), Square(x,y), getPtype(promoted));
--x;
++i;
} else if (c == '/') {
if (x != 0)
throw ParseError(word);
x = 9;
++y;
} else if (isdigit(c)) {
const int n = c - '0';
if (n == 0)
throw ParseError(word);
x -= n;
} else {
throw ParseError("usi: unknown input " + std::string(1,c));
}
if (x < 0 || x > 9 || y < 0 || y > 9)
throw ParseError(word);
}
out = NumEffectState(state);
}
void osl::usi::parse(const std::string& line, NumEffectState& state)
{
NumEffectState board;
std::vector<Move> moves;
parse(line, board, moves);
state.copyFrom(board);
for (Move move: moves) {
state.makeMove(move);
}
}
osl::NumEffectState osl::usi::makeState(const std::string& line){
NumEffectState state;
parse(line,state);
return state;
}
void osl::usi::parse(const std::string& line, NumEffectState& state, std::vector<Move>& moves)
{
moves.clear();
std::istringstream is(line);
std::string word;
is >> word;
if (word == "position")
is >> word;
if (word == "startpos")
state.init(HIRATE);
else {
if (word != "sfen")
throw ParseError("sfen not found "+word);
is >> word;
parseBoard(word, state);
is >> word;
if (word != "b" && word != "w")
throw ParseError(" turn error "+word);
state.setTurn((word == "b") ? BLACK : WHITE);
is >> word;
if (word != "-") {
int prefix = 0;
for (char c: word) {
if (isalpha(c)) {
PtypeO ptypeo = charToPtypeO(c);
for (int j=0; j<std::max(1, prefix); ++j)
state.setPiece(getOwner(ptypeo), Square::STAND(), getPtype(ptypeo));
prefix = 0;
}
else {
if (!isdigit(c))
throw ParseError(word);
prefix = (c - '0') + prefix*10;
if (prefix == 0)
throw ParseError(word);
}
}
}
state.initPawnMask();
int move_number; // will not be used
if (! (is >> move_number))
return;
assert(is);
}
if (! (is >> word))
return;
if (word != "moves")
throw ParseError("moves not found "+word);
NumEffectState state_copy(state);
while (is >> word) {
Move m = strToMove(word, state_copy);
moves.push_back(m);
if (! m.isNormal() || ! state_copy.isValidMove(m))
throw ParseError("invalid move "+word);
state_copy.makeMove(m);
}
}
/* ------------------------------------------------------------------------- */
// ;;; Local Variables:
// ;;; mode:c++
// ;;; c-basic-offset:2
// ;;; End:
osl::Move
圧縮していない moveの表現 .
Definition basic_type.h:1052
osl::Move::PASS
static const Move PASS(Player P)
Definition basic_type.h:1094
osl::Move::INVALID
static const Move INVALID()
Definition basic_type.h:1095
osl::Move::isInvalid
bool isInvalid() const
state に apply 可能でない場合にtrue
Definition basic_type.h:1202
osl::Move::isPromotion
bool isPromotion() const
Definition basic_type.h:1147
osl::Move::ptype
Ptype ptype() const
Definition basic_type.h:1155
osl::Move::player
Player player() const
Definition basic_type.h:1195
osl::Move::DeclareWin
static const Move DeclareWin()
Definition basic_type.h:1096
osl::Move::isPass
bool isPass() const
Definition basic_type.h:1092
osl::Move::capturePtype
Ptype capturePtype() const
Definition basic_type.h:1180
osl::Move::isNormal
bool isNormal() const
INVALID でも PASS でもない.
Definition basic_type.h:1088
osl::Move::promoteMask
int promoteMask() const
pieceに使うためのmaskなので
Definition basic_type.h:1143
osl::Move::to
const Square to() const
Definition basic_type.h:1132
osl::Move::from
const Square from() const
Definition basic_type.h:1125
osl::NumEffectState
利きを持つ局面
Definition numEffectState.h:34
osl::NumEffectState::makeMove
void makeMove(Move move)
Definition numEffectState.cc:201
osl::NumEffectState::copyFrom
void copyFrom(const NumEffectState &src)
主要部分を高速にコピーする.
Definition numEffectState.cc:932
osl::PieceStand::order
static const CArray< Ptype, 7 > order
持駒の表示で良く使われる順番.
Definition bits/pieceStand.h:41
osl::Piece
駒.
Definition basic_type.h:788
osl::Piece::ptypeO
PtypeO ptypeO() const
Definition basic_type.h:824
osl::Piece::ptype
Ptype ptype() const
Definition basic_type.h:821
osl::Piece::isEmpty
bool isEmpty() const
Definition basic_type.h:913
osl::SimpleState
Definition simpleState.h:35
osl::SimpleState::pieceOnBoard
const Piece pieceOnBoard(Square sq) const
Definition simpleState.h:170
osl::SimpleState::isValidMove
bool isValidMove(Move move, bool show_error=true) const
合法手かどうかを検査する． isValidMoveByRule, isAlmostValidMove をおこなう． 玉の素抜きや王手を防いでいるか， 千日手，打歩詰かどうかは検査しない．
Definition simpleState.cc:435
osl::SimpleState::setTurn
void setTurn(Player player)
Definition simpleState.h:217
osl::SimpleState::init
void init()
盤面が空の状態に初期化
Definition simpleState.cc:44
osl::SimpleState::turn
Player turn() const
Definition simpleState.h:220
osl::SimpleState::initPawnMask
void initPawnMask()
Definition simpleState.cc:20
osl::SimpleState::setPiece
void setPiece(Player player, Square sq, Ptype ptype)
Definition simpleState.cc:114
osl::SimpleState::countPiecesOnStand
int countPiecesOnStand(Player pl, Ptype ptype) const
持駒の枚数を数える
Definition simpleState.h:182
osl::Square
Definition basic_type.h:532
osl::Square::isPieceStand
bool isPieceStand() const
Definition basic_type.h:576
osl::Square::y
int y() const
将棋としてのY座標を返す.
Definition basic_type.h:567
osl::Square::canPromote
bool canPromote() const
Definition basic_type.h:659
osl::Square::STAND
static const Square STAND()
Definition basic_type.h:548
osl::Square::x
int x() const
将棋としてのX座標を返す.
Definition basic_type.h:563
osl::psn::ParseError
Definition usi.h:52
osl::usi::ParseError
Definition usi.h:24
osl::psn::strToPos
const Square strToPos(const std::string &)
Definition usi.cc:115
osl::psn::showXP
const std::string showXP(Move)
decorate capture by 'x', promote by '+', and unpromote by '='
Definition usi.cc:58
osl::psn::show
const std::string show(Move)
Definition usi.cc:39
osl::psn::charToPtype
Ptype charToPtype(char)
Definition usi.cc:126
osl::psn::strToMove
const Move strToMove(const std::string &, const SimpleState &)
Definition usi.cc:87
osl::usi::strToMove
const Move strToMove(const std::string &, const NumEffectState &)
Definition usi.cc:226
osl::usi::makeState
NumEffectState makeState(const std::string &line)
Definition usi.cc:312
osl::usi::charToPtypeO
PtypeO charToPtypeO(char)
Definition usi.cc:246
osl::usi::parse
void parse(const std::string &line, NumEffectState &)
[sfen <sfenstring> | startpos ] moves <move1> ... <movei>
Definition usi.cc:301
osl::usi::parseBoard
void parseBoard(const std::string &board, NumEffectState &)
盤面を取得する.
Definition usi.cc:255
osl::usi::show
const std::string show(Move)
Definition usi.cc:146
osl::Ptype
Ptype
駒の種類を4ビットでコード化する
Definition basic_type.h:84
osl::ROOK
@ ROOK
Definition basic_type.h:100
osl::BISHOP
@ BISHOP
Definition basic_type.h:99
osl::PAWN
@ PAWN
Definition basic_type.h:95
osl::KING
@ KING
Definition basic_type.h:93
osl::KNIGHT
@ KNIGHT
Definition basic_type.h:97
osl::PTYPE_EMPTY
@ PTYPE_EMPTY
Definition basic_type.h:85
osl::SILVER
@ SILVER
Definition basic_type.h:98
osl::GOLD
@ GOLD
Definition basic_type.h:94
osl::LANCE
@ LANCE
Definition basic_type.h:96
osl::getPtype
Ptype getPtype(PtypeO ptypeO)
Definition basic_type.h:217
osl::indexToPlayer
constexpr Player indexToPlayer(int n)
Definition basic_type.h:19
osl::canPromote
bool canPromote(Ptype ptype)
ptypeがpromote可能な型かどうかのチェック promote済みの場合はfalseを返す
Definition basic_type.h:147
osl::unpromote
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に，promote前の型を返す． promoteしていない型の時はそのまま返す
Definition basic_type.h:157
osl::getOwner
Player getOwner(PtypeO ptypeO)
Definition basic_type.h:256
osl::isPromoted
bool isPromoted(Ptype ptype)
ptypeがpromote後の型かどうかのチェック
Definition basic_type.h:137
osl::Player
Player
Definition basic_type.h:8
osl::WHITE
@ WHITE
Definition basic_type.h:10
osl::BLACK
@ BLACK
Definition basic_type.h:9
osl::isPiece
constexpr bool isPiece(Ptype ptype)
ptypeが空白やEDGEでないかのチェック
Definition basic_type.h:120
osl::HIRATE
@ HIRATE
Definition simpleState.h:21
osl::PtypeO
PtypeO
Player + Ptype [-15, 15] PtypeO の O は Owner の O.
Definition basic_type.h:199
osl::newPtypeO
PtypeO newPtypeO(Player player, Ptype ptype)
Definition basic_type.h:211
osl::promote
Ptype promote(Ptype ptype)
promote可能なptypeに対して，promote後の型を返す promote不可のptypeを与えてはいけない．
Definition basic_type.h:173
osl::captured
PtypeO captured(PtypeO ptypeO)
unpromoteすると共に，ownerを反転する．
Definition basic_type.h:264
usi.h