void Game::LoadMap( const std::string & filename ) { XMLDocument doc; doc.LoadFile(filename.c_str()); if ( doc.ErrorID() != XML_NO_ERROR ) { ostringstream ss; ss << "Loadfile:" << g_TinyXmlErrors[doc.ErrorID()] << " " << doc.GetErrorStr1() << " " << doc.GetErrorStr2(); throw XmlParsingException(ss.str()); } // Load rooms XMLElement *pElem = doc.FirstChildElement( "Room"); while( pElem != NULL ) { g_Log << "loading..." << pElem->Attribute("id"); Room *pRoom = NULL; // Custom rooms if ( pElem->Attribute("class")) { std::string classID = pElem->Attribute("class"); pRoom = RoomFactory::Create(classID); } else { pRoom = new Room(); } pRoom->Load( *pElem ); if ( m_Rooms.find(pRoom->GetId()) != m_Rooms.end()) { throw DuplicateRoomIdException(pRoom->GetId()); } m_Rooms[pRoom->GetId()] = pRoom; pElem = pElem->NextSiblingElement("Room"); } // Load transitions pElem = doc.FirstChildElement( "Transitions"); if ( pElem != NULL ) { pElem = pElem->FirstChildElement("Transition"); while( pElem != NULL ) { const char * from = pElem->Attribute("from"); const char * to = pElem->Attribute("to"); const char * direction = pElem->Attribute("direction"); const char * oneway = pElem->Attribute("oneway"); if ( direction == NULL ) throw AttributeMissingException("Direction is missing from transition"); if ( from == NULL ) throw AttributeMissingException("From attribute is missing from transition!"); if ( to == NULL ) throw AttributeMissingException("To attribute is missing from transition!"); // check is from a proper id if ( m_Rooms.find(from) == m_Rooms.end() ) { ostringstream ss; ss << from << " is not a proper room id"; throw InvalidAttributeException(ss.str()); } // check is to a proper id if ( m_Rooms.find(to) == m_Rooms.end() ) { ostringstream ss; ss << to << " is not a proper room id"; throw InvalidAttributeException(ss.str()); } string tmp = direction; transform(tmp.begin(),tmp.end(), tmp.begin(), [] (char c){ return tolower(c);}); Direction dir = kNumDirs; if ( tmp == "east" ) dir = East; else if ( tmp == "north" ) dir = North; else if ( tmp == "south" ) dir = South; else if ( tmp == "west" ) dir = West; else throw InvalidAttributeException("Direction is not properly set"); m_Rooms[from]->SetNextRoom(dir, m_Rooms[to]); if ( !oneway ) { m_Rooms[to]->SetNextRoom(g_Opposite[dir], m_Rooms[from]); } pElem = pElem->NextSiblingElement("Transition"); } } else { throw ElementMissingException("Transitions is missing!"); } // set current room pElem = doc.FirstChildElement("OnStart"); if ( pElem == NULL ) throw ElementMissingException("No OnStart defined"); pElem = pElem->FirstChildElement("CurrentRoom"); if ( pElem == NULL ) { cout << "No current room set, problems might arise\n"; } else { const char *szRoomId = pElem->Attribute("id"); if ( szRoomId == NULL) throw InvalidAttributeException("Bad format CurrentRoom"); string tmp = szRoomId; if ( m_Rooms.find(tmp) == m_Rooms.end() ) { ostringstream ss; ss << "No room " << tmp << " found!"; throw ElementMissingException(ss.str()); } SetCurrentRoom(m_Rooms[tmp]); } pElem = doc.FirstChildElement("OnStart"); pElem = pElem->FirstChildElement("Story"); if ( pElem == NULL ) throw ElementMissingException("Story"); m_Story = (pElem->GetText() == NULL) ? "" : pElem->GetText(); pElem = doc.FirstChildElement("Player"); if ( !pElem ) throw new ElementMissingException("Player"); m_Player.Load(*pElem); }
void Game::Save( const std::string & filename ) { FILE *file = fopen(filename.c_str(), "w+"); if ( !file ) { stringstream ss; ss << "Cannot open file '" << filename << "' for writing"; throw runtime_error( ss.str() ); } XMLPrinter printer(file); printer.PushHeader(true,true); // store rooms with properties and items for(auto elem : m_Rooms ) { elem.second->Save(printer); } // store transitions map<pair<Direction,Room *>, Room * > savedTransitions; printer.OpenElement("Transitions"); for(auto elem : m_Rooms ) { Room * from = elem.second; for( int dir = (int)North; dir<kNumDirs; dir++) { Direction d = static_cast<Direction>(dir); Room * to = from->GetNextRoom(d); if ( to != NULL ) { // if two-way if( from == to->GetNextRoom(g_Opposite[d])) { // store our transition savedTransitions[make_pair<>(d,from)] = to; // remove link between rooms from->SetNextRoom(d,NULL); to->SetNextRoom(g_Opposite[d], NULL); printer.OpenElement("Transition"); printer.PushAttribute("from", from->GetId().c_str()); printer.PushAttribute("to", to->GetId().c_str()); printer.PushAttribute("direction", g_DirStr[d].c_str()); printer.CloseElement(); } else // one-way { printer.OpenElement("Transition"); printer.PushAttribute("from", from->GetId().c_str()); printer.PushAttribute("to", to->GetId().c_str()); printer.PushAttribute("direction", g_DirStr[d].c_str()); printer.PushAttribute("oneway", "true"); printer.CloseElement(); } } } } printer.CloseElement(); // restore links between actual rooms for( auto e : savedTransitions ) { // for readabilty Room * from = e.first.second; Room * to = e.second; Direction dir = e.first.first; g_Log << "adding transition " << from->GetId() << " <-> " << to->GetId() << " via " << g_DirStr[dir] << "\n"; from->SetNextRoom( dir, to ); to->SetNextRoom( g_Opposite[dir], from ); } // Store player's current location. printer.OpenElement("OnStart"); printer.OpenElement("CurrentRoom"); printer.PushAttribute("id", GetCurrentRoom()->GetId().c_str()); printer.CloseElement(); printer.OpenElement("Story"); printer.PushText(m_Story.c_str()); printer.CloseElement(); printer.CloseElement(); m_Player.Save(printer); }
void Configuration::ReadDatabase() { _professors.clear(); _studentGroups.clear(); _courses.clear(); _rooms.clear(); _courseClasses.clear(); mapid.clear(); PGconn *conn; PGresult *res, *resgr; int rec_count, rec_countgr; int row,row1,col; conn = PQconnectdb("dbname=gaschedule_development host=localhost user=alex password=alex"); if (PQstatus(conn) == CONNECTION_BAD) { puts("We were unable to connect to the database");} res = PQexec(conn,"select * from rooms order by id"); if (PQresultStatus(res) != PGRES_TUPLES_OK) {puts("We did not get any data!");} rec_count = PQntuples(res); for (row=0; row<rec_count; row++) { int id = atoi(PQgetvalue(res, row , 0)); char* name = PQgetvalue(res, row , 1) ; bool lab = !strcmp ( PQgetvalue(res, row , 2), "t" ); int size = atoi(PQgetvalue(res, row , 3)); Room* r = new Room(name, lab, size ); int a = row; a = a + 1; mapid.insert(pair <int,int> (a,id)); if( r ) { _rooms.insert( pair<int, Room*>( r->GetId(), r ) ); } } PQclear(res); res = PQexec(conn, "select * from courses order by id"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { puts("We did not get any data!");} rec_count = PQntuples(res); for (row=0; row<rec_count; row++) { int id = atoi(PQgetvalue(res, row , 0)); char* name = PQgetvalue(res, row , 1) ; Course* r = new Course(id, name ); if( r ) _courses.insert( pair<int, Course*>( r->GetId(), r ) ); } PQclear(res); res = PQexec(conn,"select * from professors order by id"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { puts("We did not get any data!");} rec_count = PQntuples(res); for (row=0; row<rec_count; row++) { int id = atoi(PQgetvalue(res, row , 0)); char* name = PQgetvalue(res, row , 1) ; Professor* r = new Professor(id, name ); if( r ) _professors.insert( pair<int, Professor*>( r->GetId(), r ) ); } PQclear(res); res = PQexec(conn,"select * from groups order by id"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { puts("We did not get any data!");} rec_count = PQntuples(res); for (row=0; row<rec_count; row++) { int id = atoi(PQgetvalue(res, row , 0)); char* name = PQgetvalue(res, row , 1) ; int size = atoi(PQgetvalue(res, row , 2)); StudentsGroup* r = new StudentsGroup(id, name , size ); if( r ) { _studentGroups.insert( pair<int, StudentsGroup*>( r->GetId(), r ) ); } } PQclear(res); list<StudentsGroup*> groups; res = PQexec(conn, "select * from clas order by id"); if (PQresultStatus(res) != PGRES_TUPLES_OK) {puts("We did not get any data!");} rec_count = PQntuples(res); resgr = PQexec(conn, "select clas.id, cla_groups.group_id from cla_groups INNER JOIN clas ON cla_groups.cla_id = clas.id"); if (PQresultStatus(resgr) != PGRES_TUPLES_OK) {puts("We did not get any data!"); } rec_countgr = PQntuples(resgr); for (row=0; row<rec_count; row++) { int claid = atoi(PQgetvalue(res, row , 0)); int pid = atoi(PQgetvalue(res, row , 1)); int cid = atoi(PQgetvalue(res, row , 2)); int dur = atoi(PQgetvalue(res, row , 4)); bool lab = !strcmp ( PQgetvalue(res, row , 5), "t" ); Professor* p = GetProfessorById( pid ); Course* c = GetCourseById( cid ); for (row1=0; row1<rec_countgr; row1++) { if (claid ==atoi(PQgetvalue(resgr, row1 , 0))) { StudentsGroup* g = GetStudentsGroupById( atoi(PQgetvalue(resgr, row1 , 1))); if( g ) { groups.push_back( g ); } } } CourseClass* cc = new CourseClass( p, c, groups, lab, dur ); if( cc ) _courseClasses.push_back( cc ); groups.clear(); } PQclear(resgr); PQclear(res); PQfinish(conn); _isEmpty = false; }