Skip to main content
Tweeted twitter.com/StackCodeReview/status/779163535515480064
edited tags; froze GitHub commit
Source Link
200_success
  • 144.2k
  • 22
  • 188
  • 473

I wrote a simple room booking system to get to know more about C++ and OOP. It simply stores rooms/labs/lecture halls with name, position, doors and possibly more details and can be booked/unbooked. features include dynamically adding/removing rooms, getting specific query rooms and summarizing the details. The C++ code is at this placethis place. It basically asks for user input. I tried to make it very robust with invalid input fail-proof.

I wrote a simple room booking system to get to know more about C++ and OOP. It simply stores rooms/labs/lecture halls with name, position, doors and possibly more details and can be booked/unbooked. features include dynamically adding/removing rooms, getting specific query rooms and summarizing the details. The C++ code is at this place. It basically asks for user input. I tried to make it very robust with invalid input fail-proof.

I wrote a simple room booking system to get to know more about C++ and OOP. It simply stores rooms/labs/lecture halls with name, position, doors and possibly more details and can be booked/unbooked. features include dynamically adding/removing rooms, getting specific query rooms and summarizing the details. The C++ code is at this place. It basically asks for user input. I tried to make it very robust with invalid input fail-proof.

added 3 characters in body; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

C++ OOP first time for Room Booking System

MainThe main things I am unaware are of standard practices, conventions and better ways to get few things done. I have coded most of it using various examples spread around the web, which might not be optimal for this application.

C++ OOP first time for Room Booking System

Main things I am unaware are of standard practices, conventions and better ways to get few things done. I have coded most of it using various examples spread around the web, which might not be optimal for this application.

Room Booking System

The main things I am unaware are of standard practices, conventions and better ways to get few things done. I have coded most of it using various examples spread around the web, which might not be optimal for this application.

deleted 3476 characters in body
Source Link
RE60K
  • 1.5k
  • 2
  • 11
  • 27

LabRoomBookingSystem.cpph

#ifndef ROOMBOOKINGSYSTEM_H_
#define ROOMBOOKINGSYSTEM_H_

#include <iostream>
#include <string>
#include <vector>

#include "Lab"Position.h"
#include "Room.h"
#include "Lab.h"
#include "LectureHall.h"

class Lab;
class LectureHall;

using namespace std;

#define #includeROOMS <iostream>1
#define LABS 2
#define LECTURE_HALLS 3

//TODO make #includereadme
class <string>RoomBookingSystem {

        void parse(vector<vector<string> > roomDetails, int type);
    #include "Position.h"   void loadstate(vector<vector<string> > bookstatus, int type);
        vector<Room*>* getList(int type);
    using namespace std;  vector<Room*>* getConstList(int type) const;
    //=========================================================================    template<typename T> Room* getRoom(int type, const T matcher) const;
    // CONSTRUCTOR   template<typename T> void print(vector<Room*>& vec, const string& pDescriptor);
    //=========================================================================    struct RoomComparator {
    Lab::Lab            bool operator(string)(const pNameint i, doubleconst pAreaint j);
        };
        void saveRooms(vector<Room*>& vec, intconst pDoorschar* loc, Positionconst pPositionchar* bookloc);
        vector<vector<string> > read(const char* pFilename, const int pComputerspColumns);

    public: 

        RoomBookingSystem();
     Room   ~RoomBookingSystem();
        void addRoom(const string& pName, const double pArea, const int pDoors, pPosition)const {int pX, const int pY);
        computersvoid =addLab(const pComputers;
string& pName, const double pArea, const }int pDoors, const int pX, const int pY, int pComputers);
        void Lab::printRoomaddLectureHall() {
const string& pName, const double pArea, const int coutpDoors, <<const expand_selfint <<pX, "\tComputers:const "int <<pY, computersconst <<int endl;pChairs);
    }
    intbool Lab::getComputersremoveRoom()int consttype, {Room* r);
        returnRoom* computers;
getRoom(const string& pName, int }type) const;
    
     voidRoom* Lab::setComputersgetRoom(const int computerspX, const int pY, int type) {const;
        this->computersvector<Room*> =getMinimumRoomsOfArea(const computers;int pRequiredArea) const;
    }
    LectureHall* getSmallestLectureHallByStudents(const int pRequiredChairs) const;
    double Lab::getEquipmentDensity   Lab* getLabByLeastEquipmentDensity() {const;
        returnRoom* computersgetNearestRoom(const /int area;pX, const int pY) const;
        void printAll();

};

#endif /* ROOMBOOKINGSYSTEM_H_ */

MatchersRoomBookingSystem.hcpp

    #ifndef MATCHERS_H_
    #define MATCHERS_H_
    
    #include <string>
    
    #include "Position.h"
    #include "Room.h"
    
    using namespace std;
    
    class Matchers {
        public:
            struct MatchName {
                    MatchName(const string& s);
                    bool operator()(const Room* r) const;
                private:
                    const string& name;
            };
            struct MatchPosition {
                    MatchPosition(const int pX, const int pY);
                    bool operator()(const Room* r) const;
                private:
                    const int x;
                    const int y;
            };
    };
    
    #endif /* MATCHERS_H_ */
#include "RoomBookingSystem.h"

#include <stdlib.h>
#include <algorithm>
#include <cfloat>
#include <climits>
#include <fstream>
#include <iterator>
#include <string.h>

#include "Matchers.h"

#define expand_it (*it)[0], atof((*it)[1].c_str()), atoi((*it)[2].c_str()), Position(atoi((*it)[3].c_str()), atoi((*it)[4].c_str()))
#define print_separator cout<<string(100,'=')<<endl;
#define sq(x) (x)*(x)
using namespace std;

#define ROOM_FILE_LOC "data/ROOM.txt"
#define LAB_FILE_LOC "data/LAB.txt"
#define LECTURE_HALL_FILE_LOC "data/LEC.txt"

#define ROOM_BOOK_LOC "data/ROOM_BOOK.txt"
#define LAB_BOOK_LOC "data/LAB_BOOK.txt"
#define LECTURE_HALL_BOOK_LOC "data/LEC_BOOK.txt"

vector<Room*> rooms;
vector<Room*> labss;
vector<Room*> lectureHalls;

RoomBookingSystem::RoomBookingSystem() {
        vector<vector<string> > roomDetails = read(ROOM_FILE_LOC, 5);
        vector<vector<string> > labDetails = read(LAB_FILE_LOC, 6);
        vector<vector<string> > lectureHallDetails = read(LECTURE_HALL_FILE_LOC, 6);
        vector<vector<string> > roomBookDetails = read(ROOM_BOOK_LOC, 1);
        vector<vector<string> > labBookDetails = read(LAB_BOOK_LOC, 1);
        vector<vector<string> > lectureHallBookDetails = read(LECTURE_HALL_BOOK_LOC, 1);
        parse(roomDetails, ROOMS);
        parse(labDetails, LABS);
        parse(lectureHallDetails, LECTURE_HALLS);
        loadstate(roomBookDetails, ROOMS);
        loadstate(labBookDetails, LABS);
        loadstate(lectureHallBookDetails, LECTURE_HALLS);
}

RoomBookingSystem::~RoomBookingSystem() {
        saveRooms(rooms, ROOM_FILE_LOC, ROOM_BOOK_LOC);
        saveRooms(labss, LAB_FILE_LOC, LAB_BOOK_LOC);
        saveRooms(lectureHalls, LECTURE_HALL_FILE_LOC, LECTURE_HALL_BOOK_LOC);
}
vector<vector<string> > RoomBookingSystem::read(const char* pFilename, const int pColumns) {
        ifstream inputStream;
        vector<vector<string> > rooms_list;
        inputStream.open(pFilename);
        if (inputStream.is_open()) {
                while (!inputStream.eof()) {
                        vector<string> roomDetails;
                        for (int i = 0; i < pColumns; i++) {
                                string detail;
                                inputStream >> detail;
                                roomDetails.push_back(detail);
                        }
                        rooms_list.push_back(roomDetails);
                }
        }
        inputStream.close();
        return rooms_list;
}
void RoomBookingSystem::saveRooms(vector<Room*>& vec, const char* loc, const char* bookloc) {
        ofstream outputStream;
        ofstream outputStream2;
        outputStream.open(loc);
        outputStream2.open(bookloc);
        string s = string(loc);
        if (outputStream.is_open() && outputStream2.is_open()) {
                for (unsigned i = 0; i < vec.size(); i++) {
                        Room* r = vec[i];
                        outputStream << r->getName() << "\t" << fixed << setprecision(4) << r->getArea() << "\t" << r->getDoors() << "\t" << r->getPosition().x << "\t" << r->getPosition().y;
                        if (s.compare(LAB_FILE_LOC) == 0) {
                                outputStream << "\t" << ((Lab*) r)->getComputers();
                        } else if (s.compare(LECTURE_HALL_FILE_LOC) == 0) {
                                outputStream << "\t" << ((LectureHall*) r)->getChairs();
                        }
                        outputStream2 << ((vec[i]->isBooked()) ? "1" : "0");
                        if (i != vec.size() - 1) {
                                outputStream << endl;
                                outputStream2 << endl;
                        }
                }
        }
        outputStream.close();
        outputStream2.close();
}
vector<Room*>* RoomBookingSystem::getList(int type) {
        switch (type) {
        case ROOMS:
                return &rooms;
        case LABS:
                return &labss;
        case LECTURE_HALLS:
                return &lectureHalls;
        }
        return NULL;
}
vector<Room*>* RoomBookingSystem::getConstList(int type) const {
        switch (type) {
        case ROOMS:
                return &rooms;
        case LABS:
                return &labss;
        case LECTURE_HALLS:
                return &lectureHalls;
        }
        return NULL;
}

void RoomBookingSystem::parse(vector<vector<string> > roomDetails, int type) {
        for (vector<vector<string> >::iterator it = roomDetails.begin(); it != roomDetails.end(); it++) {
                switch (type) {
                case ROOMS:
                        rooms.push_back(new Room(expand_it));
                        break;
                case LABS:
                        labss.push_back(new Lab(expand_it, atoi((*it)[5].c_str())));
                        break;
                case LECTURE_HALLS:
                        lectureHalls.push_back(new LectureHall(expand_it, atoi((*it)[5].c_str())));
                        break;
                }
        }
}
void RoomBookingSystem::loadstate(vector<vector<string> > bookstatus, int type) {
        vector<Room*>* vec = getList(type);
        for (unsigned i = 0; i < vec->size(); i++) {
                ((*vec)[i])->setBooked(atoi(bookstatus[i][0].c_str()) == 1);
        }
}

void bookRoom(Room &r) {
        r.book();
}
void unbookRoom(Room &r) {
        r.unbook();
}
void RoomBookingSystem::printAll() {
        print<Room>(rooms, "Rooms");
        print<Lab>(labss, "Labs");
        print<LectureHall>(lectureHalls, "Lecture Halls");
}
template<typename T> void RoomBookingSystem::print(vector<Room*>& vec, const string& pDescriptor) {
        print_separator
                cout << "These are currently " << vec.size() << " " << pDescriptor << ": " << endl;
        for (unsigned i = 0; i < vec.size(); i++) {
                ((T*) vec[i])->printRoom();
        }
        print_separator
}
void RoomBookingSystem::addRoom(const string& pName, const double pArea, const int pDoors, const int pX, const int pY) {
        rooms.push_back(new Room(pName, pArea, pDoors, Position(pX, pY)));
}
void RoomBookingSystem::addLab(const string& pName, const double pArea, const int pDoors, const int pX, int pY, int pComputers) {
        labss.push_back(new Lab(pName, pArea, pDoors, Position(pX, pY), pComputers));
}
void RoomBookingSystem::addLectureHall(const string& pName, const double pArea, const int pDoors, const int pX, const int pY, const int pChairs) {
        lectureHalls.push_back(new LectureHall(pName, pArea, pDoors, Position(pX, pY), pChairs));
}
Room* RoomBookingSystem::getRoom(const string& pName, int type) const {
        return getRoom(type, Matchers::MatchName(pName));
}
Room* RoomBookingSystem::getRoom(const int pX, const int pY, int type) const {
        return getRoom(type, Matchers::MatchPosition(pX, pY));
}
bool RoomBookingSystem::RoomComparator::operator()(const int i, const int j) {
        bool b1 = rooms[i]->isBooked();
        bool b2 = rooms[j]->isBooked();
        if (b1 && !b2) {
                return i;
        } else if (!b1 && b2) {
                return j;
        } else {
                return rooms[i]->getArea() >= rooms[j]->getArea();
        }
}
vector<Room*> RoomBookingSystem::getMinimumRoomsOfArea(const int pRequiredArea) const {
        vector<int> roomIndices;
        vector<Room*> requiredRoom;
        for (unsigned i = 0; i < rooms.size(); i++)
                roomIndices.push_back(i);
        sort(roomIndices.begin(), roomIndices.end(), RoomComparator());
        double area = 0;
        for (unsigned i = 0; i < roomIndices.size() && area < pRequiredArea && !rooms[roomIndices[i]]->isBooked(); i++) {
                area += rooms[roomIndices[i]]->getArea();
                requiredRoom.push_back(rooms[roomIndices[i]]);
        }
        if (area >= pRequiredArea)
                return requiredRoom;
        else {
                vector<Room*> emptyVec;
                return emptyVec;
        }
}
LectureHall* RoomBookingSystem::getSmallestLectureHallByStudents(const int pRequiredChairs) const {
        double minArea = DBL_MAX;
        LectureHall* requiredHall = new LectureHall("", 0, 0, Position(0, 0), 0);
        for (vector<Room*>::iterator it = lectureHalls.begin(); it != lectureHalls.end(); it++) {
                if (((LectureHall*) *it)->getChairs() >= pRequiredChairs && !(*it)->isBooked() && (*it)->getArea() < minArea) {
                        requiredHall = (LectureHall*) *it;
                        minArea = requiredHall->getArea();
                }
        }
        return requiredHall;
}
Lab* RoomBookingSystem::getLabByLeastEquipmentDensity() const {
        double minDensity = DBL_MAX;
        Lab* requiredLab = new Lab("", 0, 0, Position(0, 0), 0);
        for (vector<Room*>::iterator it = labss.begin(); it != labss.end(); it++) {
                if (((Lab*) *it)->getEquipmentDensity() < minDensity && !(*it)->isBooked()) {
                        requiredLab = (Lab*) *it;
                        minDensity = requiredLab->getEquipmentDensity();
                }
        }
        return requiredLab;
}

