00001 #include "osl/record/kisen.h"
00002 #include "osl/record/csaIOError.h"
00003 #include "osl/apply_move/applyMove.h"
00004 #include "osl/pieceStand.h"
00005 #include <boost/filesystem/convenience.hpp>
00006 #include <iostream>
00007
00008 namespace osl
00009 {
00010 namespace record
00011 {
00012 Position KisenUtils::convertPosition( int pos ){
00013 assert(1<=pos && pos<=0x51);
00014 int y=((pos-1)/9)+1, x=((pos-1)%9)+1;
00015 return Position(x,y);
00016 }
00017
00018 Move KisenUtils::convertMove(SimpleState const& state,int c0,int c1){
00019 Move move;
00020
00021 if(1<=c1 && c1<=0x51){
00022 Position from=convertPosition(c1),to;
00023 Piece fromPiece=state.getPieceAt(from);
00024 assert(fromPiece.owner()==state.getTurn() ||
00025 (std::cerr << c1 << "," << from << "," << fromPiece << std::endl,0)
00026 );
00027 bool isPromote=false;
00028 if(1<=c0 && c0<=0x51){
00029 to=convertPosition(c0);
00030 }
00031 else if(0x65<=c0 && c0<=0xb5){
00032 to=convertPosition(c0-0x64);
00033 isPromote=true;
00034 }
00035 else{
00036 abort();
00037 }
00038 Piece toPiece=state.getPieceAt(to);
00039 assert(toPiece.isEmpty() || toPiece.owner()==alt(state.getTurn()));
00040 Ptype ptype=fromPiece.ptype();
00041 if(isPromote)ptype=promote(ptype);
00042 const Ptype captured = toPiece.ptype();
00043 if (captured == KING)
00044 return Move::INVALID();
00045 move=Move(from,to,ptype,captured,isPromote,state.getTurn());
00046 }
00047 else{
00048 assert(0x65<=c1);
00049 assert(1<=c0&&c0<=0x51);
00050 Position to=convertPosition(c0);
00051 Ptype ptype=PTYPE_EMPTY;
00052 int piece_on_stand = c1;
00053 const Ptype ptypes[]={ROOK,BISHOP,GOLD,SILVER,KNIGHT,LANCE,PAWN};
00054 for(size_t i=0;i<sizeof(ptypes)/sizeof(Ptype);i++){
00055 int count=state.countPiecesOnStand(state.getTurn(),ptypes[i]);
00056 if(count>0){
00057 if(piece_on_stand>0x64){
00058 piece_on_stand-=count;
00059 if(piece_on_stand<=0x64) ptype=ptypes[i];
00060 }
00061 }
00062 }
00063 assert(ptype!=PTYPE_EMPTY ||
00064 (std::cerr << state << to << " " << c1
00065 << " " << piece_on_stand << std::endl, false));
00066 move=Move(to,ptype,state.getTurn());
00067 }
00068 if (! state.isValidMove(move,true)) {
00069 std::cerr << "warning: bad move in kisen\n" << state << move << "\n";
00070 return Move();
00071 }
00072 assert(state.isValidMove(move,true) ||
00073 (std::cerr << state << move << std::endl, false));
00074 return move;
00075 }
00076
00077
00078 KisenFile::KisenFile(const std::string& fileName)
00079 :ifs(fileName.c_str()),initialState(HIRATE), fileName(fileName)
00080 {
00081 if (! ifs)
00082 throw CsaIOError("KisenFile not found");
00083 ifs.seekg(0,std::ios::end);
00084 assert((ifs.tellg() % 512)==0);
00085 numberOfGames=ifs.tellg()/512;
00086 }
00087
00088 const vector<Move> KisenFile::getMoves(size_t index)
00089 {
00090 assert(index<size());
00091 vector<Move> moves;
00092
00093 ifs.seekg(index*512,std::ios::beg);
00094 CArray<unsigned char, 512> cbuf;
00095 ifs.read(reinterpret_cast<char *>(&cbuf[0]),512);
00096 SimpleState state(HIRATE);
00097
00098 Player turn=BLACK;
00099 for(size_t turnCount=0;
00100 (turnCount*2 < cbuf.size())
00101 && cbuf[turnCount*2]!=0 && cbuf[turnCount*2+1]!=0;
00102 turnCount++, turn=alt(turn)){
00103 if(turnCount==KisenFile::maxMoves || cbuf[ turnCount *2 ] == 0 || cbuf[ turnCount * 2 + 1 ] == 0 ){ break; }
00104 int c0=cbuf[turnCount*2], c1=cbuf[turnCount*2+1];
00105 if (moves.empty() && c0 == 0xff && c1 == 0xff)
00106 break;
00107 const Move move=KisenUtils::convertMove(state,c0,c1);
00108 if (move.isInvalid())
00109 break;
00110 moves.push_back(move);
00111 ApplyMoveOfTurn::doMove(state, move);
00112 assert(state.isConsistent( true ) );
00113 }
00114 return moves;
00115 }
00116
00117 std::string KisenFile::getIpxFileName() const
00118 {
00119 namespace bf = boost::filesystem;
00120 const bf::path ipxfilename = bf::change_extension(bf::path(fileName), ".ipx");
00121 return ipxfilename.file_string();
00122
00123 }
00124
00125 KisenIpxFile::KisenIpxFile(const std::string& fileName)
00126 :ifs(fileName.c_str()), file_name(fileName)
00127 {
00128 if (! ifs)
00129 throw CsaIOError("KisenIpxFile not found");
00130 ifs.seekg(0,std::ios::end);
00131 assert((ifs.tellg() % 256)==0);
00132 numberOfGames=ifs.tellg()/256;
00133 }
00134 const std::string KisenIpxFile::getPlayer(size_t index,Player pl)
00135 {
00136 assert(index<size());
00137 vector<Move> moves;
00138 ifs.seekg(index*256,std::ios::beg);
00139 CArray<unsigned char, 256> cbuf;
00140 ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
00141 int startIndex=0;
00142 if(pl==WHITE)startIndex=14;
00143 CArray<char,15> buf;
00144 buf[14]='\0';
00145 strncpy(&buf[0],reinterpret_cast<char *>(&cbuf[startIndex]),14);
00146 return std::string(&buf[0]);
00147 }
00148 unsigned int KisenIpxFile::getRating(size_t index,Player pl)
00149 {
00150 assert(index<size());
00151 vector<Move> moves;
00152 ifs.seekg(index*256,std::ios::beg);
00153 CArray<unsigned char, 256> cbuf;
00154 ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
00155 int startIndex=0324;
00156 if(pl==WHITE)startIndex=0326;
00157 return cbuf[startIndex]+256*cbuf[startIndex+1];
00158 }
00159 unsigned int KisenIpxFile::getResult(size_t index)
00160 {
00161 assert(index<size());
00162 ifs.seekg(index*256,std::ios::beg);
00163 CArray<unsigned char, 256> cbuf;
00164 ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
00165 return cbuf[64+48+6];
00166 }
00167 const std::string KisenIpxFile::getTitle(size_t index,Player pl)
00168 {
00169 assert(index<size());
00170 vector<Move> moves;
00171 ifs.seekg(index*256,std::ios::beg);
00172 CArray<unsigned char, 256> cbuf;
00173 ifs.read(reinterpret_cast<char *>(&cbuf[0]),256);
00174 int startIndex=28;
00175 if(pl==WHITE)startIndex+=8;
00176 CArray<char,9> buf;
00177 buf[8]='\0';
00178 strncpy(&buf[0],reinterpret_cast<const char*>(&cbuf[startIndex]),8);
00179 return std::string(&buf[0]);
00180 }
00181
00182 KisenPlusFile::KisenPlusFile(const std::string& fileName)
00183 :ifs(fileName.c_str()),initialState(HIRATE)
00184 {
00185 if (! ifs)
00186 throw CsaIOError("KisenPlusFile not found");
00187 ifs.seekg(0,std::ios::end);
00188 assert((ifs.tellg() % 2048)==0);
00189 numberOfGames=ifs.tellg()/2048;
00190 }
00191
00192 const vector<Move> KisenPlusFile::getMoves(size_t index)
00193 {
00194 vector<Move> moves;
00195 vector<int> times;
00196 getMoves(index, moves, times);
00197 return moves;
00198 }
00199
00200 void KisenPlusFile::getMoves(size_t index,
00201 vector<Move>& moves, vector<int>& times)
00202 {
00203 assert(index<size());
00204
00205 ifs.seekg(index*2048,std::ios::beg);
00206 CArray<unsigned char, 2048> cbuf;
00207 ifs.read(reinterpret_cast<char *>(&cbuf[0]),2048);
00208 SimpleState state(HIRATE);
00209 for (size_t i = 0;
00210 i < 2048 && cbuf[i]!=0 && cbuf[i+1]!=0;
00211 i += 8)
00212 {
00213 int c0 = cbuf[i];
00214 int c1 = cbuf[i + 1];
00215 bool is_promote = false;
00216 Move move;
00217
00218 if (c0 > 100)
00219 {
00220 is_promote = true;
00221 c0 = 256 - c0;
00222 }
00223
00224 Position to(c0 % 10, c0 / 10);
00225
00226 if (c1 < 10)
00227 {
00228
00229 move = Move(to,
00230 PieceStand::order[c1 - 1],
00231 state.getTurn());
00232 }
00233 else
00234 {
00235 Position from(c1 % 10, c1 / 10);
00236 Ptype type = state.getPieceAt(from).ptype();
00237 if (is_promote)
00238 type = promote(type);
00239 move = Move(from, to,
00240 type, state.getPieceAt(to).ptype(),
00241 is_promote, state.getTurn());
00242 }
00243 moves.push_back(move);
00244 times.push_back(cbuf[i + 7] * 60 + cbuf[i + 6]);
00245 ApplyMoveOfTurn::doMove(state, move);
00246 assert(state.isConsistent( true ) );
00247 }
00248 }
00249 }
00250 }
00251
00252 osl::record::
00253 KisenFile::~KisenFile()
00254 {
00255 }
00256
00257 osl::record::
00258 KisenIpxFile::~KisenIpxFile()
00259 {
00260 }
00261
00262
00263
00264
00265