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)