Room* RoomBookingSystem::getNearestRoom(const int pX, const int pY) const {
        long minDistanceSquared = LONG_MAX;
        Room* requiredRoom = new Room("", 0, 0, Position(0, 0));
        for (vector<Room*>::iterator it = rooms.begin(); it != rooms.end(); it++) {
                long distanceSquared = sq((*it)->getPosition().x - pX) + sq((*it)->getPosition().y - pY);
                if (distanceSquared < minDistanceSquared && !(*it)->isBooked()) {
                        requiredRoom = *it;
                        minDistanceSquared = distanceSquared;
                }
        }
        return requiredRoom;
}

template<class T> Room* RoomBookingSystem::getRoom(int type, const T matcher) const {
        vector<Room*>* vec = getConstList(type);
        vector<Room*>::iterator r = find_if(vec->begin(), vec->end(), matcher);
        return *r;
}

bool RoomBookingSystem::removeRoom(int type, Room* r) {
        vector<Room*>* vec = getList(type);
        if (r != *vec->end()) {
                vec->erase(std::remove(vec->begin(), vec->end(), r), vec->end());
                return true;
        } else
                return false;
}

PositionRoom.cpph

#ifndef ROOM_H_
#define ROOM_H_

#include <string>
#include <iomanip>

#include "Position.h"
 
#define expand_self "Name: 
 "<<name<<"\tArea: "<<setprecision(4)<<area<<"\tDoors: "<<doors<<"\tPosition: ("<<position.x<<","<<position.y<<")\tBooked: "<<((booked)?"Yes":"No")

using namespace std; 

class Room {

  Position:  protected:

        string name;
        double area;
        int doors;
        Position position;
        bool booked;

    public:

        Room(intstring apName, double pArea, int pDoors, Position pPosition);
        virtual void printRoom();
        virtual ~Room() {
        }
        bool operator==(const Room& b);
 :       double getArea() const;
        bool isBooked() const;
  x      void book(a),;
 y       void unbook(b);
 {       int getDoors() const;
    }    const string& getName() const;
        Position getPosition() const;

        void setBooked(bool booked);
};

#endif /* ROOM_H_ */
    #include "Room.h"
    
    #include <iostream>
    
    using namespace std;
    Room::Room(string pName, double pArea, int pDoors, Position pPosition) :
            name(pName), area(pArea), doors(pDoors), position(pPosition), booked(false) {
    }
    void Room::printRoom() {
        cout << expand_self << endl;
    }
    bool Room::operator==(const Room& r) {
        return name == r.name && position.x == r.position.x && position.y == r.position.y;
    }
    double Room::getArea() const {
        return area;
    }
    
    bool Room::isBooked() const {
        return booked;
    }
    
    void Room::book() {
        this->booked = true;
    }
    void Room::unbook() {
        this->booked = false;
    }
    
    int Room::getDoors() const {
        return doors;
    }
    
    const string& Room::getName() const {
        return name;
    }
    
    Position Room::getPosition() const {
        return position;
    }
    void Room::setBooked(bool booked) {
        this->booked = booked;
    }
    

RoomBookingSystemPosition.cpph

    #include "RoomBookingSystem.h"
    
    #include <stdlib.h>
    #include <algorithm>
    #include <cfloat>
    #include <climits>
    #include <fstream>
    #include <iterator>
    #include <string.h>
    
    #include "Matchers.h"
    
    #define expand_it (*it)[0], atof((*it)[1].c_str()), atoi((*it)[2].c_str()), Position(atoi((*it)[3].c_str()), atoi((*it)[4].c_str()))
    #define print_separator cout<<string(100,'=')<<endl;
    #define sq(x) (x)*(x)
    using namespace std;
    
    #define ROOM_FILE_LOC "data/ROOM.txt"
    #define LAB_FILE_LOC "data/LAB.txt"
    #define LECTURE_HALL_FILE_LOC "data/LEC.txt"
    
    #define ROOM_BOOK_LOC "data/ROOM_BOOK.txt"
    #define LAB_BOOK_LOC "data/LAB_BOOK.txt"
    #define LECTURE_HALL_BOOK_LOC "data/LEC_BOOK.txt"
    
    vector<Room*> rooms;
    vector<Room*> labss;
    vector<Room*> lectureHalls;
    
    RoomBookingSystem::RoomBookingSystem() {
            vector<vector<string> > roomDetails = read(ROOM_FILE_LOC, 5);
            vector<vector<string> > labDetails = read(LAB_FILE_LOC, 6);
            vector<vector<string> > lectureHallDetails = read(LECTURE_HALL_FILE_LOC, 6);
            vector<vector<string> > roomBookDetails = read(ROOM_BOOK_LOC, 1);
            vector<vector<string> > labBookDetails = read(LAB_BOOK_LOC, 1);
            vector<vector<string> > lectureHallBookDetails = read(LECTURE_HALL_BOOK_LOC, 1);
            parse(roomDetails, ROOMS);
            parse(labDetails, LABS);
            parse(lectureHallDetails, LECTURE_HALLS);
            loadstate(roomBookDetails, ROOMS);
            loadstate(labBookDetails, LABS);
            loadstate(lectureHallBookDetails, LECTURE_HALLS);
    }
    
    RoomBookingSystem::~RoomBookingSystem() {
            saveRooms(rooms, ROOM_FILE_LOC, ROOM_BOOK_LOC);
            saveRooms(labss, LAB_FILE_LOC, LAB_BOOK_LOC);
            saveRooms(lectureHalls, LECTURE_HALL_FILE_LOC, LECTURE_HALL_BOOK_LOC);
    }
    vector<vector<string> > RoomBookingSystem::read(const char* pFilename, const int pColumns) {
            ifstream inputStream;
            vector<vector<string> > rooms_list;
            inputStream.open(pFilename);
            if (inputStream.is_open()) {
                    while (!inputStream.eof()) {
                            vector<string> roomDetails;
                            for (int i = 0; i < pColumns; i++) {
                                    string detail;
                                    inputStream >> detail;
                                    roomDetails.push_back(detail);
                            }
                            rooms_list.push_back(roomDetails);
                    }
            }
            inputStream.close();
            return rooms_list;
    }
    void RoomBookingSystem::saveRooms(vector<Room*>& vec, const char* loc, const char* bookloc) {
            ofstream outputStream;
            ofstream outputStream2;
            outputStream.open(loc);
            outputStream2.open(bookloc);
            string s = string(loc);
            if (outputStream.is_open() && outputStream2.is_open()) {
                    for (unsigned i = 0; i < vec.size(); i++) {
                            Room* r = vec[i];
                            outputStream << r->getName() << "\t" << fixed << setprecision(4) << r->getArea() << "\t" << r->getDoors() << "\t" << r->getPosition().x << "\t" << r->getPosition().y;
                            if (s.compare(LAB_FILE_LOC) == 0) {
                                    outputStream << "\t" << ((Lab*) r)->getComputers();
                            } else if (s.compare(LECTURE_HALL_FILE_LOC) == 0) {
                                    outputStream << "\t" << ((LectureHall*) r)->getChairs();
                            }
                            outputStream2 << ((vec[i]->isBooked()) ? "1" : "0");
                            if (i != vec.size() - 1) {
                                    outputStream << endl;
                                    outputStream2 << endl;
                            }
                    }
            }
            outputStream.close();
            outputStream2.close();
    }
    vector<Room*>* RoomBookingSystem::getList(int type) {
            switch (type) {
            case ROOMS:
                    return &rooms;
            case LABS:
                    return &labss;
            case LECTURE_HALLS:
                    return &lectureHalls;
            }
            return NULL;
    }
    vector<Room*>* RoomBookingSystem::getConstList(int type) const {
            switch (type) {
            case ROOMS:
                    return &rooms;
            case LABS:
                    return &labss;
            case LECTURE_HALLS:
                    return &lectureHalls;
            }
            return NULL;
    }
    
    void RoomBookingSystem::parse(vector<vector<string> > roomDetails, int type) {
            for (vector<vector<string> >::iterator it = roomDetails.begin(); it != roomDetails.end(); it++) {
                    switch (type) {
                    case ROOMS:
                            rooms.push_back(new Room(expand_it));
                            break;
                    case LABS:
                            labss.push_back(new Lab(expand_it, atoi((*it)[5].c_str())));
                            break;
                    case LECTURE_HALLS:
                            lectureHalls.push_back(new LectureHall(expand_it, atoi((*it)[5].c_str())));
                            break;
                    }
            }
    }
    void RoomBookingSystem::loadstate(vector<vector<string> > bookstatus, int type) {
            vector<Room*>* vec = getList(type);
            for (unsigned i = 0; i < vec->size(); i++) {
                    ((*vec)[i])->setBooked(atoi(bookstatus[i][0].c_str()) == 1);
            }
    }
    
    void bookRoom(Room &r) {
            r.book();
    }
    void unbookRoom(Room &r) {
            r.unbook();
    }
    void RoomBookingSystem::printAll() {
            print<Room>(rooms, "Rooms");
            print<Lab>(labss, "Labs");
            print<LectureHall>(lectureHalls, "Lecture Halls");
    }
    template<typename T> void RoomBookingSystem::print(vector<Room*>& vec, const string& pDescriptor) {
            print_separator
                    cout << "These are currently " << vec.size() << " " << pDescriptor << ": " << endl;
            for (unsigned i = 0; i < vec.size(); i++) {
                    ((T*) vec[i])->printRoom();
            }
            print_separator
    }
    void RoomBookingSystem::addRoom(const string& pName, const double pArea, const int pDoors, const int pX, const int pY) {
            rooms.push_back(new Room(pName, pArea, pDoors, Position(pX, pY)));
    }
    void RoomBookingSystem::addLab(const string& pName, const double pArea, const int pDoors, const int pX, int pY, int pComputers) {
            labss.push_back(new Lab(pName, pArea, pDoors, Position(pX, pY), pComputers));
    }
    void RoomBookingSystem::addLectureHall(const string& pName, const double pArea, const int pDoors, const int pX, const int pY, const int pChairs) {
            lectureHalls.push_back(new LectureHall(pName, pArea, pDoors, Position(pX, pY), pChairs));
    }
    Room* RoomBookingSystem::getRoom(const string& pName, int type) const {
            return getRoom(type, Matchers::MatchName(pName));
    }
    Room* RoomBookingSystem::getRoom(const int pX, const int pY, int type) const {
            return getRoom(type, Matchers::MatchPosition(pX, pY));
    }
    bool RoomBookingSystem::RoomComparator::operator()(const int i, const int j) {
            bool b1 = rooms[i]->isBooked();
            bool b2 = rooms[j]->isBooked();
            if (b1 && !b2) {
                    return i;
            } else if (!b1 && b2) {
                    return j;
            } else {
                    return rooms[i]->getArea() >= rooms[j]->getArea();
            }
    }
    vector<Room*> RoomBookingSystem::getMinimumRoomsOfArea(const int pRequiredArea) const {
            vector<int> roomIndices;
            vector<Room*> requiredRoom;
            for (unsigned i = 0; i < rooms.size(); i++)
                    roomIndices.push_back(i);
            sort(roomIndices.begin(), roomIndices.end(), RoomComparator());
            double area = 0;
            for (unsigned i = 0; i < roomIndices.size() && area < pRequiredArea && !rooms[roomIndices[i]]->isBooked(); i++) {
                    area += rooms[roomIndices[i]]->getArea();
                    requiredRoom.push_back(rooms[roomIndices[i]]);
            }
            if (area >= pRequiredArea)
                    return requiredRoom;
            else {
                    vector<Room*> emptyVec;
                    return emptyVec;
            }
    }
    LectureHall* RoomBookingSystem::getSmallestLectureHallByStudents(const int pRequiredChairs) const {
            double minArea = DBL_MAX;
            LectureHall* requiredHall = new LectureHall("", 0, 0, Position(0, 0), 0);
            for (vector<Room*>::iterator it = lectureHalls.begin(); it != lectureHalls.end(); it++) {
                    if (((LectureHall*) *it)->getChairs() >= pRequiredChairs && !(*it)->isBooked() && (*it)->getArea() < minArea) {
                            requiredHall = (LectureHall*) *it;
                            minArea = requiredHall->getArea();
                    }
            }
            return requiredHall;
    }
    Lab* RoomBookingSystem::getLabByLeastEquipmentDensity() const {
            double minDensity = DBL_MAX;
            Lab* requiredLab = new Lab("", 0, 0, Position(0, 0), 0);
            for (vector<Room*>::iterator it = labss.begin(); it != labss.end(); it++) {
                    if (((Lab*) *it)->getEquipmentDensity() < minDensity && !(*it)->isBooked()) {
                            requiredLab = (Lab*) *it;
                            minDensity = requiredLab->getEquipmentDensity();
                    }
            }
            return requiredLab;
    }
    
    Room* RoomBookingSystem::getNearestRoom(const int pX, const int pY) const {
            long minDistanceSquared = LONG_MAX;
            Room* requiredRoom = new Room("", 0, 0, Position(0, 0));
            for (vector<Room*>::iterator it = rooms.begin(); it != rooms.end(); it++) {
                    long distanceSquared = sq((*it)->getPosition().x - pX) + sq((*it)->getPosition().y - pY);
                    if (distanceSquared < minDistanceSquared && !(*it)->isBooked()) {
                            requiredRoom = *it;
                            minDistanceSquared = distanceSquared;
                    }
            }
            return requiredRoom;
    }
    
    template<class T> Room* RoomBookingSystem::getRoom(int type, const T matcher) const {
            vector<Room*>* vec = getConstList(type);
            vector<Room*>::iterator r = find_if(vec->begin(), vec->end(), matcher);
            return *r;
    }
    
    bool RoomBookingSystem::removeRoom(int type, Room* r) {
            vector<Room*>* vec = getList(type);
            if (r != *vec->end()) {
                    vec->erase(std::remove(vec->begin(), vec->end(), r), vec->end());
                    return true;
            } else
                    return false;
    }
