5 #include <boost/filesystem/convenience.hpp> 9 assert(1<=pos && pos<=0x51);
10 int y=((pos-1)/9)+1, x=((pos-1)%9)+1;
15 return ((pos.
y() - 1) * 9 + 1) + pos.
x() - 1;
21 if(1<=c1 && c1<=0x51){
28 (std::cerr << c1 <<
"," << from <<
"," << fromPiece << std::endl,0)
31 if(1<=c0 && c0<=0x51){
34 else if(0x65<=c0 && c0<=0xb5){
45 if(isPromote)ptype=
promote(ptype);
49 move=
Move(from,to,ptype,captured,isPromote,state.
turn());
53 if (!(1<=c0&&c0<=0x51)) {
54 throw CsaIOError(
"unknown kisen move "+std::to_string((
int)c0));
56 assert(1<=c0&&c0<=0x51);
59 int piece_on_stand = c1;
61 for(
size_t i=0;i<
sizeof(ptypes)/
sizeof(
Ptype);i++){
64 if(piece_on_stand>0x64){
65 piece_on_stand-=count;
66 if(piece_on_stand<=0x64) ptype=ptypes[i];
71 (std::cerr << state << to <<
" " << c1
72 <<
" " << piece_on_stand << std::endl,
false));
76 std::cerr <<
"warning: bad move in kisen\n" << state << move <<
"\n";
80 (std::cerr << state << move << std::endl,
false));
89 ifs.seekg(0,std::ios::end);
90 assert((
ifs.tellg() % 512)==0);
97 std::vector<Move>
moves;
99 ifs.seekg(index*512,std::ios::beg);
101 ifs.read(reinterpret_cast<char *>(&cbuf[0]),512);
105 for(
size_t turn_count=0;
106 (turn_count*2 < cbuf.
size())
107 && cbuf[turn_count*2]!=0 && cbuf[turn_count*2+1]!=0;
108 turn_count++, turn=
alt(turn)){
109 if(turn_count==
KisenFile::MaxMoves || cbuf[ turn_count *2 ] == 0 || cbuf[ turn_count * 2 + 1 ] == 0 ){
break; }
110 int c0=cbuf[turn_count*2], c1=cbuf[turn_count*2+1];
111 if (moves.empty() && c0 == 0xff && c1 == 0xff)
116 moves.push_back(move);
125 namespace bf = boost::filesystem;
126 const bf::path ipxfilename = bf::change_extension(bf::path(filename),
".ipx");
131 :
ifs(filename), file_name(filename)
134 throw CsaIOError(
"KisenIpxFile not found "+filename);
135 ifs.seekg(0,std::ios::end);
136 assert((
ifs.tellg() % 256)==0);
141 assert(index<
size());
142 ifs.seekg(index*256,std::ios::beg);
144 ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
146 if(pl==
WHITE)startIndex=14;
149 strncpy(&buf[0],reinterpret_cast<char *>(&cbuf[startIndex]),14);
154 assert(index<
size());
155 ifs.seekg(index*256,std::ios::beg);
157 ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
159 if(pl==
WHITE)startIndex=0326;
160 return cbuf[startIndex]+256*cbuf[startIndex+1];
164 assert(index<
size());
165 ifs.seekg(index*256,std::ios::beg);
167 ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
168 return cbuf[64+48+6];
172 assert(index<
size());
173 ifs.seekg(index*256,std::ios::beg);
175 ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
177 if(pl==
WHITE)startIndex+=8;
180 strncpy(&buf[0],reinterpret_cast<const char*>(&cbuf[startIndex]),8);
185 assert(index<
size());
186 ifs.seekg(index*256,std::ios::beg);
188 ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
189 const int startIndex=84;
190 const unsigned int year = cbuf[startIndex] + 256*cbuf[startIndex+1];
191 const unsigned int month = cbuf[startIndex+2];
192 const unsigned int day = cbuf[startIndex+3];
194 const boost::gregorian::date d = boost::gregorian::date(year, month, day);
196 }
catch (std::out_of_range& e) {
197 std::cerr << e.what() <<
": [" 198 << index <<
"] " << year <<
"-" << month <<
"-" << day <<
"\n";
199 return boost::gregorian::date(boost::gregorian::not_a_date_time);
208 ifs.seekg(0,std::ios::end);
209 assert((
ifs.tellg() % 2048)==0);
215 std::vector<Move>
moves;
216 std::vector<int> times;
217 load(index, moves, times);
222 std::vector<Move>&
moves, std::vector<int>& times)
224 assert(index<
size());
226 ifs.seekg(index*2048,std::ios::beg);
228 ifs.read(reinterpret_cast<char *>(&cbuf[0]),2048);
231 i < 2048 && cbuf[i]!=0 && cbuf[i+1]!=0;
235 int c1 = cbuf[i + 1];
236 bool is_promote =
false;
245 Square to(c0 % 10, c0 / 10);
256 Square from(c1 % 10, c1 / 10);
260 move =
Move(from, to,
262 is_promote, state.
turn());
264 moves.push_back(move);
265 times.push_back(cbuf[i + 7] * 60 + cbuf[i + 6]);
287 std::cerr <<
"Can not save non-HIRATE record" << std::endl;
291 const int max_length =
std::min(256, static_cast<int>(record.
moves.size()));
292 for (
int i = 0; i < max_length; ++i)
303 os << static_cast<char>(to) << static_cast<char>(from);
310 if (ptype == move.
ptype())
317 os << static_cast<char>(to) << static_cast<char>(count);
321 for (
int i = max_length; i < 256; ++i)
330 for (
size_t i = 0; i < length; ++i)
332 if (i < name.length())
346 int high = rating / 256;
347 int low = rating % 256;
348 os << static_cast<char>(low) << static_cast<char>(high);
354 const int high_year = year / 256;
355 const int low_year = year % 256;
356 os << static_cast<char>(low_year)
357 << static_cast<char>(high_year)
358 <<
static_cast<char>(month)
359 << static_cast<char>(day)
360 <<
static_cast<char>(hour)
361 << static_cast<char>(min);
366 int black_rating,
int white_rating,
367 const std::string &black_title,
368 const std::string &white_title)
383 for (
int i = 44; i < 84; ++i)
387 const boost::gregorian::date start_date = record.
start_date;
388 if (!start_date.is_special()) {
390 writeStartDate(start_date.year(), start_date.month(), start_date.day(), 9, 0);
392 for (
int i = 84; i < 90; ++i)
397 for (
int i = 90; i < 118; ++i)
402 std::vector<int> time = record.
times;
404 if (moves.size() <= 256)
406 if (moves.size() % 2 == 0)
413 if (moves.size() % 2 == 0)
418 for (
int i = 119; i < 212; ++i)
422 writeRating(black_rating);
423 writeRating(white_rating);
424 for (
int i = 216; i < 256; ++i)
void writeRating(int rating)
CArray< std::string, 2 > player
constexpr Player alt(Player player)
static std::string convert(const std::string &fromcode, const std::string &tocode, const std::string &src)
std::string file_string(const boost::filesystem::path &path)
void load(size_t index, std::vector< Move > &, std::vector< int > &)
int min(Player p, int v1, int v2)
int countPiecesOnStand(Player pl, Ptype ptype) const
持駒の枚数を数える
const Piece pieceAt(Square sq) const
const std::string filename
NumEffectState initial_state
int y() const
将棋としてのY座標を返す.
unsigned int rating(size_t index, Player pl)
const Piece pieceOnBoard(Square sq) const
KisenIpxFile(std::string const &filename)
std::string player(size_t index, Player pl)
std::string title(size_t index, Player pl)
int x() const
将棋としてのX座標を返す.
static const size_t MaxMoves
static Move convertMove(SimpleState const &state, int c0, int c1)
Ptype promote(Ptype ptype)
promote可能なptypeに対して,promote後の型を返す promote不可のptypeを与えてはいけない. ...
bool isConsistent(bool showError=true) const
bool isValidMove(Move move, bool show_error=true) const
合法手かどうかを検査する. isValidMoveByRule, isAlmostValidMove をおこなう. 玉の素抜きや王手を防いで...
const Square from() const
boost::gregorian::date startDate(size_t index)
開始日の年月日を返す
static const Move INVALID()
void writeString(const std::string &name, size_t length)
std::vector< Move > moves(size_t index)
void save(const RecordMinimal &)
std::vector< Move > moves() const
KisenPlusFile(const std::string &fileName)
void save(const Record &, int black_rating, int white_rating, const std::string &black_title, const std::string &white_title)
std::vector< Move > moves(size_t index)
std::string ipxFileName() const
static const CArray< Ptype, 7 > order
持駒の表示で良く使われる順番.
PtypeO captured(PtypeO ptypeO)
unpromoteすると共に,ownerを反転する.
void writeStartDate(int year, int month, int day, int hour, int min)
boost::gregorian::date start_date
static Square convertSquare(int pos)
KisenFile(const std::string &filename)
unsigned int result(size_t index)
std::vector< Move > moves
std::string sjis2euc(const std::string &str)
Convert character encoding from Shift_JIS to EUC-JP.
bool isInvalid() const
state に apply 可能でない場合にtrue