My Project
csaRecord.cc
Go to the documentation of this file.
2#include "osl/simpleState.h"
3#include "osl/oslConfig.h"
4#include "osl/usi.h"
5#include <boost/algorithm/string/classification.hpp>
6#include <boost/algorithm/string/split.hpp>
7#include <boost/algorithm/string/trim.hpp>
8#include <iostream>
9#include <fstream>
10#include <stdexcept>
11#include <cassert>
12#include <string>
13#include <sstream>
14
15/* ------------------------------------------------------------------------- */
16
19 const std::string& line,
20 Move last_move)
21{
22 std::istringstream is(line);
23 SearchInfo info;
24 is >> info.value;
25
26 NumEffectState state(initial);
27 std::string s;
28 while (is >> s)
29 {
30 if (s == csa::show(last_move) ||
31 s == usi::show(last_move)) // effective only if s is the first move in a comment
32 continue;
33 last_move = Move::INVALID();
34 try
35 {
36 Move move;
37 if (s == "%PASS" || /* gekisashi */ s == "<PASS>" || s == "PASS") {
38 move = Move::PASS(state.turn());
39 } else if (s[0] == '+' || s[0] == '-') {
40 move = csa::strToMove(s, state);
41 } else {
42 move = usi::strToMove(s, state);
43 }
44 if (move.isPass()
45 || (move.isNormal() && state.isValidMove(move,false)))
46 {
47 state.makeMove(move);
48 if (! state.inCheck(alt(state.turn()))) {
49 info.moves.push_back(move);
50 continue;
51 }
52 // fall through
53 }
54 }
55 catch(CsaIOError& e)
56 {
57 // fall through
58 }
59 catch(usi::ParseError &e)
60 {
61 // fall through
62 }
63 std::cerr << "drop illegal move in comment " << s << std::endl;
64 break;
65 }
66 return info;
67}
68
70CsaFile::parseLine(SimpleState& state, Record& record, std::string s,
71 bool parse_move_comment)
72{
73 switch(s.at(0)){
74 case '\'': /* コメント行 */
75 if (s.substr(1,2) == "* ")
76 {
77 record.setMoveComment(s.substr(3));
78 }
79 else if (s.substr(1,2) == "**" && parse_move_comment)
80 {
81 record.setMoveInfo(makeInfo(state, s.substr(3), record.lastMove()));
82 }
83 return;
84 case '$': /* コメント行 */
85 if (s.find("$START_TIME:") == 0) {
86 const std::string YYMMDD = s.substr(12,10);
87#if 0
88 std::vector<std::string> e;
89 boost::algorithm::split(e, YYMMDD, boost::algorithm::is_any_of("/"));
90 if (e.size() < 3)
91 throw CsaIOError("csa date fail "+YYMMDD);
92 start_date = boost::gregorian::date(stoi(e[0]), stoi(e[1]), stoi(e[2]));
93 assert(!start_date.is_special());
94#endif
95 record.setDate(YYMMDD);
96 return;
97 }
98 Record::addWithNewLine(record.initial_comment, s.substr(1));
99 return;
100 case 'V': /* バージョン番号 */
101 record.version = s.substr(1);
102 return;
103 case 'N': /* 対局者名 */
104 switch(s.at(1)){
105 case '+':
106 case '-':
107 record.player[csa::charToPlayer(s.at(1))] = s.substr(2);
108 break;
109 default:
110 std::cerr << "Illegal csa line " << s << std::endl;
111 throw CsaIOError("illegal csa line "+s);
112 }
113 break;
114 case 'T':
115 {
116 record.setMoveTime(atoi(s.c_str()+1));
117 return;
118 }
119 case '%':
120 if (s.find("%TORYO") == 0 || s.find("%ILLEGAL_MOVE") == 0)
121 record.result = ((state.turn() == BLACK)
123 else if (s.find("%SENNICHITE") == 0)
125 else if (s.find("%KACHI") == 0)
126 record.result = ((state.turn() == BLACK)
128 else if (s.find("%JISHOGI") == 0 || s.find("%HIKIWAKE") == 0)
129 record.result = Record::JiShogi;
130 else if (s.find("%+ILLEGAL_ACTION") == 0)
131 record.result = Record::WhiteWin;
132 else if (s.find("%-ILLEGAL_ACTION") == 0)
133 record.result = Record::BlackWin;
134 return;
135 default:
136 throw CsaIOError("unknown character in csaParseLine "+s);
137 }
138}
139
141CsaFile::CsaFile(const std::string& filename)
142{
143 std::ifstream ifs(filename);
144 if (! ifs) {
145 const std::string msg = "CsaFile::CsaFile file cannot read ";
146 std::cerr << msg << filename << "\n";
147 throw CsaIOError(msg + filename);
148 }
149 read(ifs);
150}
151
153CsaFile::CsaFile(std::istream& is)
154{
155 read(is);
156}
157
162
164read(std::istream& is)
165{
166 SimpleState work;
167 work.init();
168 std::string line;
169 CArray<bool, 9> board_parsed = {{ false }};
170 while (std::getline(is, line))
171 {
172 // quick hack for \r
173 if ((! line.empty())
174 && (line[line.size()-1] == 13))
175 line.erase(line.size()-1);
176
177 std::vector<std::string> elements;
178 boost::algorithm::split(elements, line, boost::algorithm::is_any_of(","));
179 for (auto& e: elements) {
180 boost::algorithm::trim(e);
181 boost::algorithm::trim_left(e);
182 if (! CsaFileMinimal::parseLine(work, record.record, e, board_parsed))
183 parseLine(work, record, e, !OslConfig::inUnitTest());
184 }
185 }
186 if (*std::min_element(board_parsed.begin(), board_parsed.end()) == false)
187 throw CsaIOError("incomplete position description in csaParseLine");
188 assert(record.record.initial_state.isConsistent());
189}
190
191/* ------------------------------------------------------------------------- */
192// ;;; Local Variables:
193// ;;; mode:c++
194// ;;; c-basic-offset:2
195// ;;; End:
iterator end()
Definition container.h:65
iterator begin()
Definition container.h:64
圧縮していない moveの表現 .
static const Move PASS(Player P)
static const Move INVALID()
bool isPass() const
bool isNormal() const
INVALID でも PASS でもない.
利きを持つ局面
void makeMove(Move move)
bool inCheck(Player P) const
Pの玉が王手状態
bool isValidMove(Move move, bool show_error=true) const
合法手かどうかを検査する. isValidMoveByRule, isAlmostValidMove をおこなう. 玉の素抜きや王手を防いでいるか, 千日手,打歩詰かどうかは検査しない.
void init()
盤面が空の状態に初期化
Player turn() const
static bool parseLine(SimpleState &, RecordMinimal &, std::string element, CArray< bool, 9 > &)
Definition csa.cc:247
CsaFile(std::istream &is)
Definition csaRecord.cc:153
void read(std::istream &)
Definition csaRecord.cc:164
static void parseLine(SimpleState &, Record &, std::string element, bool parse_move_comment=true)
Definition csaRecord.cc:70
static SearchInfo makeInfo(const SimpleState &initial, const std::string &line, Move last_move)
Definition csaRecord.cc:18
const std::string show(Move)
Definition csa.cc:133
Player charToPlayer(char c)
Definition csa.cc:18
const Move strToMove(const std::string &s, const SimpleState &st)
Definition csa.cc:48
const Move strToMove(const std::string &, const NumEffectState &)
Definition usi.cc:226
const std::string show(Move)
Definition usi.cc:146
@ BLACK
Definition basic_type.h:9
constexpr Player alt(Player player)
Definition basic_type.h:13
static int inUnitTest()
Definition oslConfig.h:87
ResultType result
Definition record.h:30
std::string version
Definition record.h:28
static void addWithNewLine(std::string &a, const std::string &b)
Definition record.h:35
Move lastMove() const
Definition record.h:47
std::string initial_comment
Definition record.h:28
void setMoveInfo(const SearchInfo &)
Definition record.cc:26
void setMoveTime(int)
Definition record.cc:33
void setDate(const std::string &date_str)
Definition record.cc:39
void setMoveComment(const std::string &)
Definition record.cc:17
CArray< std::string, 2 > player
Definition record.h:29
std::vector< Move > moves
Definition searchInfo.h:17