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){
22 Square from=convertSquare(c1),to;
28 (std::cerr << c1 <<
"," << from <<
"," << fromPiece << std::endl,0)
31 if(1<=c0 && c0<=0x51){
34 else if(0x65<=c0 && c0<=0xb5){
35 to=convertSquare(c0-0x64);
45 if(isPromote)ptype=
promote(ptype);
53 if (!(1<=c0&&c0<=0x51)) {
54 throw CsaIOError(
"unknown kisen move "+std::to_string((
int)c0));
56 assert(1<=c0&&c0<=0x51);
57 Square to=convertSquare(c0);
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)
401 std::vector<Move> moves = record.
moves();
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)
static const Move INVALID()
bool isInvalid() const
state に apply 可能でない場合にtrue
const Square from() const
bool isConsistent(bool showError=true) const
static const CArray< Ptype, 7 > order
持駒の表示で良く使われる順番.
const Piece pieceOnBoard(Square sq) const
bool isValidMove(Move move, bool show_error=true) const
合法手かどうかを検査する. isValidMoveByRule, isAlmostValidMove をおこなう. 玉の素抜きや王手を防いでいるか, 千日手,打歩詰かどうかは検査しない.
int countPiecesOnStand(Player pl, Ptype ptype) const
持駒の枚数を数える
const Piece pieceAt(Square sq) const
int y() const
将棋としてのY座標を返す.
int x() const
将棋としてのX座標を返す.
static const size_t MaxMoves
std::vector< Move > moves(size_t index)
KisenFile(const std::string &filename)
std::string ipxFileName() const
boost::gregorian::date startDate(size_t index)
開始日の年月日を返す
std::string player(size_t index, Player pl)
std::string title(size_t index, Player pl)
unsigned int rating(size_t index, Player pl)
KisenIpxFile(std::string const &filename)
unsigned int result(size_t index)
void save(const Record &, int black_rating, int white_rating, const std::string &black_title, const std::string &white_title)
void writeStartDate(int year, int month, int day, int hour, int min)
void writeRating(int rating)
void writeString(const std::string &name, size_t length)
void load(size_t index, std::vector< Move > &, std::vector< int > &)
std::vector< Move > moves(size_t index)
KisenPlusFile(const std::string &fileName)
static Move convertMove(SimpleState const &state, int c0, int c1)
static Square convertSquare(int pos)
void save(const RecordMinimal &)
std::string sjis2euc(const std::string &str)
Convert character encoding from Shift_JIS to EUC-JP.
std::string file_string(const boost::filesystem::path &path)
constexpr Player alt(Player player)
Ptype promote(Ptype ptype)
promote可能なptypeに対して,promote後の型を返す promote不可のptypeを与えてはいけない.
PtypeO captured(PtypeO ptypeO)
unpromoteすると共に,ownerを反転する.
NumEffectState initial_state
std::vector< Move > moves
static std::string convert(const std::string &fromcode, const std::string &tocode, const std::string &src)
std::vector< Move > moves() const
CArray< std::string, 2 > player
boost::gregorian::date start_date