00001 #include "osl/record/record.h"
00002 #include "osl/record/csaIOError.h"
00003 #include "osl/apply_move/doUndoMoveLock.h"
00004 #include "osl/apply_move/applyMove.h"
00005 #include <stack>
00006 #include <iostream>
00007
00008 osl::record::
00009 MoveRecord::MoveRecord(const Move& mv, int ni)
00010 : move(mv), nodeIndex(ni), time(0)
00011 {
00012 }
00013
00014 namespace osl
00015 {
00016 namespace record
00017 {
00018
00019 IRecordStream::~IRecordStream(){}
00020
00021 ORecordStream::~ORecordStream(){}
00022
00023 const Move MoveRecord::getMove() const { return move; }
00024
00025 int MoveRecord::getNodeIndex() const { return nodeIndex; }
00026
00027 void MoveRecord::setTime(int t){
00028 time=t;
00029 }
00030
00031 void NodeRecord::addMoveRecord(int moveIndex){
00032 moves.push_back(moveIndex);
00033 }
00034
00035
00036 Record::Record(){ init(); }
00037
00038 void Record::init(){
00039 version="";
00040 playerNames[0]=playerNames[1]="";
00041 nrs.clear();
00042 nrs.push_back(NodeRecord());
00043 initialState.init(HIRATE);
00044 }
00045
00046 void Record::load(IRecordStream& irs){
00047 irs.load(this);
00048 }
00049 void Record::save(ORecordStream& ){
00050
00051 }
00052
00053 void Record::setVersion(const std::string& str){
00054 version=str;
00055 }
00056 const std::string& Record::getVersion() const{
00057 return version;
00058 }
00059 void Record::setPlayer(Player player,const std::string& str){
00060 playerNames[playerToIndex(player)]=str;
00061 }
00062 const std::string& Record::getPlayer(Player player) const{
00063 return playerNames[playerToIndex(player)];
00064 }
00065 void Record::setInitialState(const SimpleState& state){
00066 initialState=state;
00067 }
00068 SimpleState const& Record::getInitialState() const {
00069 if (! initialState.isConsistent(true))
00070 {
00071 const char *msg = "Record: bad initial state";
00072 std::cerr << msg << "\n";
00073 throw CsaIOError(msg);
00074 }
00075 return initialState;
00076 }
00077 int Record::addNodeRecord(){
00078 nrs.push_back(NodeRecord());
00079 return nrs.size()-1;
00080 }
00081 int Record::addMoveRecord(const MoveRecord& moveRecord){
00082 mrs.push_back(moveRecord);
00083 return mrs.size()-1;
00084 }
00085 NodeRecord* Record::nodeOf(int index){
00086 return &nrs.at(index);
00087 }
00088 const NodeRecord* Record::nodeOf(int index) const{
00089 return &nrs.at(index);
00090 }
00091 MoveRecord* Record::moveOf(int index){
00092 if (static_cast<size_t>(index) >= mrs.size())
00093 return NULL;
00094 else
00095 return &mrs.at(index);
00096 }
00097 const MoveRecord* Record::moveOf(int index) const {
00098 if (static_cast<size_t>(index) >= mrs.size())
00099 return NULL;
00100 else
00101 return &mrs.at(index);
00102 }
00103 NodeRecord& Record::operator[](int index){
00104 return nrs.at(index);
00105 }
00106
00107 void RecordVisitor::addMoveAndAdvance(Move move){
00108 assert(state->isValidMove(move));
00109
00110 int newNode=rec->addNodeRecord();
00111 int newMove=rec->addMoveRecord(MoveRecord(move,newNode));
00112 (*rec)[nodeIndex].addMoveRecord(newMove);
00113 nodeIndex=newNode;
00114 lastMoveIndex=newMove;
00115
00116 assert(state->isConsistent() || ((std::cerr << move <<"\n"<< *state),0));
00117 ApplyMoveOfTurn::doMove(*state, move);
00118 assert(state->isConsistent() || ((std::cerr << move <<"\n"<< *state),0));
00119 for(boost::ptr_vector<record::RecordVisitorObserver>::iterator each = observers.begin(); each != observers.end(); ++each){
00120 each->update(this);
00121 }
00122 }
00123
00124
00125 std::ostream& operator<<(std::ostream& os,const MoveRecord & mr){
00126 return os << "MoveRecord(" <<
00127 mr.getNodeIndex() << ')';
00128 }
00129
00130 std::ostream& operator<<(std::ostream& os,Record & r){
00131 os << "Record(";
00132 os << "version=" << r.getVersion()
00133 << ",BLACK=" << r.getPlayer(BLACK)
00134 << ",WHITE=" << r.getPlayer(WHITE);
00135 os << ",initial=" << std:: endl << r.getInitialState() << std::endl;
00136 SimpleState state=r.getInitialState();
00137 RecordVisitor visitor;
00138 std::stack<DoUndoMoveLock*> moveStack;
00139 visitor.setState(&state);
00140 visitor.setRecord(&r);
00141 NodeRecord* node=visitor.getNode();
00142 while(node->size()>0){
00143 int moveIndex=node->at(0);
00144 MoveRecord* mr=r.moveOf(moveIndex);
00145 Move move=mr->getMove();
00146 os << move << "," << mr->getTime() << "," << mr->getComment() << std::endl;
00147 node=r.nodeOf(mr->getNodeIndex());
00148 moveStack.push(new DoUndoMoveLock(state, move));
00149 assert(state.isConsistent());
00150 }
00151 os << state;
00152 while(!moveStack.empty())
00153 {
00154 DoUndoMoveLock *lock = moveStack.top();
00155 moveStack.pop();
00156 delete lock;
00157 assert(state.isConsistent());
00158 }
00159 os << state;
00160 return os << ')';
00161 }
00162
00163
00164 const vector<Move> Record::getMoves() const {
00165 vector<Move> moves;
00166 vector<int> dummy_time;
00167 getMoves(moves, dummy_time);
00168 return moves;
00169 }
00170
00171 int readInt(std::istream& is)
00172 {
00173 int ret=0;
00174 CArray<char,4> cs;
00175 is.read(&cs[0],4);
00176 for (int i=0;i<4;i++) {
00177 ret = (ret<<8)|(cs[i]&255);
00178 }
00179 return ret;
00180 }
00181
00182 void
00183 writeInt(std::ostream& os, int n)
00184 {
00185 CArray<char,4> buf;
00186 for (int i = 0; i < 4; i++)
00187 {
00188 buf[i] = (n >> (8 * (4 - i - 1))) & 255;
00189 }
00190 os.write(&buf[0], 4);
00191 }
00192
00193 }
00194 }
00195
00196 void osl::record::
00197 Record::getMoves(vector<Move>& moves, vector<int>& times,
00198 vector<std::string>& comments,
00199 vector<SearchInfo>& info) const
00200 {
00201 const NodeRecord* node=nodeOf(0);
00202 while(node->size()>0){
00203 const int moveIndex=node->at(0);
00204 const MoveRecord* mr=moveOf(moveIndex);
00205 const Move move=mr->getMove();
00206 moves.push_back(move);
00207 times.push_back(mr->getTime());
00208 comments.push_back(mr->getComment());
00209 info.push_back(mr->info);
00210
00211 node=nodeOf(mr->getNodeIndex());
00212 }
00213 }
00214
00215 void osl::record::
00216 Record::getMoves(vector<Move>& moves, vector<int>& times) const
00217 {
00218 vector<std::string> dummy_comments;
00219 vector<SearchInfo> dummy_info;
00220 getMoves(moves, times, dummy_comments, dummy_info);
00221 }
00222
00223 osl::record::
00224 RecordVisitor::~RecordVisitor()
00225 {
00226 }
00227
00228
00229
00230
00231