7 #include <boost/filesystem/convenience.hpp> 
    8 #include <boost/foreach.hpp> 
   16     assert(1<=pos && pos<=0x51);
 
   17     int y=((pos-1)/9)+1, x=((pos-1)%9)+1;
 
   22     return ((pos.
y() - 1) * 9 + 1) + pos.
x() - 1;
 
   28     if(1<=c1 && c1<=0x51){
 
   30       Piece fromPiece=state.pieceOnBoard(from);
 
   32         throw CsaIOError(
"Square error");
 
   34       assert(fromPiece.
owner()==state.turn() ||
 
   35              (std::cerr << c1 << 
"," << from << 
"," << fromPiece << std::endl,0)
 
   38       if(1<=c0 && c0<=0x51){
 
   41       else if(0x65<=c0 && c0<=0xb5){
 
   46         throw CsaIOError(
"c0 range error");
 
   48       Piece toPiece=state.pieceAt(to);
 
   50         throw CsaIOError(
"inconsintent move (to)");
 
   52       if(isPromote)ptype=
promote(ptype);
 
   56       move=
Move(from,to,ptype,captured,isPromote,state.turn());
 
   60       assert(1<=c0&&c0<=0x51);
 
   63       int piece_on_stand = c1;
 
   65       for(
size_t i=0;i<
sizeof(ptypes)/
sizeof(
Ptype);i++){
 
   66         int count=state.countPiecesOnStand(state.turn(),ptypes[i]);
 
   68           if(piece_on_stand>0x64){
 
   69             piece_on_stand-=
count;
 
   70             if(piece_on_stand<=0x64) ptype=ptypes[i];
 
   75              (std::cerr << state << to << 
" " << c1
 
   76               << 
" " << piece_on_stand << std::endl, 
false));
 
   77       move=
Move(to,ptype,state.turn());
 
   79     if (! state.isValidMove(move,
true)) {
 
   80       std::cerr << 
"warning: bad move in kisen\n" << state << move << 
"\n";
 
   83     assert(state.isValidMove(move,
true) ||
 
   84            (std::cerr << state << move << std::endl, 
false));
 
   90     :ifs(fileName.c_str()),initialState(
HIRATE), fileName(fileName) 
 
   93       throw CsaIOError(
"KisenFile not found");
 
   94     ifs.seekg(0,std::ios::end);
 
   95     assert((
ifs.tellg() % 512)==0);
 
  101     assert(index<
size());
 
  104     ifs.seekg(index*512,std::ios::beg);
 
  105     CArray<unsigned char, 512> cbuf;
 
  106     ifs.read(reinterpret_cast<char *>(&cbuf[0]),512);
 
  107     NumEffectState state;
 
  110     for(
size_t turnCount=0; 
 
  111         (turnCount*2 < cbuf.size())
 
  112           && cbuf[turnCount*2]!=0 && cbuf[turnCount*2+1]!=0;
 
  113         turnCount++, turn=
alt(turn)){
 
  114       if(turnCount==
KisenFile::maxMoves || cbuf[  turnCount *2 ] == 0 || cbuf[ turnCount * 2 + 1 ] == 0 ){ 
break; }
 
  115       int c0=cbuf[turnCount*2], c1=cbuf[turnCount*2+1];
 
  116       if (moves.empty() && c0 == 0xff && c1 == 0xff) 
 
  121       moves.push_back(move);
 
  122       state.makeMove(move);
 
  123       assert(state.isConsistent( 
true ) );
 
  130     namespace bf = boost::filesystem;
 
  131     const bf::path ipxfilename = bf::change_extension(bf::path(filename), 
".ipx");
 
  136     :ifs(fileName.c_str()), file_name(fileName) 
 
  139       throw CsaIOError(
"KisenIpxFile not found");
 
  140     ifs.seekg(0,std::ios::end);
 
  141     assert((
ifs.tellg() % 256)==0);
 
  146     assert(index<
size());
 
  148     ifs.seekg(index*256,std::ios::beg);
 
  149     CArray<unsigned char, 256> cbuf;
 
  150     ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
 
  152     if(pl==
WHITE)startIndex=14;
 
  155     strncpy(&buf[0],reinterpret_cast<char *>(&cbuf[startIndex]),14);
 
  160     assert(index<
size());
 
  162     ifs.seekg(index*256,std::ios::beg);
 
  163     CArray<unsigned char, 256> cbuf;
 
  164     ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
 
  166     if(pl==
WHITE)startIndex=0326;
 
  167     return cbuf[startIndex]+256*cbuf[startIndex+1];
 
  171     assert(index<
size());
 
  172     ifs.seekg(index*256,std::ios::beg);
 
  173     CArray<unsigned char, 256> cbuf;
 
  174     ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
 
  175     return cbuf[64+48+6];
 
  179     assert(index<
size());
 
  181     ifs.seekg(index*256,std::ios::beg);
 
  182     CArray<unsigned char, 256> cbuf;
 
  183     ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
 
  185     if(pl==
WHITE)startIndex+=8;
 
  188     strncpy(&buf[0],reinterpret_cast<const char*>(&cbuf[startIndex]),8);
 
  193     assert(index<
size());
 
  194     ifs.seekg(index*256,std::ios::beg);
 
  195     CArray<unsigned char, 256> cbuf;
 
  196     ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
 
  197     const int startIndex=84;
 
  198     const unsigned int year  = cbuf[startIndex] + 256*cbuf[startIndex+1];
 
  199     const unsigned int month = cbuf[startIndex+2];
 
  200     const unsigned int day   = cbuf[startIndex+3];
 
  202       const boost::gregorian::date d = boost::gregorian::date(year, month, day);
 
  204     } 
catch (std::out_of_range& e) {
 
  205       std::cerr << e.what() << 
": [" 
  206         << index << 
"] " << year << 
"-" << month << 
"-" << day << 
"\n"; 
 
  207       return boost::gregorian::date(boost::gregorian::not_a_date_time); 
 
  212     :ifs(fileName.c_str()),initialState(
HIRATE) 
 
  215       throw CsaIOError(
"KisenPlusFile not found");
 
  216     ifs.seekg(0,std::ios::end);
 
  217     assert((
ifs.tellg() % 2048)==0);
 
  230                                vector<Move>& 
moves, vector<int>& times)
 
  232     assert(index<
size());
 
  234     ifs.seekg(index*2048,std::ios::beg);
 
  235     CArray<unsigned char, 2048> cbuf;
 
  236     ifs.read(reinterpret_cast<char *>(&cbuf[0]),2048);
 
  237     NumEffectState state;
 
  239          i < 2048 && cbuf[i]!=0 && cbuf[i+1]!=0;
 
  243       int c1 = cbuf[i + 1];
 
  244       bool is_promote = 
false;
 
  253       Square to(c0 % 10, c0 / 10);
 
  264         Square from(c1 % 10, c1 / 10);
 
  265         Ptype type = state.pieceAt(from).ptype();
 
  268         move = 
Move(from, to,
 
  269                     type, state.pieceAt(to).ptype(),
 
  270                     is_promote, state.turn());
 
  272       moves.push_back(move);
 
  273       times.push_back(cbuf[i + 7] * 60 + cbuf[i + 6]);
 
  274       state.makeMove(move);
 
  275       assert(state.isConsistent( 
true ) );
 
  295   if (!(src == SimpleState(
HIRATE)))
 
  297     std::cerr << 
"Can not save non-HIRATE record" << std::endl;
 
  300   NumEffectState state;
 
  301   const int max_length = 
std::min(256, static_cast<int>(moves.size()));
 
  302   for (
int i = 0; i < max_length; ++i)
 
  304     const Move move = moves[i];
 
  307       int from = KisenUtils::convertSquare(move.
from());
 
  308       int to = KisenUtils::convertSquare(move.
to());
 
  313       os << static_cast<char>(to) << static_cast<char>(from);
 
  317       int to = KisenUtils::convertSquare(move.
to());
 
  321         if (ptype == move.
ptype())
 
  325         count += state.countPiecesOnStand(move.
player(), ptype);
 
  328       os << static_cast<char>(to) << static_cast<char>(count);
 
  330     state.makeMove(moves[i]);
 
  332   for (
int i = max_length; i < 256; ++i)
 
  351   for (
size_t i = 0; i < 
length; ++i)
 
  353     if (i < name.length())
 
  367   int high = rating / 256;
 
  368   int low = rating % 256;
 
  369   os << static_cast<char>(low) << static_cast<char>(high);
 
  375   const int high_year = year / 256;
 
  376   const int low_year  = year % 256;
 
  377   os << static_cast<char>(low_year)
 
  378      << static_cast<char>(high_year)
 
  379      << 
static_cast<char>(month)
 
  380      << static_cast<char>(day)
 
  381      << 
static_cast<char>(hour)
 
  382      << static_cast<char>(min);
 
  387                      int black_rating, 
int white_rating,
 
  388                      const std::string &black_title,
 
  389                      const std::string &white_title)
 
  404   for (
int i = 44; i < 84; ++i)
 
  408   const boost::gregorian::date start_date = record.
getDate();
 
  409   if (!start_date.is_special()) {
 
  411     writeStartDate(start_date.year(), start_date.month(), start_date.day(), 9, 0);
 
  413     for (
int i = 84; i < 90; ++i)
 
  418   for (
int i = 90; i < 118; ++i)
 
  426   if (moves.size() <= 256)
 
  428     if (moves.size() % 2 == 0)
 
  435     if (moves.size() % 2 == 0)
 
  436       os << static_cast<char>(KisenIpxFile::WHITE_WIN_256);
 
  438       os << static_cast<char>(KisenIpxFile::BLACK_WIN_256);
 
  440   for (
int i = 119; i < 212; ++i)
 
  444   writeRating(black_rating);
 
  445   writeRating(white_rating);
 
  446   for (
int i = 216; i < 256; ++i)