9 #include <boost/algorithm/string/split.hpp>
10 #include <boost/algorithm/string/replace.hpp>
11 #include <boost/algorithm/string/classification.hpp>
12 #include <boost/date_time/gregorian/gregorian.hpp>
13 #include <boost/foreach.hpp>
26 std::string s, CArray<bool,9>& board_parsed)
29 static const CArray<std::string,11> n_str = {{
30 "",
K_K1,
K_K2,
K_K3,
K_K4,
K_K5,
K_K6,
K_K7,
K_K8,
K_K9,
K_K10
32 Record *record=rv->getRecord();
33 SimpleState* state=rv->getState();
36 if (s.size() < 1+3*9+1+2)
37 throw KakinokiIOError(
"board too short in kakinokiParseLine "+s);
38 const int y =
std::find(n_str.begin(), n_str.end(), s.substr(s.size()-2))
40 if (! (1 <= y && y <= 9))
41 throw KakinokiIOError(
"unknown y in kakinokiParseLine "+s);
42 board_parsed[y-1] =
true;
43 for (
unsigned int x=9,i=1;i<s.length()&&x>0;i+=3,x--) {
47 state->setPiece(pp.first,
Square(x,y), pp.second);
50 if (s.find(
K_TESUU "--") == 0) {
52 if (
std::find(board_parsed.begin(), board_parsed.end(),
true)
53 == board_parsed.end()) {
55 board_parsed.fill(
true);
57 if (*std::min_element(board_parsed.begin(), board_parsed.end()) ==
false)
58 throw KakinokiIOError(
"incomplete position description in kakinokiParseLine");
59 state->initPawnMask();
69 if (s.find(
K_WHITE K_COLON) == 0) {
73 if (s.find(
K_KISEN K_COLON) == 0)
79 boost::gregorian::date date =
86 std::string piece_str = s.substr(s.find(K_COLON)+2);
87 boost::algorithm::replace_all(piece_str,
K_SPACE,
" ");
88 std::vector<std::string> pieces;
89 boost::algorithm::split(pieces, piece_str,
90 boost::algorithm::is_any_of(
" "));
94 else throw KakinokiIOError(
"error in stand "+ s);
96 BOOST_FOREACH(
const std::string& e, pieces) {
97 if (e.empty())
continue;
98 if (e.size() < 2)
throw KakinokiIOError(
"error in stand "+ e);
102 n =
std::find(n_str.begin(),n_str.end(),e.substr(2,2))
105 n = n * ((e.substr(2,2) ==
K_K10) ? 1 : 10)
106 + (
std::find(n_str.begin(),n_str.end(),e.substr(4,2))
108 for (
int i=0; i<n; ++i)
124 if (rv->getLastMove() == 0)
137 size_t p = s.find(
'(');
139 s.replace(p, 1, 1,
' ');
142 s.replace(p, 1, 1,
' ');
145 if (rv->getLastMove())
146 last_move = rv->getLastMove()->getMove();
149 if (! state->isValidMove(m)) {
150 std::ostringstream ss;
152 std::cerr << ss.str();
153 throw KakinokiIOError(ss.str());
155 rv->addMoveAndAdvance(m);
164 static const KanjiMove& Kanji_Move = KanjiMove::instance();
165 if (s.size() != 3 || (s[0] !=
'v' && s[0] !=
' '))
169 return std::make_pair(pl, ptype);
175 static const KanjiMove& Kanji_Move = KanjiMove::instance();
176 std::istringstream is(s);
177 int move_number, from_number;
178 std::string move_string;
179 is >> move_number >> move_string;
182 if (move_string.substr(0,2) ==
K_ONAZI)
185 to = Kanji_Move.
toSquare(move_string.substr(0,4));
191 if (move_string.substr(cur,2) ==
K_NARU)
193 assert(move_string.size() >= cur+4);
194 ptype = Kanji_Move.
toPtype(move_string.substr(cur,4));
199 ptype = Kanji_Move.
toPtype(move_string.substr(cur,2));
202 if (move_string.size() >= cur+2 && move_string.substr(cur,2)
207 if (! (is >> from_number))
209 from =
Square(from_number / 10, from_number % 10);
212 bool is_promote =
false;
213 if (move_string.size() >= cur+2 && move_string.substr(cur,2) ==
K_NARU)
217 return Move(to, ptype, state.turn());
219 return Move(from, to, is_promote ?
promote(ptype) : ptype,
220 captured, is_promote, state.turn());
230 std::cerr <<
"InputStream::InputStream cannot read \n";
241 std::cerr <<
"InputStream::InputStream cannot read \n";
254 rv->setState(&state);
257 CArray<bool, 9> board_parsed = {{
false }};
258 while (std::getline(is, line))
262 && (line[line.size()-1] == 13))
263 line.erase(line.size()-1);
264 if (line.length()==0)
271 if (! line.empty() && line[0] ==
'#'
272 && line.find(
"separator") != line.npos)
277 assert(state.isConsistent());
283 std::ifstream ifs(filename.c_str());
286 const std::string msg =
"KakinokiFile::KakinokiFile file cannot read ";
287 std::cerr << msg << filename <<
"\n";
308 return NumEffectState(rec.getInitialState());
314 std::ifstream is(filename.c_str());
316 if (! is || ! getline(is, line))
319 return line.find(
"Kifu for Windows") != line.npos
320 || line.find(
"KIFU") != line.npos
322 || (line.find(
"#") == 0 && line.find(
K_KIFU) != line.npos);