00001 #include "osl/record/csaRecord.h"
00002 #include "osl/record/csaIOError.h"
00003 #include "osl/state/pawnMaskState.h"
00004 #include "osl/apply_move/applyMove.h"
00005 #include <iostream>
00006 #include <fstream>
00007 #include <stdexcept>
00008 #include <cassert>
00009 #include <string>
00010 #include <sstream>
00011
00012
00013
00014 namespace osl
00015 {
00016 namespace record
00017 {
00018 namespace
00019 {
00020 const SearchInfo makeInfo(const SimpleState& initial,
00021 const std::string& line,
00022 Move last_move)
00023 {
00024 std::istringstream is(line);
00025 SearchInfo info;
00026 is >> info.value;
00027
00028 PawnMaskState state(initial);
00029 std::string s;
00030 while (is >> s)
00031 {
00032 if (s == csa::show(last_move))
00033 continue;
00034 last_move = Move::INVALID();
00035 try
00036 {
00037 const Move move = (s == "%PASS"
00038 ? Move::PASS(state.getTurn())
00039 : csa::strToMove(s, state));
00040 if (move.isPass() || state.isValidMove(move))
00041 {
00042 info.moves.push_back(move);
00043 ApplyMoveOfTurn::doMove(state, move);
00044 }
00045 continue;
00046 }
00047 catch(CsaIOError& e)
00048 {
00049
00050 }
00051 std::cerr << "drop illegal move in comment " << s << std::endl;
00052 break;
00053 }
00054 return info;
00055 }
00056 void csaParseLine(boost::shared_ptr<RecordVisitor> rv,const std::string& s)
00057 {
00058 Record *rec=rv->getRecord();
00059 SimpleState* state=rv->getState();
00060
00061 if (s.length()==0)
00062 return;
00063 switch(s.at(0)){
00064 case '\'':
00065 if (s.substr(1,2) == "* ")
00066 rv->getLastMove()->setComment(s.substr(3));
00067 else if (s.substr(1,2) == "**")
00068 {
00069 MoveRecord *mr = rv->getLastMove();
00070 rv->getLastMove()->info = makeInfo(*state, s.substr(3), mr ? mr->getMove() : Move::INVALID());
00071 }
00072 return;
00073 case '$':
00074 return;
00075 case 'V':
00076 rec->setVersion(s.substr(1));
00077 return;
00078 case 'N':
00079 switch(s.at(1)){
00080 case '+':
00081 case '-':
00082 rec->setPlayer(csa::charToPlayer(s.at(1)),s.substr(2));
00083 break;
00084 default:
00085 std::cerr << "Illegal csa line " << s << std::endl;
00086 throw CsaIOError("illegal csa line "+s);
00087 }
00088 break;
00089 case 'P':
00090 switch(s.at(1)){
00091 case 'I':
00092 state->init(HIRATE);
00093 break;
00094 case '+':
00095 case '-':{
00096 Player pl=csa::charToPlayer(s.at(1));
00097 for(unsigned int i=2;i<=s.length()-4;i+=4){
00098 Position pos=csa::strToPos(s.substr(i,2));
00099 if(s.substr(i+2,2) == "AL"){
00100 state->setPieceAll(pl);
00101 }
00102 else{
00103 Ptype ptype=csa::strToPtype(s.substr(i+2,2));
00104 state->setPiece(pl,pos,ptype);
00105 }
00106 }
00107 break;
00108 }
00109 default:
00110 if(isdigit(s.at(1))){
00111 int y=s.at(1)-'0';
00112 for(unsigned int x=9,i=2;i<s.length();i+=3,x--){
00113 if(s.at(i)==' ') continue;
00114 Player pl=csa::charToPlayer(s.at(i));
00115 Position pos(x,y);
00116 Ptype ptype=csa::strToPtype(s.substr(i+1,2));
00117 state->setPiece(pl,pos,ptype);
00118 }
00119 }
00120 }
00121 break;
00122 case '+':
00123 case '-':{
00124 Player pl=csa::charToPlayer(s.at(0));
00125 if(s.length()==1){
00126 state->setTurn(pl);
00127 rec->setInitialState(*state);
00128 }
00129 else{
00130 const Move m = csa::strToMove(s,*state);
00131 if (! state->isValidMove(m))
00132 {
00133 std::cerr << "Illegal move " << m << std::endl;
00134 throw CsaIOError("illegal move "+s);
00135 }
00136 rv->addMoveAndAdvance(m);
00137 return;
00138 }
00139 break;
00140 }
00141 case 'T':
00142 (rv->getLastMove())->setTime(atoi(s.c_str()+1));
00143 return;
00144 case '%':
00145 return;
00146 default:
00147 throw CsaIOError("unknown character in csaParseLine "+s);
00148 }
00149 }
00150 }
00151 }
00152 }
00153
00154 osl::record::csa::
00155 InputStream::InputStream(std::istream& is)
00156 : is(is),
00157 rv(boost::shared_ptr<record::RecordVisitor>(new record::RecordVisitor()))
00158 {
00159 if (! is)
00160 {
00161 std::cerr << "InputStream::InputStream cannot read \n";
00162 abort();
00163 }
00164 }
00165
00166 osl::record::csa::
00167 InputStream::InputStream(std::istream& is, boost::shared_ptr<record::RecordVisitor> rv)
00168 : is(is), rv(rv)
00169 {
00170 if (! is)
00171 {
00172 std::cerr << "InputStream::InputStream cannot read \n";
00173 abort();
00174 }
00175 }
00176
00177 osl::record::csa::
00178 InputStream::~InputStream(){}
00179
00180 void osl::record::csa::
00181 InputStream::load(Record* rec)
00182 {
00183
00184 state.init();
00185 rv->setState(&state);
00186 rv->setRecord(rec);
00187 std::string line;
00188 while (std::getline(is, line))
00189 {
00190
00191 if ((! line.empty())
00192 && (line[line.size()-1] == 13))
00193 line.erase(line.size()-1);
00194 csaParseLine(rv, line);
00195 }
00196 }
00197
00198 osl::record::csa::
00199 CsaFile::CsaFile(const std::string& fileName)
00200 {
00201 std::ifstream ifs(fileName.c_str());
00202 if (! ifs)
00203 {
00204 const std::string msg = "CsaFile::CsaFile file cannot read ";
00205 std::cerr << msg << fileName << "\n";
00206 throw CsaIOError(msg + fileName);
00207 }
00208 InputStream irs(ifs);
00209 irs.load(&rec);
00210 }
00211
00212 osl::record::csa::
00213 CsaFile::~CsaFile()
00214 {
00215 }
00216
00217 const osl::record::Record& osl::record::csa::
00218 CsaFile::getRecord() const
00219 {
00220 return rec;
00221 }
00222
00223 const osl::SimpleState& osl::record::csa::
00224 CsaFile::getInitialState() const
00225 {
00226 return rec.getInitialState();
00227 }
00228
00229
00230
00231
00232
00233