#ifndef POSITION_H_
#define POSITION_H_

using namespace std;

class Position {

    public:
        int x;
        int y;
        Position(const int a, const int b);
};

#endif /* POSITION_H_ */

LectureHallPosition.hcpp

    #ifndef LECTUREHALL_H_
    #define LECTUREHALL_H_
    
    #include <string>
    
    #include "Room"Position.h"
    
    using namespace std;
    
    class LectureHallPosition: public Room {
    
            int chairs;
        public:
            LectureHallPosition(string pName, double pArea, int pDoors, Position pPositiona, int pChairsb);
            virtual void printRoom();:
            virtual ~LectureHallx(a) {
            }
            int, getChairsy(b) const;
            void setChairs(int chairs);{
    };
    
    #endif /* LECTUREHALL_H_ */

RoomMatchers.h

    #ifndef ROOM_H_MATCHERS_H_
    #define ROOM_H_MATCHERS_H_
    
    #include <string>
    #include <iomanip>
    
    #include "Position.h"
    
    #define expand_self "Name: "<<name<<"\tArea: "<<setprecision(4)<<area<<"\tDoors: "<<doors<<"\tPosition:#include ("<<position.x<<","<<position"Room.y<<")\tBooked: "<<((booked)?"Yes":"No")h"
    
    using namespace std;
    
    class RoomMatchers {
    
        protectedpublic:
    
           struct stringMatchName name;{
            double area;
           MatchName(const intstring& doors;s);
            Position position;
            bool booked;
 operator()(const Room* r) const;
        public:
    private:
            Room(string pName, double pArea, int pDoors,const Positionstring& pPosition);name;
            virtual void printRoom()};
            virtualstruct ~Room()MatchPosition {
            }
          MatchPosition(const int boolpX, operator==(const Room&int bpY);
            double getArea() const;
            bool isBookedoperator() const;
           (const voidRoom* book(r); const;
            void unbook();private:
            int getDoors() const;
            const string& getName()int const;x;
            Position getPosition() const;
  const int y;
            void setBooked(bool booked)};
    };
    
    #endif /* ROOM_H_MATCHERS_H_ */

RoomBookingSystemMatchers.hcpp

    #ifndef ROOMBOOKINGSYSTEM_H_
    #define ROOMBOOKINGSYSTEM_H_
    
    #include <iostream>
    #include <string>
    #include <vector>
    
    #include "Position.h"
    #include "Room.h"
    #include "Lab.h"
    #include "LectureHall"Matchers.h"
    
    class Lab;
    class LectureHall;
    
    using namespace std;
    
    #define ROOMS 1
    #define LABS 2
    #define LECTURE_HALLS 3
    
    //TODO make readme
    class RoomBookingSystem {
    
            void parse(vector<vector<string> > roomDetails, int type);
            void loadstate(vector<vector<string> > bookstatus, int type);
            vector<Room*>* getList(int type);
            vector<Room*>* getConstList(int type) const;
            template<typename T> Room* getRoomMatchers::MatchName::MatchName(int type, const Tstring& matchers) const;:
            template<typename T> void printname(vector<Room*>& vec, const string& pDescriptors);
            struct RoomComparator {
                    }
bool Matchers::MatchName::operator()(const int i, const intRoom* jr);
            };
            void saveRooms(vector<Room*>& vec, const char* loc, const char* bookloc);{
            vector<vector<string> >return readr->getName(const char* pFilename, const int pColumns);
    
        public:
    
           == RoomBookingSystem();name;
            ~RoomBookingSystem();}
            void addRoomMatchers::MatchPosition::MatchPosition(const string& pName, const double pArea, const int pDoors, const int pX, const int pY);
            void addLab(const string& pName, const double pArea, const int pDoors, const int pX, const int pY, int pComputers);:
            void addLectureHallx(const string& pName, const double pArea, const int pDoors, const int pX, const int pY, const int pChairs);
            bool removeRoom(int type, Room* r);
            Room* getRoom(const string& pName, int type) const;
            Room* getRoomy(const int pX, const int pY, int type) const;{
            vector<Room*>}
bool getMinimumRoomsOfAreaMatchers::MatchPosition::operator(const int pRequiredArea) const;
            LectureHall* getSmallestLectureHallByStudents(const intRoom* pRequiredChairsr) const;
            Lab* getLabByLeastEquipmentDensity()const const;{
            Room*return getNearestRoomr->getPosition(const int pX, const int pY) const;
         .x == x void&& printAllr->getPosition();
  .y == y;
    };
    
    #endif /* ROOMBOOKINGSYSTEM_H_ */

ClientLectureHall.h

    #ifndef CLIENT_H_LECTUREHALL_H_
    #define CLIENT_H_LECTUREHALL_H_
    
   #include <string>

#include "RoomBookingSystem"Room.h"
    
    using namespace std;
    
    class Client {
    
            RoomBookingSystem* rbs;
    
          LectureHall: public intRoom getRoomType();{
            int getRoomByWhat();
            Room* getRoom(int type);
            template<typename T> T input(const string& s) const;
    chairs;
        public:
    
            Client();
            ~ClientLectureHall();
    string pName, double pArea, int pDoors, Position pPosition, voidint printChoices(pChairs);
           virtual void addRoomprintRoom();
            voidvirtual getMinimumRoomsofArea~LectureHall();
            void printRoom();{
            void getSmallestLectureHallForGivenStudents();}
            voidint getLeastEquipmentDensityLabgetChairs();
            void getNearestRoom();const;
            void removeRoomsetChairs();
            voidint bookUnbook(chairs);
    };
    
    #endif /* CLIENT_H_LECTUREHALL_H_ */

MatchersLectureHall.cpp

    #include "Matchers"LectureHall.h"
    
  #include <iostream>

#include "Position.h"

using namespace std;
    Matchers::MatchName
LectureHall::MatchNameLectureHall(const string& s) :
   string pName, double pArea, int pDoors, Position pPosition, int name(spChairs) {:
    }
    bool Matchers::MatchName::operator()Room(constpName, Room*pArea, r)pDoors, constpPosition) {
        return r->getName()chairs === name;pChairs;
    }
   
void Matchers::MatchPositionLectureHall::MatchPositionprintRoom(const int pX, const int pY) :{
    cout << expand_self << "\tChairs: "  << x(pX),chairs y(pY)<< {endl;
    }
    bool
int Matchers::MatchPositionLectureHall::operator()getChairs(const Room* r) const {
        return r->getPosition().x == x &&chairs;
}

void r->getPositionLectureHall::setChairs().yint ==chairs) y;{
    }
  this->chairs = chairs;
}

LectureHallLab.cpph

  #ifndef LAB_H_
#define LAB_H_

#include "LectureHall"Room.h"
    
   using #includenamespace <iostream>std;

class Lab: public Room {

    #include "Position.h"
   int computers;
   
  using namespace std;public:

    
     LectureHall::LectureHallLab(string pName, double pArea, int pDoors, Position pPosition, int pChairspComputers) :;
          virtual void RoomprintRoom(pName, pArea, pDoors, pPosition) {
        chairs = pChairs;
    };
    
     voidvirtual LectureHall::printRoom~Lab() {
        cout << expand_self << "\tChairs: "  << chairs << endl;
    }
    
     int LectureHall::getChairsgetComputers() const {
        return chairs;
    }const;
    
     void LectureHall::setChairssetComputers(int chairscomputers) {;
        this->chairs =double chairs;getEquipmentDensity();
    };
 
#endif /* LAB_H_ */

ClientLab.cpp

    #include "Client.h"
    
    #include <cstdlib>
    #include <iostream>
    #include <iterator>
    #include <string>
    #include <vector>
    
    #include "Lab.h"
    #include "LectureHall.h"
    
    #define NAME 1
    #define POSITION 2
    
    #define BOOK 1
    #define UNBOOK 2
    
    #define CIN_IGNORE_MAX 512
    
    using namespace std;
    
    void Client::printChoices() {
        cout << "Press the corresponding keys for these operations:" << endl;
        cout << "1. Add Room/Lab/Lecture Hall." << endl;
        cout << "2. Remove Room/Lab/Lecture Hall." << endl;
        cout << "3. Book/Unbook a Room/Lab/Lecture Hall." << endl;
        cout << "4. Get minimum number of rooms to accommodate given number of persons." << endl;
        cout << "5. Get smallest lecture hall to accommodate given number of students." << endl;
        cout << "6. Get lab with least equipment density or change lab equipment quantities." << endl;
        cout << "7. Find a room nearest to a location." << endl;
        cout << "8. Print Room/Lab/Lecture Hall details." << endl;
        cout << "9. Exit." << endl;
    }
    Client::Client() {
        rbs = new RoomBookingSystem();
    }
    Client::~Client() {
        delete rbs;
    }
    int Client::getRoomType() {
        cout << ROOMS << ". Room." << endl;
        cout << LABS << ". Lab." << endl;
        cout << LECTURE_HALLS << ". Lecture Hall." << endl;
        int choice = -1;
        while ((choice = input<int>("Enter Choice:")) < ROOMS || choice > LECTURE_HALLS)
            cout << "Please enter valid option." << endl;
        return choice;
    }
    
    int Client::getRoomByWhat() {
        cout << "Choose:" << endl;
        cout << NAME << ". By Name." << endl;
        cout << POSITION << ". By Position." << endl;
        int choice = -1;
        while ((choice = input<int>("Enter Choice:")) < NAME || choice > POSITION)
            cout << "Please enter valid option." << endl;
        return choice;
    }
    
    void Client::addRoom() {
        int roomType = getRoomType();
        string name = input<string>("Enter Name: ");
        double area = input<double>("Enter Area: ");
        int doors = input<int>("Enter Doors: ");
        int x = input<int>("Enter Position X: ");
        int y = input<int>("Enter Position Y: ");
        switch (roomType) {
            case ROOMS:
                rbs->addRoom(name, area, doors, x, y);
                cout << "Room Added." << endl;
                break;
    
            case LABS: {
                int computers = input<int>("Enter Computers: ");
                rbs->addLab(name, area, doors, x, y, computers);
            }
                cout << "Lab Added." << endl;
                break;
            case LECTURE_HALLS: {
                int chairs = input<int>("Enter Chairs: ");
                rbs->addLectureHall(name, area, doors, x, y, chairs);
            }
                cout << "Lecture Hall Added." << endl;
                break;
        }
    }
    
    void Client::removeRoom() {
        int roomType = getRoomType();
        Room* r = getRoom(roomType);
        if (rbs->removeRoom(roomType, r))
            cout << "Room removed successfully." << endl;
        else
            cout << "Room not removed." << endl;
    }
    
    Room* Client::getRoom(int type) {
        switch (getRoomByWhat()) {
            case NAME: {
                string name = input<string>("Enter Name.");
                return rbs->getRoom(name, type);
            }
            case POSITION: {
                int x = input<int>("Enter Position X.");
                int y = input<int>("Enter Position Y.");
                return rbs->getRoom(x, y, type);
            }
        }
        return NULL;
    }
    void Client::bookUnbook() {
        Room* r = getRoom(getRoomType());
        cout << "This room is " << ((r->isBooked()) ? "booked" : "un-booked") << ". Do you want to " << ((r->isBooked()) ? "un-book" : "book") << " it?" << endl;
        char toggleBook = 'z';
        while (toggleBook != 'y' && toggleBook != 'n') {
            cout << "Enter.(y/n)" << endl;
            cin >> toggleBook;
        }
        if (toggleBook == 'y') {
            if (!r->isBooked()) {
                r->book();
            } else {
                r->unbook();
            }
            cout << "Room successfully " << ((r->isBooked()) ? "booked." : "un-booked.") << endl;
        } else {
            cout << "OK." << endl;
        }
    }
    void Client::getMinimumRoomsofArea() {
        double area;
        while ((area = input<double>("Enter Area(>0): ")) <= 0)
            ;
        vector<Room*> v = rbs->getMinimumRoomsOfArea(area);
        if (v.size() == 0) {
            cout << "Not Enough Rooms." << endl;
            return;
        }
        cout << "You may use these " << v.size() << " un-booked rooms." << endl;
        for (vector<Room*>::iterator it = v.begin(); it != v.end(); it++)
            (*it)->printRoom();
    }
    void Client::printRoom() {
        int choice = -1;
        while ((choice = input<int>("Enter 1 for specific Room/Lab/Lecture Hall and 2 for all.")) < 1 || choice > 2)
            ;
        switch (choice) {
            case 1: {
                int type = getRoomType();
                Room* r = getRoom(type);
                if (type == LABS) {
                    ((Lab*) r)->printRoom();
                } else if (type == LECTURE_HALLS) {
                    ((LectureHall*) r)->printRoom();
                } else {
                    r->printRoom();
                }
                break;
            }
            case 2:
                rbs->printAll();
                break;
        }
    }
    
    void Client::getSmallestLectureHallForGivenStudents() {
        int students;
        while ((students = input<int>("Enter Students (>0): ")) <= 0)
            ;
        LectureHall* r = rbs->getSmallestLectureHallByStudents(students);
        if (r->getChairs() > 0) {
            cout << "The required Lecture Hall is:" << endl;
            r->printRoom();
        } else {
            cout << "No such Lecture Hall." << endl;
        }
    }
    void Client::getLeastEquipmentDensityLab() {
        int choice = -1;
        while ((choice = input<int>("Enter 1 to get the lab with least equipment density and 2 to increase equipment density of a lab.")) < 1 || choice > 2)
            ;
        switch (choice) {
            case 1: {
                Room* r = rbs->getLabByLeastEquipmentDensity();
                if (r->getArea() > 0) {
                    r->printRoom();
                } else {
                    cout << "No such Labs." << endl;
                }
            }
                break;
            case 2: {
                Lab* l = (Lab*) getRoom(LABS);
                cout << "The selected lab is:" << endl;
                l->printRoom();
                int newEqu = -1;
                while ((newEqu = input<int>("Enter the new Lab Equipments.")) < 0)
                    ;
                l->setComputers(newEqu);
                break;
            }
        }
    }
    void Client::getNearestRoom() {
        int x = input<int>("Enter Position X:"), y = input<int>("Enter Position Y:");
        Room* r = rbs->getNearestRoom(x, y);
        if (r->getArea() > 0) {
            r->printRoom();
        } else {
            cout << "No such Labs." << endl;
        }
    }
    
    template<typename T> T Client::input(const string& s) const {
        T x;
        do {
            cout << s << endl;
            cin >> x;
            if (!cin) {
                cout << "Please enter valid option." << endl;
                cin.clear();
                cin.ignore(CIN_IGNORE_MAX, '\n');
            } else
                break;
        } while (true);
        return x;
    }
    
    int main(int argc, char **argv) {
        Client* client = new Client();
        while (true) {
            client->printChoices();
            int choice;
            while (!(cin >> choice) || choice < 1 || choice > 9) {
                cout << "Please choose from 1-9" << endl;
                cin.clear();
                cin.ignore(CIN_IGNORE_MAX, '\n');
            }
            switch (choice) {
                case 1:
                    client->addRoom();
                    break;
                case 2:
                    client->removeRoom();
                    break;
                case 3:
                    client->bookUnbook();
                    break;
                case 4:
                    client->getMinimumRoomsofArea();
                    break;
                case 5:
                    client->getSmallestLectureHallForGivenStudents();
                    break;
                case 6:
                    client->getLeastEquipmentDensityLab();
                    break;
                case 7:
                    client->getNearestRoom();
                    break;
                case 8:
                    client->printRoom();
                    break;
                case 9:
                    delete client;
                    cout << "Exited." << endl;
                    exit(0);
                    break;
            }
            char cont = 'z';
            while (cont != 'y' && cont != 'n') {
                cout << "Continue?(y/n)" << endl;
                cin >> cont;
            }
            if (cont == 'n') {
                cout << "Exited." << endl;
                delete client;
                exit(0);
                break;
            }
    
        }
    }
#include "Lab.h"

#include <iostream>
#include <string>

#include "Position.h"

using namespace std;
//=========================================================================
// CONSTRUCTOR
//=========================================================================
Lab::Lab(string pName, double pArea, int pDoors, Position pPosition, int pComputers) :
        Room(pName, pArea, pDoors, pPosition) {
    computers = pComputers;
}
void Lab::printRoom() {
    cout << expand_self << "\tComputers: " << computers << endl;
}
int Lab::getComputers() const {
    return computers;
}

void Lab::setComputers(int computers) {
    this->computers = computers;
}

double Lab::getEquipmentDensity() {
    return computers / area;
}

PositionClient.h

#ifndef CLIENT_H_
#define CLIENT_H_

#include "RoomBookingSystem.h"

using #ifndefnamespace POSITION_H_std;

class Client {

  #define POSITION_H_
     RoomBookingSystem* rbs;

    using namespace std;  int getRoomType();
        int getRoomByWhat();
    class Position {
  Room* getRoom(int type);
        template<typename T> T input(const string& s) const;

    public: 

        Client();
    int x;   ~Client();
        void printChoices();
   int y;    void addRoom();
        void getMinimumRoomsofArea();
   Position     void printRoom(const);
 int a, const int b   void getSmallestLectureHallForGivenStudents();
    }    void getLeastEquipmentDensityLab();
        void getNearestRoom();
        void removeRoom();
        void bookUnbook();
};

#endif /* POSITION_H_CLIENT_H_ */

LabClient.hcpp

#include "Client.h"

#include <cstdlib>
#include <iostream>
#include #ifndef<iterator>
#include LAB_H_<string>
#include <vector>

#include "Lab.h"
#include "LectureHall.h"

#define NAME 1
#define POSITION 2

#define LAB_H_BOOK 1
#define UNBOOK 2

#define CIN_IGNORE_MAX 512

using namespace std;

void Client::printChoices() #include{
 "Room   cout << "Press the corresponding keys for these operations:" << endl;
    cout << "1.h" Add Room/Lab/Lecture Hall." << endl;
    cout << "2. Remove Room/Lab/Lecture Hall." << endl;
    usingcout namespace<< std;"3. Book/Unbook a Room/Lab/Lecture Hall." << endl;
    cout << "4. Get minimum number of rooms to accommodate given number of persons." << endl;
    classcout << "5. Get smallest lecture hall to accommodate given number of students." << endl;
    cout << "6. Get lab with least equipment density or change lab equipment quantities." << endl;
    cout << "7. Find a room nearest to a location." << endl;
    cout << "8. Print Room/Lab/Lecture Hall details." << endl;
    cout << "9. Exit." << endl;
}
Client::Client() public{
 Room   rbs = new RoomBookingSystem();
}
Client::~Client() {
    delete rbs;
}
int Client::getRoomType() {
    cout << ROOMS << ". Room." << endl;
    cout << LABS << ". Lab." << endl;
    cout << LECTURE_HALLS << ". Lecture Hall." << endl;
    int computers;choice = -1;
    while ((choice = input<int>("Enter Choice:")) < ROOMS || choice > LECTURE_HALLS)
        publiccout << "Please enter valid option." << endl;
    return choice;
}

int Client::getRoomByWhat() {
    cout << "Choose:" << endl;
    cout << NAME << ". By Name." << Labendl;
    cout << POSITION << ". By Position." << endl;
    int choice = -1;
    while ((choice = input<int>("Enter Choice:")) < NAME || choice > POSITION)
        cout << "Please enter valid option." << endl;
    return choice;
}

void Client::addRoom() {
    int roomType = getRoomType();
    string pName,name = input<string>("Enter Name: ");
    double pAreaarea = input<double>("Enter Area: ");
    int doors = input<int>("Enter Doors: ");
    int x = input<int>("Enter Position X: ");
    int y = input<int>("Enter Position Y: ");
    switch (roomType) {
        case ROOMS:
            rbs->addRoom(name, area, doors, x, y);
            cout << "Room Added." << endl;
            break;

        case LABS: {
            int pDoorscomputers = input<int>("Enter Computers: ");
            rbs->addLab(name, Positionarea, pPositiondoors, x, y, computers);
        }
            cout << "Lab Added." << endl;
            break;
        case LECTURE_HALLS: {
            int pComputerschairs = input<int>("Enter Chairs: ");
            virtualrbs->addLectureHall(name, area, doors, x, y, chairs);
        }
            cout << "Lecture Hall Added." << endl;
            break;
    }
}

void Client::removeRoom() {
    int roomType = getRoomType();
    Room* r = getRoom(roomType);
    if (rbs->removeRoom(roomType, r))
        cout << "Room removed successfully." << endl;
    else
        cout << "Room not removed." << endl;
}

Room* Client::getRoom(int type) {
    switch (getRoomByWhat()) {
        case NAME: {
            string name = input<string>("Enter Name.");
            return rbs->getRoom(name, type);
        }
        case POSITION: {
            int x = input<int>("Enter Position X.");
            int y = input<int>("Enter Position Y.");
            return rbs->getRoom(x, y, type);
        }
    }
    return NULL;
}
void Client::bookUnbook() {
    Room* r = getRoom(getRoomType());
    cout << "This room is " << ((r->isBooked()) ? "booked" : "un-booked") << ". Do you want to " << ((r->isBooked()) ? "un-book" : "book") << " it?" << endl;
    char toggleBook = 'z';
    while (toggleBook != 'y' && toggleBook != 'n') {
        cout << "Enter.(y/n)" << endl;
        cin >> toggleBook;
    }
    if (toggleBook == 'y') {
        if (!r->isBooked()) {
            r->book();
        } else {
            r->unbook();
        }
        cout << "Room successfully " << ((r->isBooked()) ? "booked." : "un-booked.") << endl;
    } else {
        cout << "OK." << endl;
    }
}
void Client::getMinimumRoomsofArea() {
    double area;
    while ((area = input<double>("Enter Area(>0): ")) <= 0)
        ;
    vector<Room*> v = rbs->getMinimumRoomsOfArea(area);
    if (v.size() == 0) {
        cout << "Not Enough Rooms." << endl;
        return;
    }
    cout << "You may use these " << v.size() << " un-booked rooms." << endl;
    for (vector<Room*>::iterator it = v.begin(); it != v.end(); it++)
        (*it)->printRoom();
}
void Client::printRoom() {
    int choice = -1;
    while ((choice = input<int>("Enter 1 for specific Room/Lab/Lecture Hall and 2 for all.")) < 1 || choice > 2)
        ;
    switch (choice) {
        case 1: {
  virtual ~Lab         int type = getRoomType();
            Room* r = getRoom(type);
            if (type == LABS) {
                ((Lab*) r)->printRoom();
            } else if (type == LECTURE_HALLS) {
                ((LectureHall*) r)->printRoom();
            } else {
                r->printRoom();
            }
            break;
        }
        case 2:
            rbs->printAll();
            break;
    }
}

void Client::getSmallestLectureHallForGivenStudents() {
    int getComputersstudents;
    while ((students = input<int>("Enter Students (>0): const;")) <= 0)
        ;
    LectureHall* r = rbs->getSmallestLectureHallByStudents(students);
    if (r->getChairs() > 0) {
        cout << "The required Lecture Hall is:" << endl;
        r->printRoom();
    } else {
        cout << "No such Lecture Hall." << endl;
    }
}
void setComputersClient::getLeastEquipmentDensityLab() {
    int computerschoice = -1;
    while ((choice = input<int>("Enter 1 to get the lab with least equipment density and 2 to increase equipment density of a lab.")) < 1 || choice > 2)
        ;
    switch (choice) {
      double getEquipmentDensity case 1: {
            Room* r = rbs->getLabByLeastEquipmentDensity();
            if (r->getArea() > 0) {
                r->printRoom();
            } else {
                cout << "No such Labs." << endl;
            }
        }
            break;
        case 2: {
            Lab* l = (Lab*) getRoom(LABS);
            cout << "The selected lab is:" << endl;
    #endif /* LAB_H_ *     l->printRoom();
            int newEqu = -1;
            while ((newEqu = input<int>("Enter the new Lab Equipments.")) < 0)
                ;
            l->setComputers(newEqu);
            break;
        }
    }
}
void Client::getNearestRoom() {
    int x = input<int>("Enter Position X:"), y = input<int>("Enter Position Y:");
    Room* r = rbs->getNearestRoom(x, y);
    if (r->getArea() > 0) {
        r->printRoom();
    } else {
        cout << "No such Labs." << endl;
    }
}

template<typename T> T Client::input(const string& s) const {
    T x;
    do {
        cout << s << endl;
        cin >> x;
        if (!cin) {
            cout << "Please enter valid option." << endl;
            cin.clear();
            cin.ignore(CIN_IGNORE_MAX, '\n');
        } else
            break;
    } while (true);
    return x;
}

int main(int argc, char **argv) {
    Client* client = new Client();
    while (true) {
        client->printChoices();
        int choice;
        while (!(cin >> choice) || choice < 1 || choice > 9) {
            cout << "Please choose from 1-9" << endl;
            cin.clear();
            cin.ignore(CIN_IGNORE_MAX, '\n');
        }
        switch (choice) {
            case 1:
                client->addRoom();
                break;
            case 2:
                client->removeRoom();
                break;
            case 3:
                client->bookUnbook();
                break;
            case 4:
                client->getMinimumRoomsofArea();
                break;
            case 5:
                client->getSmallestLectureHallForGivenStudents();
                break;
            case 6:
                client->getLeastEquipmentDensityLab();
                break;
            case 7:
                client->getNearestRoom();
                break;
            case 8:
                client->printRoom();
                break;
            case 9:
                delete client;
                cout << "Exited." << endl;
                exit(0);
                break;
        }
        char cont = 'z';
        while (cont != 'y' && cont != 'n') {
            cout << "Continue?(y/n)" << endl;
            cin >> cont;
        }
        if (cont == 'n') {
            cout << "Exited." << endl;
            delete client;
            exit(0);
            break;
        }

    }
}

Lab.cpp

    #include "Lab.h"
    
    #include <iostream>
    #include <string>
    
    #include "Position.h"
    
    using namespace std;
    //=========================================================================
    // CONSTRUCTOR
    //=========================================================================
    Lab::Lab(string pName, double pArea, int pDoors, Position pPosition, int pComputers) :
            Room(pName, pArea, pDoors, pPosition) {
        computers = pComputers;
    }
    void Lab::printRoom() {
        cout << expand_self << "\tComputers: " << computers << endl;
    }
    int Lab::getComputers() const {
        return computers;
    }
    
     void Lab::setComputers(int computers) {
        this->computers = computers;
    }
    
    double Lab::getEquipmentDensity() {
        return computers / area;
    }

Matchers.h

    #ifndef MATCHERS_H_
    #define MATCHERS_H_
    
    #include <string>
    
    #include "Position.h"
    #include "Room.h"
    
    using namespace std;
    
    class Matchers {
        public:
            struct MatchName {
                    MatchName(const string& s);
                    bool operator()(const Room* r) const;
                private:
                    const string& name;
            };
            struct MatchPosition {
                    MatchPosition(const int pX, const int pY);
                    bool operator()(const Room* r) const;
                private:
                    const int x;
                    const int y;
            };
    };
    
    #endif /* MATCHERS_H_ */

Position.cpp

    #include "Position.h"
    
     using namespace std;
    Position::Position(int a, int b) :
            x(a), y(b) {
    }
    
    #include "Room.h"
    
    #include <iostream>
    
    using namespace std;
    Room::Room(string pName, double pArea, int pDoors, Position pPosition) :
            name(pName), area(pArea), doors(pDoors), position(pPosition), booked(false) {
    }
    void Room::printRoom() {
        cout << expand_self << endl;
    }
    bool Room::operator==(const Room& r) {
        return name == r.name && position.x == r.position.x && position.y == r.position.y;
    }
    double Room::getArea() const {
        return area;
    }
    
    bool Room::isBooked() const {
        return booked;
    }
    
    void Room::book() {
        this->booked = true;
    }
    void Room::unbook() {
        this->booked = false;
    }
    
    int Room::getDoors() const {
        return doors;
    }
    
    const string& Room::getName() const {
        return name;
    }
    
    Position Room::getPosition() const {
        return position;
    }
    void Room::setBooked(bool booked) {
        this->booked = booked;
    }
    

RoomBookingSystem.cpp

    #include "RoomBookingSystem.h"
    
    #include <stdlib.h>
    #include <algorithm>
    #include <cfloat>
    #include <climits>
    #include <fstream>
    #include <iterator>
    #include <string.h>
    
    #include "Matchers.h"
    
    #define expand_it (*it)[0], atof((*it)[1].c_str()), atoi((*it)[2].c_str()), Position(atoi((*it)[3].c_str()), atoi((*it)[4].c_str()))
    #define print_separator cout<<string(100,'=')<<endl;
    #define sq(x) (x)*(x)
    using namespace std;
    
    #define ROOM_FILE_LOC "data/ROOM.txt"
    #define LAB_FILE_LOC "data/LAB.txt"
    #define LECTURE_HALL_FILE_LOC "data/LEC.txt"
    
    #define ROOM_BOOK_LOC "data/ROOM_BOOK.txt"
    #define LAB_BOOK_LOC "data/LAB_BOOK.txt"
    #define LECTURE_HALL_BOOK_LOC "data/LEC_BOOK.txt"
    
    vector<Room*> rooms;
    vector<Room*> labss;
    vector<Room*> lectureHalls;
    
    RoomBookingSystem::RoomBookingSystem() {
            vector<vector<string> > roomDetails = read(ROOM_FILE_LOC, 5);
            vector<vector<string> > labDetails = read(LAB_FILE_LOC, 6);
            vector<vector<string> > lectureHallDetails = read(LECTURE_HALL_FILE_LOC, 6);
            vector<vector<string> > roomBookDetails = read(ROOM_BOOK_LOC, 1);
            vector<vector<string> > labBookDetails = read(LAB_BOOK_LOC, 1);
            vector<vector<string> > lectureHallBookDetails = read(LECTURE_HALL_BOOK_LOC, 1);
            parse(roomDetails, ROOMS);
            parse(labDetails, LABS);
            parse(lectureHallDetails, LECTURE_HALLS);
            loadstate(roomBookDetails, ROOMS);
            loadstate(labBookDetails, LABS);
            loadstate(lectureHallBookDetails, LECTURE_HALLS);
    }
    
    RoomBookingSystem::~RoomBookingSystem() {
            saveRooms(rooms, ROOM_FILE_LOC, ROOM_BOOK_LOC);
            saveRooms(labss, LAB_FILE_LOC, LAB_BOOK_LOC);
            saveRooms(lectureHalls, LECTURE_HALL_FILE_LOC, LECTURE_HALL_BOOK_LOC);
    }
    vector<vector<string> > RoomBookingSystem::read(const char* pFilename, const int pColumns) {
            ifstream inputStream;
            vector<vector<string> > rooms_list;
            inputStream.open(pFilename);
            if (inputStream.is_open()) {
                    while (!inputStream.eof()) {
                            vector<string> roomDetails;
                            for (int i = 0; i < pColumns; i++) {
                                    string detail;
                                    inputStream >> detail;
                                    roomDetails.push_back(detail);
                            }
                            rooms_list.push_back(roomDetails);
                    }
            }
            inputStream.close();
            return rooms_list;
    }
    void RoomBookingSystem::saveRooms(vector<Room*>& vec, const char* loc, const char* bookloc) {
            ofstream outputStream;
            ofstream outputStream2;
            outputStream.open(loc);
            outputStream2.open(bookloc);
            string s = string(loc);
            if (outputStream.is_open() && outputStream2.is_open()) {
                    for (unsigned i = 0; i < vec.size(); i++) {
                            Room* r = vec[i];
                            outputStream << r->getName() << "\t" << fixed << setprecision(4) << r->getArea() << "\t" << r->getDoors() << "\t" << r->getPosition().x << "\t" << r->getPosition().y;
                            if (s.compare(LAB_FILE_LOC) == 0) {
                                    outputStream << "\t" << ((Lab*) r)->getComputers();
                            } else if (s.compare(LECTURE_HALL_FILE_LOC) == 0) {
                                    outputStream << "\t" << ((LectureHall*) r)->getChairs();
                            }
                            outputStream2 << ((vec[i]->isBooked()) ? "1" : "0");
                            if (i != vec.size() - 1) {
                                    outputStream << endl;
                                    outputStream2 << endl;
                            }
                    }
            }
            outputStream.close();
            outputStream2.close();
    }
    vector<Room*>* RoomBookingSystem::getList(int type) {
            switch (type) {
            case ROOMS:
                    return &rooms;
            case LABS:
                    return &labss;
            case LECTURE_HALLS:
                    return &lectureHalls;
            }
            return NULL;
    }
    vector<Room*>* RoomBookingSystem::getConstList(int type) const {
            switch (type) {
            case ROOMS:
                    return &rooms;
            case LABS:
                    return &labss;
            case LECTURE_HALLS:
                    return &lectureHalls;
            }
            return NULL;
    }
    
    void RoomBookingSystem::parse(vector<vector<string> > roomDetails, int type) {
            for (vector<vector<string> >::iterator it = roomDetails.begin(); it != roomDetails.end(); it++) {
                    switch (type) {
                    case ROOMS:
                            rooms.push_back(new Room(expand_it));
                            break;
                    case LABS:
                            labss.push_back(new Lab(expand_it, atoi((*it)[5].c_str())));
                            break;
                    case LECTURE_HALLS:
                            lectureHalls.push_back(new LectureHall(expand_it, atoi((*it)[5].c_str())));
                            break;
                    }
            }
    }
    void RoomBookingSystem::loadstate(vector<vector<string> > bookstatus, int type) {
            vector<Room*>* vec = getList(type);
            for (unsigned i = 0; i < vec->size(); i++) {
                    ((*vec)[i])->setBooked(atoi(bookstatus[i][0].c_str()) == 1);
            }
    }
    
    void bookRoom(Room &r) {
            r.book();
    }
    void unbookRoom(Room &r) {
            r.unbook();
    }
    void RoomBookingSystem::printAll() {
            print<Room>(rooms, "Rooms");
            print<Lab>(labss, "Labs");
            print<LectureHall>(lectureHalls, "Lecture Halls");
    }
    template<typename T> void RoomBookingSystem::print(vector<Room*>& vec, const string& pDescriptor) {
            print_separator
                    cout << "These are currently " << vec.size() << " " << pDescriptor << ": " << endl;
            for (unsigned i = 0; i < vec.size(); i++) {
                    ((T*) vec[i])->printRoom();
            }
            print_separator
    }
    void RoomBookingSystem::addRoom(const string& pName, const double pArea, const int pDoors, const int pX, const int pY) {
            rooms.push_back(new Room(pName, pArea, pDoors, Position(pX, pY)));
    }
    void RoomBookingSystem::addLab(const string& pName, const double pArea, const int pDoors, const int pX, int pY, int pComputers) {
            labss.push_back(new Lab(pName, pArea, pDoors, Position(pX, pY), pComputers));
    }
    void RoomBookingSystem::addLectureHall(const string& pName, const double pArea, const int pDoors, const int pX, const int pY, const int pChairs) {
            lectureHalls.push_back(new LectureHall(pName, pArea, pDoors, Position(pX, pY), pChairs));
    }
    Room* RoomBookingSystem::getRoom(const string& pName, int type) const {
            return getRoom(type, Matchers::MatchName(pName));
    }
    Room* RoomBookingSystem::getRoom(const int pX, const int pY, int type) const {
            return getRoom(type, Matchers::MatchPosition(pX, pY));
    }
    bool RoomBookingSystem::RoomComparator::operator()(const int i, const int j) {
            bool b1 = rooms[i]->isBooked();
            bool b2 = rooms[j]->isBooked();
            if (b1 && !b2) {
                    return i;
            } else if (!b1 && b2) {
                    return j;
            } else {
                    return rooms[i]->getArea() >= rooms[j]->getArea();
            }
    }
    vector<Room*> RoomBookingSystem::getMinimumRoomsOfArea(const int pRequiredArea) const {
            vector<int> roomIndices;
            vector<Room*> requiredRoom;
            for (unsigned i = 0; i < rooms.size(); i++)
                    roomIndices.push_back(i);
            sort(roomIndices.begin(), roomIndices.end(), RoomComparator());
            double area = 0;
            for (unsigned i = 0; i < roomIndices.size() && area < pRequiredArea && !rooms[roomIndices[i]]->isBooked(); i++) {
                    area += rooms[roomIndices[i]]->getArea();
                    requiredRoom.push_back(rooms[roomIndices[i]]);
            }
            if (area >= pRequiredArea)
                    return requiredRoom;
            else {
                    vector<Room*> emptyVec;
                    return emptyVec;
            }
    }
    LectureHall* RoomBookingSystem::getSmallestLectureHallByStudents(const int pRequiredChairs) const {
            double minArea = DBL_MAX;
            LectureHall* requiredHall = new LectureHall("", 0, 0, Position(0, 0), 0);
            for (vector<Room*>::iterator it = lectureHalls.begin(); it != lectureHalls.end(); it++) {
                    if (((LectureHall*) *it)->getChairs() >= pRequiredChairs && !(*it)->isBooked() && (*it)->getArea() < minArea) {
                            requiredHall = (LectureHall*) *it;
                            minArea = requiredHall->getArea();
                    }
            }
            return requiredHall;
    }
    Lab* RoomBookingSystem::getLabByLeastEquipmentDensity() const {
            double minDensity = DBL_MAX;
            Lab* requiredLab = new Lab("", 0, 0, Position(0, 0), 0);
            for (vector<Room*>::iterator it = labss.begin(); it != labss.end(); it++) {
                    if (((Lab*) *it)->getEquipmentDensity() < minDensity && !(*it)->isBooked()) {
                            requiredLab = (Lab*) *it;
                            minDensity = requiredLab->getEquipmentDensity();
                    }
            }
            return requiredLab;
    }
    
    Room* RoomBookingSystem::getNearestRoom(const int pX, const int pY) const {
            long minDistanceSquared = LONG_MAX;
            Room* requiredRoom = new Room("", 0, 0, Position(0, 0));
            for (vector<Room*>::iterator it = rooms.begin(); it != rooms.end(); it++) {
                    long distanceSquared = sq((*it)->getPosition().x - pX) + sq((*it)->getPosition().y - pY);
                    if (distanceSquared < minDistanceSquared && !(*it)->isBooked()) {
                            requiredRoom = *it;
                            minDistanceSquared = distanceSquared;
                    }
            }
            return requiredRoom;
    }
    
    template<class T> Room* RoomBookingSystem::getRoom(int type, const T matcher) const {
            vector<Room*>* vec = getConstList(type);
            vector<Room*>::iterator r = find_if(vec->begin(), vec->end(), matcher);
            return *r;
    }
    
    bool RoomBookingSystem::removeRoom(int type, Room* r) {
            vector<Room*>* vec = getList(type);
            if (r != *vec->end()) {
                    vec->erase(std::remove(vec->begin(), vec->end(), r), vec->end());
                    return true;
            } else
                    return false;
    }

LectureHall.h

    #ifndef LECTUREHALL_H_
    #define LECTUREHALL_H_
    
    #include <string>
    
    #include "Room.h"
    
    using namespace std;
    
    class LectureHall: public Room {
    
            int chairs;
        public:
            LectureHall(string pName, double pArea, int pDoors, Position pPosition, int pChairs);
            virtual void printRoom();
            virtual ~LectureHall() {
            }
            int getChairs() const;
            void setChairs(int chairs);
    };
    
    #endif /* LECTUREHALL_H_ */

Room.h

    #ifndef ROOM_H_
    #define ROOM_H_
    
    #include <string>
    #include <iomanip>
    
    #include "Position.h"
    
    #define expand_self "Name: "<<name<<"\tArea: "<<setprecision(4)<<area<<"\tDoors: "<<doors<<"\tPosition: ("<<position.x<<","<<position.y<<")\tBooked: "<<((booked)?"Yes":"No")
    
    using namespace std;
    
    class Room {
    
        protected:
    
            string name;
            double area;
            int doors;
            Position position;
            bool booked;
    
        public:
    
            Room(string pName, double pArea, int pDoors, Position pPosition);
            virtual void printRoom();
            virtual ~Room() {
            }
            bool operator==(const Room& b);
            double getArea() const;
            bool isBooked() const;
            void book();
            void unbook();
            int getDoors() const;
            const string& getName() const;
            Position getPosition() const;
    
            void setBooked(bool booked);
    };
    
    #endif /* ROOM_H_ */

RoomBookingSystem.h

    #ifndef ROOMBOOKINGSYSTEM_H_
    #define ROOMBOOKINGSYSTEM_H_
    
    #include <iostream>
    #include <string>
    #include <vector>
    
    #include "Position.h"
    #include "Room.h"
    #include "Lab.h"
    #include "LectureHall.h"
    
    class Lab;
    class LectureHall;
    
    using namespace std;
    
    #define ROOMS 1
    #define LABS 2
    #define LECTURE_HALLS 3
    
    //TODO make readme
    class RoomBookingSystem {
    
            void parse(vector<vector<string> > roomDetails, int type);
            void loadstate(vector<vector<string> > bookstatus, int type);
            vector<Room*>* getList(int type);
            vector<Room*>* getConstList(int type) const;
            template<typename T> Room* getRoom(int type, const T matcher) const;
            template<typename T> void print(vector<Room*>& vec, const string& pDescriptor);
            struct RoomComparator {
                    bool operator()(const int i, const int j);
            };
            void saveRooms(vector<Room*>& vec, const char* loc, const char* bookloc);
            vector<vector<string> > read(const char* pFilename, const int pColumns);
    
        public:
    
            RoomBookingSystem();
            ~RoomBookingSystem();
            void addRoom(const string& pName, const double pArea, const int pDoors, const int pX, const int pY);
            void addLab(const string& pName, const double pArea, const int pDoors, const int pX, const int pY, int pComputers);
            void addLectureHall(const string& pName, const double pArea, const int pDoors, const int pX, const int pY, const int pChairs);
            bool removeRoom(int type, Room* r);
            Room* getRoom(const string& pName, int type) const;
            Room* getRoom(const int pX, const int pY, int type) const;
            vector<Room*> getMinimumRoomsOfArea(const int pRequiredArea) const;
            LectureHall* getSmallestLectureHallByStudents(const int pRequiredChairs) const;
            Lab* getLabByLeastEquipmentDensity() const;
            Room* getNearestRoom(const int pX, const int pY) const;
            void printAll();
    
    };
    
    #endif /* ROOMBOOKINGSYSTEM_H_ */

Client.h

    #ifndef CLIENT_H_
    #define CLIENT_H_
    
    #include "RoomBookingSystem.h"
    
    using namespace std;
    
    class Client {
    
            RoomBookingSystem* rbs;
    
            int getRoomType();
            int getRoomByWhat();
            Room* getRoom(int type);
            template<typename T> T input(const string& s) const;
    
        public:
    
            Client();
            ~Client();
            void printChoices();
            void addRoom();
            void getMinimumRoomsofArea();
            void printRoom();
            void getSmallestLectureHallForGivenStudents();
            void getLeastEquipmentDensityLab();
            void getNearestRoom();
            void removeRoom();
            void bookUnbook();
    };
    
    #endif /* CLIENT_H_ */

Matchers.cpp

    #include "Matchers.h"
    
    using namespace std;
    Matchers::MatchName::MatchName(const string& s) :
            name(s) {
    }
    bool Matchers::MatchName::operator()(const Room* r) const {
        return r->getName() == name;
    }
    Matchers::MatchPosition::MatchPosition(const int pX, const int pY) :
            x(pX), y(pY) {
    }
    bool Matchers::MatchPosition::operator()(const Room* r) const {
        return r->getPosition().x == x && r->getPosition().y == y;
    }
    

LectureHall.cpp

    #include "LectureHall.h"
    
    #include <iostream>
    
    #include "Position.h"
    
    using namespace std;
    
     LectureHall::LectureHall(string pName, double pArea, int pDoors, Position pPosition, int pChairs) :
            Room(pName, pArea, pDoors, pPosition) {
        chairs = pChairs;
    }
    
     void LectureHall::printRoom() {
        cout << expand_self << "\tChairs: "  << chairs << endl;
    }
    
     int LectureHall::getChairs() const {
        return chairs;
    }
    
     void LectureHall::setChairs(int chairs) {
        this->chairs = chairs;
    }
    

Client.cpp

    #include "Client.h"
    
    #include <cstdlib>
    #include <iostream>
    #include <iterator>
    #include <string>
    #include <vector>
    
    #include "Lab.h"
    #include "LectureHall.h"
    
    #define NAME 1
    #define POSITION 2
    
    #define BOOK 1
    #define UNBOOK 2
    
    #define CIN_IGNORE_MAX 512
    
    using namespace std;
    
    void Client::printChoices() {
        cout << "Press the corresponding keys for these operations:" << endl;
        cout << "1. Add Room/Lab/Lecture Hall." << endl;
        cout << "2. Remove Room/Lab/Lecture Hall." << endl;
        cout << "3. Book/Unbook a Room/Lab/Lecture Hall." << endl;
        cout << "4. Get minimum number of rooms to accommodate given number of persons." << endl;
        cout << "5. Get smallest lecture hall to accommodate given number of students." << endl;
        cout << "6. Get lab with least equipment density or change lab equipment quantities." << endl;
        cout << "7. Find a room nearest to a location." << endl;
        cout << "8. Print Room/Lab/Lecture Hall details." << endl;
        cout << "9. Exit." << endl;
    }
    Client::Client() {
        rbs = new RoomBookingSystem();
    }
    Client::~Client() {
        delete rbs;
    }
    int Client::getRoomType() {
        cout << ROOMS << ". Room." << endl;
        cout << LABS << ". Lab." << endl;
        cout << LECTURE_HALLS << ". Lecture Hall." << endl;
        int choice = -1;
        while ((choice = input<int>("Enter Choice:")) < ROOMS || choice > LECTURE_HALLS)
            cout << "Please enter valid option." << endl;
        return choice;
    }
    
    int Client::getRoomByWhat() {
        cout << "Choose:" << endl;
        cout << NAME << ". By Name." << endl;
        cout << POSITION << ". By Position." << endl;
        int choice = -1;
        while ((choice = input<int>("Enter Choice:")) < NAME || choice > POSITION)
            cout << "Please enter valid option." << endl;
        return choice;
    }
    
    void Client::addRoom() {
        int roomType = getRoomType();
        string name = input<string>("Enter Name: ");
        double area = input<double>("Enter Area: ");
        int doors = input<int>("Enter Doors: ");
        int x = input<int>("Enter Position X: ");
        int y = input<int>("Enter Position Y: ");
        switch (roomType) {
            case ROOMS:
                rbs->addRoom(name, area, doors, x, y);
                cout << "Room Added." << endl;
                break;
    
            case LABS: {
                int computers = input<int>("Enter Computers: ");
                rbs->addLab(name, area, doors, x, y, computers);
            }
                cout << "Lab Added." << endl;
                break;
            case LECTURE_HALLS: {
                int chairs = input<int>("Enter Chairs: ");
                rbs->addLectureHall(name, area, doors, x, y, chairs);
            }
                cout << "Lecture Hall Added." << endl;
                break;
        }
    }
    
    void Client::removeRoom() {
        int roomType = getRoomType();
        Room* r = getRoom(roomType);
        if (rbs->removeRoom(roomType, r))
            cout << "Room removed successfully." << endl;
        else
            cout << "Room not removed." << endl;
    }
    
    Room* Client::getRoom(int type) {
        switch (getRoomByWhat()) {
            case NAME: {
                string name = input<string>("Enter Name.");
                return rbs->getRoom(name, type);
            }
            case POSITION: {
                int x = input<int>("Enter Position X.");
                int y = input<int>("Enter Position Y.");
                return rbs->getRoom(x, y, type);
            }
        }
        return NULL;
    }
    void Client::bookUnbook() {
        Room* r = getRoom(getRoomType());
        cout << "This room is " << ((r->isBooked()) ? "booked" : "un-booked") << ". Do you want to " << ((r->isBooked()) ? "un-book" : "book") << " it?" << endl;
        char toggleBook = 'z';
        while (toggleBook != 'y' && toggleBook != 'n') {
            cout << "Enter.(y/n)" << endl;
            cin >> toggleBook;
        }
        if (toggleBook == 'y') {
            if (!r->isBooked()) {
                r->book();
            } else {
                r->unbook();
            }
            cout << "Room successfully " << ((r->isBooked()) ? "booked." : "un-booked.") << endl;
        } else {
            cout << "OK." << endl;
        }
    }
    void Client::getMinimumRoomsofArea() {
        double area;
        while ((area = input<double>("Enter Area(>0): ")) <= 0)
            ;
        vector<Room*> v = rbs->getMinimumRoomsOfArea(area);
        if (v.size() == 0) {
            cout << "Not Enough Rooms." << endl;
            return;
        }
        cout << "You may use these " << v.size() << " un-booked rooms." << endl;
        for (vector<Room*>::iterator it = v.begin(); it != v.end(); it++)
            (*it)->printRoom();
    }
    void Client::printRoom() {
        int choice = -1;
        while ((choice = input<int>("Enter 1 for specific Room/Lab/Lecture Hall and 2 for all.")) < 1 || choice > 2)
            ;
        switch (choice) {
            case 1: {
                int type = getRoomType();
                Room* r = getRoom(type);
                if (type == LABS) {
                    ((Lab*) r)->printRoom();
                } else if (type == LECTURE_HALLS) {
                    ((LectureHall*) r)->printRoom();
                } else {
                    r->printRoom();
                }
                break;
            }
            case 2:
                rbs->printAll();
                break;
        }
    }
    
    void Client::getSmallestLectureHallForGivenStudents() {
        int students;
        while ((students = input<int>("Enter Students (>0): ")) <= 0)
            ;
        LectureHall* r = rbs->getSmallestLectureHallByStudents(students);
        if (r->getChairs() > 0) {
            cout << "The required Lecture Hall is:" << endl;
            r->printRoom();
        } else {
            cout << "No such Lecture Hall." << endl;
        }
    }
    void Client::getLeastEquipmentDensityLab() {
        int choice = -1;
        while ((choice = input<int>("Enter 1 to get the lab with least equipment density and 2 to increase equipment density of a lab.")) < 1 || choice > 2)
            ;
        switch (choice) {
            case 1: {
                Room* r = rbs->getLabByLeastEquipmentDensity();
                if (r->getArea() > 0) {
                    r->printRoom();
                } else {
                    cout << "No such Labs." << endl;
                }
            }
                break;
            case 2: {
                Lab* l = (Lab*) getRoom(LABS);
                cout << "The selected lab is:" << endl;
                l->printRoom();
                int newEqu = -1;
                while ((newEqu = input<int>("Enter the new Lab Equipments.")) < 0)
                    ;
                l->setComputers(newEqu);
                break;
            }
        }
    }
    void Client::getNearestRoom() {
        int x = input<int>("Enter Position X:"), y = input<int>("Enter Position Y:");
        Room* r = rbs->getNearestRoom(x, y);
        if (r->getArea() > 0) {
            r->printRoom();
        } else {
            cout << "No such Labs." << endl;
        }
    }
    
    template<typename T> T Client::input(const string& s) const {
        T x;
        do {
            cout << s << endl;
            cin >> x;
            if (!cin) {
                cout << "Please enter valid option." << endl;
                cin.clear();
                cin.ignore(CIN_IGNORE_MAX, '\n');
            } else
                break;
        } while (true);
        return x;
    }
    
    int main(int argc, char **argv) {
        Client* client = new Client();
        while (true) {
            client->printChoices();
            int choice;
            while (!(cin >> choice) || choice < 1 || choice > 9) {
                cout << "Please choose from 1-9" << endl;
                cin.clear();
                cin.ignore(CIN_IGNORE_MAX, '\n');
            }
            switch (choice) {
                case 1:
                    client->addRoom();
                    break;
                case 2:
                    client->removeRoom();
                    break;
                case 3:
                    client->bookUnbook();
                    break;
                case 4:
                    client->getMinimumRoomsofArea();
                    break;
                case 5:
                    client->getSmallestLectureHallForGivenStudents();
                    break;
                case 6:
                    client->getLeastEquipmentDensityLab();
                    break;
                case 7:
                    client->getNearestRoom();
                    break;
                case 8:
                    client->printRoom();
                    break;
                case 9:
                    delete client;
                    cout << "Exited." << endl;
                    exit(0);
                    break;
            }
            char cont = 'z';
            while (cont != 'y' && cont != 'n') {
                cout << "Continue?(y/n)" << endl;
                cin >> cont;
            }
            if (cont == 'n') {
                cout << "Exited." << endl;
                delete client;
                exit(0);
                break;
            }
    
        }
    }

Position.h

    #ifndef POSITION_H_
    #define POSITION_H_
    
    using namespace std;
    
    class Position {
    
        public:
            int x;
            int y;
            Position(const int a, const int b);
    };
    
    #endif /* POSITION_H_ */

Lab.h

    #ifndef LAB_H_
    #define LAB_H_
    
    #include "Room.h"
    
    using namespace std;
    
    class Lab: public Room {
    
            int computers;
    
        public:
    
            Lab(string pName, double pArea, int pDoors, Position pPosition, int pComputers);
            virtual void printRoom();
            virtual ~Lab() {
            }
            int getComputers() const;
            void setComputers(int computers);
            double getEquipmentDensity();
    };
    
    #endif /* LAB_H_ */

RoomBookingSystem.h

#ifndef ROOMBOOKINGSYSTEM_H_
#define ROOMBOOKINGSYSTEM_H_

#include <iostream>
#include <string>
#include <vector>

#include "Position.h"
#include "Room.h"
#include "Lab.h"
#include "LectureHall.h"

class Lab;
class LectureHall;

using namespace std;

#define ROOMS 1
#define LABS 2
#define LECTURE_HALLS 3

//TODO make readme
class RoomBookingSystem {

        void parse(vector<vector<string> > roomDetails, int type);
        void loadstate(vector<vector<string> > bookstatus, int type);
        vector<Room*>* getList(int type);
        vector<Room*>* getConstList(int type) const;
        template<typename T> Room* getRoom(int type, const T matcher) const;
        template<typename T> void print(vector<Room*>& vec, const string& pDescriptor);
        struct RoomComparator {
                bool operator()(const int i, const int j);
        };
        void saveRooms(vector<Room*>& vec, const char* loc, const char* bookloc);
        vector<vector<string> > read(const char* pFilename, const int pColumns);

    public: 

        RoomBookingSystem();
        ~RoomBookingSystem();
        void addRoom(const string& pName, const double pArea, const int pDoors, const int pX, const int pY);
        void addLab(const string& pName, const double pArea, const int pDoors, const int pX, const int pY, int pComputers);
        void addLectureHall(const string& pName, const double pArea, const int pDoors, const int pX, const int pY, const int pChairs);
        bool removeRoom(int type, Room* r);
        Room* getRoom(const string& pName, int type) const;
        Room* getRoom(const int pX, const int pY, int type) const;
        vector<Room*> getMinimumRoomsOfArea(const int pRequiredArea) const;
        LectureHall* getSmallestLectureHallByStudents(const int pRequiredChairs) const;
        Lab* getLabByLeastEquipmentDensity() const;
        Room* getNearestRoom(const int pX, const int pY) const;
        void printAll();

};

#endif /* ROOMBOOKINGSYSTEM_H_ */

RoomBookingSystem.cpp

#include "RoomBookingSystem.h"

#include <stdlib.h>
#include <algorithm>
#include <cfloat>
#include <climits>
#include <fstream>
#include <iterator>
#include <string.h>

#include "Matchers.h"

#define expand_it (*it)[0], atof((*it)[1].c_str()), atoi((*it)[2].c_str()), Position(atoi((*it)[3].c_str()), atoi((*it)[4].c_str()))
#define print_separator cout<<string(100,'=')<<endl;
#define sq(x) (x)*(x)
using namespace std;

#define ROOM_FILE_LOC "data/ROOM.txt"
#define LAB_FILE_LOC "data/LAB.txt"
#define LECTURE_HALL_FILE_LOC "data/LEC.txt"

#define ROOM_BOOK_LOC "data/ROOM_BOOK.txt"
#define LAB_BOOK_LOC "data/LAB_BOOK.txt"
#define LECTURE_HALL_BOOK_LOC "data/LEC_BOOK.txt"

vector<Room*> rooms;
vector<Room*> labss;
vector<Room*> lectureHalls;

RoomBookingSystem::RoomBookingSystem() {
        vector<vector<string> > roomDetails = read(ROOM_FILE_LOC, 5);
        vector<vector<string> > labDetails = read(LAB_FILE_LOC, 6);
        vector<vector<string> > lectureHallDetails = read(LECTURE_HALL_FILE_LOC, 6);
        vector<vector<string> > roomBookDetails = read(ROOM_BOOK_LOC, 1);
        vector<vector<string> > labBookDetails = read(LAB_BOOK_LOC, 1);
        vector<vector<string> > lectureHallBookDetails = read(LECTURE_HALL_BOOK_LOC, 1);
        parse(roomDetails, ROOMS);
        parse(labDetails, LABS);
        parse(lectureHallDetails, LECTURE_HALLS);
        loadstate(roomBookDetails, ROOMS);
        loadstate(labBookDetails, LABS);
        loadstate(lectureHallBookDetails, LECTURE_HALLS);
}

RoomBookingSystem::~RoomBookingSystem() {
        saveRooms(rooms, ROOM_FILE_LOC, ROOM_BOOK_LOC);
        saveRooms(labss, LAB_FILE_LOC, LAB_BOOK_LOC);
        saveRooms(lectureHalls, LECTURE_HALL_FILE_LOC, LECTURE_HALL_BOOK_LOC);
}
vector<vector<string> > RoomBookingSystem::read(const char* pFilename, const int pColumns) {
        ifstream inputStream;
        vector<vector<string> > rooms_list;
        inputStream.open(pFilename);
        if (inputStream.is_open()) {
                while (!inputStream.eof()) {
                        vector<string> roomDetails;
                        for (int i = 0; i < pColumns; i++) {
                                string detail;
                                inputStream >> detail;
                                roomDetails.push_back(detail);
                        }
                        rooms_list.push_back(roomDetails);
                }
        }
        inputStream.close();
        return rooms_list;
}
void RoomBookingSystem::saveRooms(vector<Room*>& vec, const char* loc, const char* bookloc) {
        ofstream outputStream;
        ofstream outputStream2;
        outputStream.open(loc);
        outputStream2.open(bookloc);
        string s = string(loc);
        if (outputStream.is_open() && outputStream2.is_open()) {
                for (unsigned i = 0; i < vec.size(); i++) {
                        Room* r = vec[i];
                        outputStream << r->getName() << "\t" << fixed << setprecision(4) << r->getArea() << "\t" << r->getDoors() << "\t" << r->getPosition().x << "\t" << r->getPosition().y;
                        if (s.compare(LAB_FILE_LOC) == 0) {
                                outputStream << "\t" << ((Lab*) r)->getComputers();
                        } else if (s.compare(LECTURE_HALL_FILE_LOC) == 0) {
                                outputStream << "\t" << ((LectureHall*) r)->getChairs();
                        }
                        outputStream2 << ((vec[i]->isBooked()) ? "1" : "0");
                        if (i != vec.size() - 1) {
                                outputStream << endl;
                                outputStream2 << endl;
                        }
                }
        }
        outputStream.close();
        outputStream2.close();
}
vector<Room*>* RoomBookingSystem::getList(int type) {
        switch (type) {
        case ROOMS:
                return &rooms;
        case LABS:
                return &labss;
        case LECTURE_HALLS:
                return &lectureHalls;
        }
        return NULL;
}
vector<Room*>* RoomBookingSystem::getConstList(int type) const {
        switch (type) {
        case ROOMS:
                return &rooms;
        case LABS:
                return &labss;
        case LECTURE_HALLS:
                return &lectureHalls;
        }
        return NULL;
}

void RoomBookingSystem::parse(vector<vector<string> > roomDetails, int type) {
        for (vector<vector<string> >::iterator it = roomDetails.begin(); it != roomDetails.end(); it++) {
                switch (type) {
                case ROOMS:
                        rooms.push_back(new Room(expand_it));
                        break;
                case LABS:
                        labss.push_back(new Lab(expand_it, atoi((*it)[5].c_str())));
                        break;
                case LECTURE_HALLS:
                        lectureHalls.push_back(new LectureHall(expand_it, atoi((*it)[5].c_str())));
                        break;
                }
        }
}
void RoomBookingSystem::loadstate(vector<vector<string> > bookstatus, int type) {
        vector<Room*>* vec = getList(type);
        for (unsigned i = 0; i < vec->size(); i++) {
                ((*vec)[i])->setBooked(atoi(bookstatus[i][0].c_str()) == 1);
        }
}

void bookRoom(Room &r) {
        r.book();
}
void unbookRoom(Room &r) {
        r.unbook();
}
void RoomBookingSystem::printAll() {
        print<Room>(rooms, "Rooms");
        print<Lab>(labss, "Labs");
        print<LectureHall>(lectureHalls, "Lecture Halls");
}
template<typename T> void RoomBookingSystem::print(vector<Room*>& vec, const string& pDescriptor) {
        print_separator
                cout << "These are currently " << vec.size() << " " << pDescriptor << ": " << endl;
        for (unsigned i = 0; i < vec.size(); i++) {
                ((T*) vec[i])->printRoom();
        }
        print_separator
}
void RoomBookingSystem::addRoom(const string& pName, const double pArea, const int pDoors, const int pX, const int pY) {
        rooms.push_back(new Room(pName, pArea, pDoors, Position(pX, pY)));
}
void RoomBookingSystem::addLab(const string& pName, const double pArea, const int pDoors, const int pX, int pY, int pComputers) {
        labss.push_back(new Lab(pName, pArea, pDoors, Position(pX, pY), pComputers));
}
void RoomBookingSystem::addLectureHall(const string& pName, const double pArea, const int pDoors, const int pX, const int pY, const int pChairs) {
        lectureHalls.push_back(new LectureHall(pName, pArea, pDoors, Position(pX, pY), pChairs));
}
Room* RoomBookingSystem::getRoom(const string& pName, int type) const {
        return getRoom(type, Matchers::MatchName(pName));
}
Room* RoomBookingSystem::getRoom(const int pX, const int pY, int type) const {
        return getRoom(type, Matchers::MatchPosition(pX, pY));
}
bool RoomBookingSystem::RoomComparator::operator()(const int i, const int j) {
        bool b1 = rooms[i]->isBooked();
        bool b2 = rooms[j]->isBooked();
        if (b1 && !b2) {
                return i;
        } else if (!b1 && b2) {
                return j;
        } else {
                return rooms[i]->getArea() >= rooms[j]->getArea();
        }
}
vector<Room*> RoomBookingSystem::getMinimumRoomsOfArea(const int pRequiredArea) const {
        vector<int> roomIndices;
        vector<Room*> requiredRoom;
        for (unsigned i = 0; i < rooms.size(); i++)
                roomIndices.push_back(i);
        sort(roomIndices.begin(), roomIndices.end(), RoomComparator());
        double area = 0;
        for (unsigned i = 0; i < roomIndices.size() && area < pRequiredArea && !rooms[roomIndices[i]]->isBooked(); i++) {
                area += rooms[roomIndices[i]]->getArea();
                requiredRoom.push_back(rooms[roomIndices[i]]);
        }
        if (area >= pRequiredArea)
                return requiredRoom;
        else {
                vector<Room*> emptyVec;
                return emptyVec;
        }
}
LectureHall* RoomBookingSystem::getSmallestLectureHallByStudents(const int pRequiredChairs) const {
        double minArea = DBL_MAX;
        LectureHall* requiredHall = new LectureHall("", 0, 0, Position(0, 0), 0);
        for (vector<Room*>::iterator it = lectureHalls.begin(); it != lectureHalls.end(); it++) {
                if (((LectureHall*) *it)->getChairs() >= pRequiredChairs && !(*it)->isBooked() && (*it)->getArea() < minArea) {
                        requiredHall = (LectureHall*) *it;
                        minArea = requiredHall->getArea();
                }
        }
        return requiredHall;
}
Lab* RoomBookingSystem::getLabByLeastEquipmentDensity() const {
        double minDensity = DBL_MAX;
        Lab* requiredLab = new Lab("", 0, 0, Position(0, 0), 0);
        for (vector<Room*>::iterator it = labss.begin(); it != labss.end(); it++) {
                if (((Lab*) *it)->getEquipmentDensity() < minDensity && !(*it)->isBooked()) {
                        requiredLab = (Lab*) *it;
                        minDensity = requiredLab->getEquipmentDensity();
                }
        }
        return requiredLab;
}

Room* RoomBookingSystem::getNearestRoom(const int pX, const int pY) const {
        long minDistanceSquared = LONG_MAX;
        Room* requiredRoom = new Room("", 0, 0, Position(0, 0));
        for (vector<Room*>::iterator it = rooms.begin(); it != rooms.end(); it++) {
                long distanceSquared = sq((*it)->getPosition().x - pX) + sq((*it)->getPosition().y - pY);
                if (distanceSquared < minDistanceSquared && !(*it)->isBooked()) {
                        requiredRoom = *it;
                        minDistanceSquared = distanceSquared;
                }
        }
        return requiredRoom;
}

template<class T> Room* RoomBookingSystem::getRoom(int type, const T matcher) const {
        vector<Room*>* vec = getConstList(type);
        vector<Room*>::iterator r = find_if(vec->begin(), vec->end(), matcher);
        return *r;
}

bool RoomBookingSystem::removeRoom(int type, Room* r) {
        vector<Room*>* vec = getList(type);
        if (r != *vec->end()) {
                vec->erase(std::remove(vec->begin(), vec->end(), r), vec->end());
                return true;
        } else
                return false;
}

Room.h

#ifndef ROOM_H_
#define ROOM_H_

#include <string>
#include <iomanip>

#include "Position.h"

#define expand_self "Name: "<<name<<"\tArea: "<<setprecision(4)<<area<<"\tDoors: "<<doors<<"\tPosition: ("<<position.x<<","<<position.y<<")\tBooked: "<<((booked)?"Yes":"No")

using namespace std; 

class Room {

    protected:

        string name;
        double area;
        int doors;
        Position position;
        bool booked;

    public:

        Room(string pName, double pArea, int pDoors, Position pPosition);
        virtual void printRoom();
        virtual ~Room() {
        }
        bool operator==(const Room& b);
        double getArea() const;
        bool isBooked() const;
        void book();
        void unbook();
        int getDoors() const;
        const string& getName() const;
        Position getPosition() const;

        void setBooked(bool booked);
};

#endif /* ROOM_H_ */
#include "Room.h"

#include <iostream>

using namespace std;
Room::Room(string pName, double pArea, int pDoors, Position pPosition) :
        name(pName), area(pArea), doors(pDoors), position(pPosition), booked(false) {
}
void Room::printRoom() {
    cout << expand_self << endl;
}
bool Room::operator==(const Room& r) {
    return name == r.name && position.x == r.position.x && position.y == r.position.y;
}
double Room::getArea() const {
    return area;
}

bool Room::isBooked() const {
    return booked;
}

void Room::book() {
    this->booked = true;
}
void Room::unbook() {
    this->booked = false;
}

int Room::getDoors() const {
    return doors;
}

const string& Room::getName() const {
    return name;
}

Position Room::getPosition() const {
    return position;
}
void Room::setBooked(bool booked) {
    this->booked = booked;
}

Position.h

#ifndef POSITION_H_
#define POSITION_H_

using namespace std;

class Position {

    public:
        int x;
        int y;
        Position(const int a, const int b);
};

#endif /* POSITION_H_ */

Position.cpp

#include "Position.h"

using namespace std;
Position::Position(int a, int b) :
        x(a), y(b) {
}

Matchers.h

#ifndef MATCHERS_H_
#define MATCHERS_H_

#include <string>

#include "Position.h"
#include "Room.h"

using namespace std;

class Matchers {
    public:
        struct MatchName {
                MatchName(const string& s);
                bool operator()(const Room* r) const;
            private:
                const string& name;
        };
        struct MatchPosition {
                MatchPosition(const int pX, const int pY);
                bool operator()(const Room* r) const;
            private:
                const int x;
                const int y;
        };
};

#endif /* MATCHERS_H_ */

Matchers.cpp

#include "Matchers.h"

using namespace std;
Matchers::MatchName::MatchName(const string& s) :
        name(s) {
}
bool Matchers::MatchName::operator()(const Room* r) const {
    return r->getName() == name;
}
Matchers::MatchPosition::MatchPosition(const int pX, const int pY) :
        x(pX), y(pY) {
}
bool Matchers::MatchPosition::operator()(const Room* r) const {
    return r->getPosition().x == x && r->getPosition().y == y;
}

LectureHall.h

#ifndef LECTUREHALL_H_
#define LECTUREHALL_H_

#include <string>

#include "Room.h"

using namespace std;

class LectureHall: public Room {

        int chairs;
    public:
        LectureHall(string pName, double pArea, int pDoors, Position pPosition, int pChairs);
        virtual void printRoom();
        virtual ~LectureHall() {
        }
        int getChairs() const;
        void setChairs(int chairs);
};

#endif /* LECTUREHALL_H_ */

LectureHall.cpp

#include "LectureHall.h"

#include <iostream>

#include "Position.h"

using namespace std;

LectureHall::LectureHall(string pName, double pArea, int pDoors, Position pPosition, int pChairs) :
        Room(pName, pArea, pDoors, pPosition) {
    chairs = pChairs;
}

void LectureHall::printRoom() {
    cout << expand_self << "\tChairs: "  << chairs << endl;
}

int LectureHall::getChairs() const {
    return chairs;
}

void LectureHall::setChairs(int chairs) {
    this->chairs = chairs;
}

Lab.h

#ifndef LAB_H_
#define LAB_H_

#include "Room.h"

using namespace std;

class Lab: public Room {

        int computers;
 
    public:

        Lab(string pName, double pArea, int pDoors, Position pPosition, int pComputers);
        virtual void printRoom();
        virtual ~Lab() {
        }
        int getComputers() const;
        void setComputers(int computers);
        double getEquipmentDensity();
};

#endif /* LAB_H_ */

Lab.cpp

#include "Lab.h"

#include <iostream>
#include <string>

#include "Position.h"

using namespace std;
//=========================================================================
// CONSTRUCTOR
//=========================================================================
Lab::Lab(string pName, double pArea, int pDoors, Position pPosition, int pComputers) :
        Room(pName, pArea, pDoors, pPosition) {
    computers = pComputers;
}
void Lab::printRoom() {
    cout << expand_self << "\tComputers: " << computers << endl;
}
int Lab::getComputers() const {
    return computers;
}

void Lab::setComputers(int computers) {
    this->computers = computers;
}

double Lab::getEquipmentDensity() {
    return computers / area;
}

Client.h

#ifndef CLIENT_H_
#define CLIENT_H_

#include "RoomBookingSystem.h"

using namespace std;

class Client {

        RoomBookingSystem* rbs;

        int getRoomType();
        int getRoomByWhat();
        Room* getRoom(int type);
        template<typename T> T input(const string& s) const;

    public: 

        Client();
        ~Client();
        void printChoices();
        void addRoom();
        void getMinimumRoomsofArea();
        void printRoom();
        void getSmallestLectureHallForGivenStudents();
        void getLeastEquipmentDensityLab();
        void getNearestRoom();
        void removeRoom();
        void bookUnbook();
};

#endif /* CLIENT_H_ */

Client.cpp

#include "Client.h"

#include <cstdlib>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

#include "Lab.h"
#include "LectureHall.h"

#define NAME 1
#define POSITION 2

#define BOOK 1
#define UNBOOK 2

#define CIN_IGNORE_MAX 512

using namespace std;

void Client::printChoices() {
    cout << "Press the corresponding keys for these operations:" << endl;
    cout << "1. Add Room/Lab/Lecture Hall." << endl;
    cout << "2. Remove Room/Lab/Lecture Hall." << endl;
    cout << "3. Book/Unbook a Room/Lab/Lecture Hall." << endl;
    cout << "4. Get minimum number of rooms to accommodate given number of persons." << endl;
    cout << "5. Get smallest lecture hall to accommodate given number of students." << endl;
    cout << "6. Get lab with least equipment density or change lab equipment quantities." << endl;
    cout << "7. Find a room nearest to a location." << endl;
    cout << "8. Print Room/Lab/Lecture Hall details." << endl;
    cout << "9. Exit." << endl;
}
Client::Client() {
    rbs = new RoomBookingSystem();
}
Client::~Client() {
    delete rbs;
}
int Client::getRoomType() {
    cout << ROOMS << ". Room." << endl;
    cout << LABS << ". Lab." << endl;
    cout << LECTURE_HALLS << ". Lecture Hall." << endl;
    int choice = -1;
    while ((choice = input<int>("Enter Choice:")) < ROOMS || choice > LECTURE_HALLS)
        cout << "Please enter valid option." << endl;
    return choice;
}

int Client::getRoomByWhat() {
    cout << "Choose:" << endl;
    cout << NAME << ". By Name." << endl;
    cout << POSITION << ". By Position." << endl;
    int choice = -1;
    while ((choice = input<int>("Enter Choice:")) < NAME || choice > POSITION)
        cout << "Please enter valid option." << endl;
    return choice;
}

void Client::addRoom() {
    int roomType = getRoomType();
    string name = input<string>("Enter Name: ");
    double area = input<double>("Enter Area: ");
    int doors = input<int>("Enter Doors: ");
    int x = input<int>("Enter Position X: ");
    int y = input<int>("Enter Position Y: ");
    switch (roomType) {
        case ROOMS:
            rbs->addRoom(name, area, doors, x, y);
            cout << "Room Added." << endl;
            break;

        case LABS: {
            int computers = input<int>("Enter Computers: ");
            rbs->addLab(name, area, doors, x, y, computers);
        }
            cout << "Lab Added." << endl;
            break;
        case LECTURE_HALLS: {
            int chairs = input<int>("Enter Chairs: ");
            rbs->addLectureHall(name, area, doors, x, y, chairs);
        }
            cout << "Lecture Hall Added." << endl;
            break;
    }
}

void Client::removeRoom() {
    int roomType = getRoomType();
    Room* r = getRoom(roomType);
    if (rbs->removeRoom(roomType, r))
        cout << "Room removed successfully." << endl;
    else
        cout << "Room not removed." << endl;
}

Room* Client::getRoom(int type) {
    switch (getRoomByWhat()) {
        case NAME: {
            string name = input<string>("Enter Name.");
            return rbs->getRoom(name, type);
        }
        case POSITION: {
            int x = input<int>("Enter Position X.");
            int y = input<int>("Enter Position Y.");
            return rbs->getRoom(x, y, type);
        }
    }
    return NULL;
}
void Client::bookUnbook() {
    Room* r = getRoom(getRoomType());
    cout << "This room is " << ((r->isBooked()) ? "booked" : "un-booked") << ". Do you want to " << ((r->isBooked()) ? "un-book" : "book") << " it?" << endl;
    char toggleBook = 'z';
    while (toggleBook != 'y' && toggleBook != 'n') {
        cout << "Enter.(y/n)" << endl;
        cin >> toggleBook;
    }
    if (toggleBook == 'y') {
        if (!r->isBooked()) {
            r->book();
        } else {
            r->unbook();
        }
        cout << "Room successfully " << ((r->isBooked()) ? "booked." : "un-booked.") << endl;
    } else {
        cout << "OK." << endl;
    }
}
void Client::getMinimumRoomsofArea() {
    double area;
    while ((area = input<double>("Enter Area(>0): ")) <= 0)
        ;
    vector<Room*> v = rbs->getMinimumRoomsOfArea(area);
    if (v.size() == 0) {
        cout << "Not Enough Rooms." << endl;
        return;
    }
    cout << "You may use these " << v.size() << " un-booked rooms." << endl;
    for (vector<Room*>::iterator it = v.begin(); it != v.end(); it++)
        (*it)->printRoom();
}
void Client::printRoom() {
    int choice = -1;
    while ((choice = input<int>("Enter 1 for specific Room/Lab/Lecture Hall and 2 for all.")) < 1 || choice > 2)
        ;
    switch (choice) {
        case 1: {
            int type = getRoomType();
            Room* r = getRoom(type);
            if (type == LABS) {
                ((Lab*) r)->printRoom();
            } else if (type == LECTURE_HALLS) {
                ((LectureHall*) r)->printRoom();
            } else {
                r->printRoom();
            }
            break;
        }
        case 2:
            rbs->printAll();
            break;
    }
}

void Client::getSmallestLectureHallForGivenStudents() {
    int students;
    while ((students = input<int>("Enter Students (>0): ")) <= 0)
        ;
    LectureHall* r = rbs->getSmallestLectureHallByStudents(students);
    if (r->getChairs() > 0) {
        cout << "The required Lecture Hall is:" << endl;
        r->printRoom();
    } else {
        cout << "No such Lecture Hall." << endl;
    }
}
void Client::getLeastEquipmentDensityLab() {
    int choice = -1;
    while ((choice = input<int>("Enter 1 to get the lab with least equipment density and 2 to increase equipment density of a lab.")) < 1 || choice > 2)
        ;
    switch (choice) {
        case 1: {
            Room* r = rbs->getLabByLeastEquipmentDensity();
            if (r->getArea() > 0) {
                r->printRoom();
            } else {
                cout << "No such Labs." << endl;
            }
        }
            break;
        case 2: {
            Lab* l = (Lab*) getRoom(LABS);
            cout << "The selected lab is:" << endl;
            l->printRoom();
            int newEqu = -1;
            while ((newEqu = input<int>("Enter the new Lab Equipments.")) < 0)
                ;
            l->setComputers(newEqu);
            break;
        }
    }
}
void Client::getNearestRoom() {
    int x = input<int>("Enter Position X:"), y = input<int>("Enter Position Y:");
    Room* r = rbs->getNearestRoom(x, y);
    if (r->getArea() > 0) {
        r->printRoom();
    } else {
        cout << "No such Labs." << endl;
    }
}

template<typename T> T Client::input(const string& s) const {
    T x;
    do {
        cout << s << endl;
        cin >> x;
        if (!cin) {
            cout << "Please enter valid option." << endl;
            cin.clear();
            cin.ignore(CIN_IGNORE_MAX, '\n');
        } else
            break;
    } while (true);
    return x;
}

int main(int argc, char **argv) {
    Client* client = new Client();
    while (true) {
        client->printChoices();
        int choice;
        while (!(cin >> choice) || choice < 1 || choice > 9) {
            cout << "Please choose from 1-9" << endl;
            cin.clear();
            cin.ignore(CIN_IGNORE_MAX, '\n');
        }
        switch (choice) {
            case 1:
                client->addRoom();
                break;
            case 2:
                client->removeRoom();
                break;
            case 3:
                client->bookUnbook();
                break;
            case 4:
                client->getMinimumRoomsofArea();
                break;
            case 5:
                client->getSmallestLectureHallForGivenStudents();
                break;
            case 6:
                client->getLeastEquipmentDensityLab();
                break;
            case 7:
                client->getNearestRoom();
                break;
            case 8:
                client->printRoom();
                break;
            case 9:
                delete client;
                cout << "Exited." << endl;
                exit(0);
                break;
        }
        char cont = 'z';
        while (cont != 'y' && cont != 'n') {
            cout << "Continue?(y/n)" << endl;
            cin >> cont;
        }
        if (cont == 'n') {
            cout << "Exited." << endl;
            delete client;
            exit(0);
            break;
        }

    }
}
Post Reopened by Mathieu Guindon
added 33602 characters in body
Source Link
RE60K
  • 1.5k
  • 2
  • 11
  • 27
Loading
Post Closed as "Not suitable for this site" by Mathieu Guindon
Source Link
RE60K
  • 1.5k
  • 2
  • 11
  • 27
Loading