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](https://github.com/adityagupta1089/Room-Booking-System). It basically asks for user input. I tried to make it very robust with invalid input fail-proof.

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.

What improvements could have been done?

---------------------------------------
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_ */

---------------------------------------
Room.cpp
---------------------------------------
    #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;
    		}
    
    	}
    }