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);