Introduction
Parking nowadays plays a crucial role in growth, particularly in urban and adaptable constructions. While airports, urban areas, and shopping centers may offer ample parking space, organizing it effectively can present challenges. A well-designed parking system facilitates traffic flow, monitors parking availability, and ensures smooth parking processes. This tutorial will delve into creating a basic parking lot layout using C++. We will outline the issue, list necessary components, and develop a straightforward solution.
Problem Statement:
We need to create a parking lot system that can accommodate more than one vehicle at a time and keep a record of how many parking spaces are still open. The system in consideration should have the capacity for the following functions:
- Park a vehicle: Site availability management - whenever the car is taken to the site, the relevant host will always invite the observer to at least one empty site.
- Remove a vehicle: If there is any vehicle parked, the system should mark that the parking space is now free.
- Track available spots: In the operations of such a system a considerable number of spots available at a particular time will be accurately mentioned.
It is evident that this parking area has a finite number of spaces available, and we can also make the assumption that it will accommodate different types of vehicles simultaneously, such as cars, motorcycles, and buses, with varying space requirements for each type of vehicle.
Program 1:
Example
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// Enum to define vehicle sizes
enum VehicleSize { MOTORCYCLE, COMPACT, LARGE };
// Abstract class for a vehicle
class Vehicle {
protected:
VehicleSize size;
int spotsNeeded;
public:
virtual VehicleSize getSize() = 0;
virtual int getSpotsNeeded() = 0;
};
class Motorcycle : public Vehicle {
public:
Motorcycle() {
size = MOTORCYCLE;
spotsNeeded = 1;
}
VehicleSize getSize() override {
return MOTORCYCLE;
}
int getSpotsNeeded() override {
return 1;
}
};
class Car : public Vehicle {
public:
Car() {
size = COMPACT;
spotsNeeded = 1;
}
VehicleSize getSize() override {
return COMPACT;
}
int getSpotsNeeded() override {
return 1;
}
};
class Bus : public Vehicle {
public:
Bus() {
size = LARGE;
spotsNeeded = 5;
}
VehicleSize getSize() override {
return LARGE;
}
int getSpotsNeeded() override {
return 5;
}
};
// Class to represent a parking spot
class ParkingSpot {
private:
VehicleSize spotSize;
Vehicle* currentVehicle;
int spotNumber;
public:
ParkingSpot(VehicleSize size, int num) : spotSize(size), spotNumber(num), currentVehicle(nullptr) {}
bool isAvailable() {
return currentVehicle == nullptr;
}
bool canFitVehicle(Vehicle* vehicle) {
return isAvailable() && vehicle->getSize() <= spotSize;
}
void parkVehicle(Vehicle* vehicle) {
currentVehicle = vehicle;
}
void removeVehicle() {
currentVehicle = nullptr;
}
int getSpotNumber() const {
return spotNumber;
}
};
// Class to represent a parking level
class ParkingLevel {
private:
int floorNumber;
vector<ParkingSpot> spots;
int availableSpots;
public:
ParkingLevel(int floor, int numberOfSpots) : floorNumber(floor), availableSpots(numberOfSpots) {
for (int i = 0; i < numberOfSpots; ++i) {
spots.push_back(ParkingSpot(COMPACT, i));
}
}
bool parkVehicle(Vehicle* vehicle) {
int spotsNeeded = vehicle->getSpotsNeeded();
for (int i = 0; i < spots.size(); ++i) {
if (spots[i].canFitVehicle(vehicle)) {
spots[i].parkVehicle(vehicle);
availableSpots--;
return true;
}
}
return false;
}
void removeVehicle(int spotNumber) {
spots[spotNumber].removeVehicle();
availableSpots++;
}
int getAvailableSpots() {
return availableSpots;
}
};
// Class to represent the parking lot
class ParkingLot {
private:
vector<ParkingLevel> levels;
public:
ParkingLot(int numLevels, int spotsPerLevel) {
for (int i = 0; i < numLevels; ++i) {
levels.push_back(ParkingLevel(i, spotsPerLevel));
}
}
bool parkVehicle(Vehicle* vehicle) {
for (auto& level : levels) {
if (level.parkVehicle(vehicle)) {
return true;
}
}
return false;
}
void removeVehicle(int levelNumber, int spotNumber) {
levels[levelNumber].removeVehicle(spotNumber);
}
void displayAvailableSpots() {
for (int i = 0; i < levels.size(); ++i) {
cout << "Level " << i << ": " << levels[i].getAvailableSpots() << " spots available." << endl;
}
}
};
int main() {
// Create a parking lot with 3 levels and 10 spots per level
ParkingLot parkingLot(3, 10);
Vehicle* car = new Car();
Vehicle* motorcycle = new Motorcycle();
Vehicle* bus = new Bus();
// Park vehicles
parkingLot.parkVehicle(car);
parkingLot.parkVehicle(motorcycle);
parkingLot.parkVehicle(bus);
// Display available spots
parkingLot.displayAvailableSpots();
return 0;
}
Output:
Level 0: 8 spots available.
Level 1: 10 spots available.
Level 2: 10 spots available.
Explanation of code:
- Vehicle Class Vehicle is an abstract class containing subclasses such as Motorcycle, Car, and Bus, which implement the required number of spots in the structure.
- ParkingSpot Class: This class gives the individual dimensioned parking space, also known as a parking spot. It is capable of verifying whether the spot is taken and if the vehicle can be accommodated.
- ParkingLevel Class: It contains several parking spots and is responsible for the proper placement of the vehicle in the parking area. The vehicle can be parked only if there is an empty parking spot. When a vehicle is driven out of the parking zone, it becomes possible to remove a vehicle from this level.
- ParkingLot Class: It controls multiple levels within the area of many parking lots. It is particularly optimized for cases where one or more vehicles have to be parked within the available space and then removed whenever desired.
Program 2:
Example
#include <iostream>
#include <vector>
#include <chrono>
#include <string>
using namespace std;
// Enum to define vehicle sizes
enum VehicleSize { MOTORCYCLE, COMPACT, LARGE };
// Abstract class for a vehicle
class Vehicle {
protected:
string licensePlate;
VehicleSize size;
int spotsNeeded;
public:
Vehicle(string plate) : licensePlate(plate) {}
string getLicensePlate() const {
return licensePlate;
}
virtual VehicleSize getSize() = 0;
virtual int getSpotsNeeded() = 0;
};
class Motorcycle : public Vehicle {
public:
Motorcycle(string plate) : Vehicle(plate) {
size = MOTORCYCLE;
spotsNeeded = 1;
}
VehicleSize getSize() override {
return MOTORCYCLE;
}
int getSpotsNeeded() override {
return 1;
}
};
class Car : public Vehicle {
public:
Car(string plate) : Vehicle(plate) {
size = COMPACT;
spotsNeeded = 1;
}
VehicleSize getSize() override {
return COMPACT;
}
int getSpotsNeeded() override {
return 1;
}
};
class Bus : public Vehicle {
public:
Bus(string plate) : Vehicle(plate) {
size = LARGE;
spotsNeeded = 5;
}
VehicleSize getSize() override {
return LARGE;
}
int getSpotsNeeded() override {
return 5;
}
};
// Class to represent a parking spot
class ParkingSpot {
private:
VehicleSize spotSize;
Vehicle* currentVehicle;
int spotNumber;
bool isReserved; // Reserved spot feature
public:
ParkingSpot(VehicleSize size, int num) : spotSize(size), spotNumber(num), currentVehicle(nullptr), isReserved(false) {}
bool isAvailable() {
return currentVehicle == nullptr && !isReserved;
}
bool canFitVehicle(Vehicle* vehicle) {
return isAvailable() && vehicle->getSize() <= spotSize;
}
void parkVehicle(Vehicle* vehicle) {
currentVehicle = vehicle;
}
void removeVehicle() {
currentVehicle = nullptr;
}
int getSpotNumber() const {
return spotNumber;
}
bool reserveSpot() {
if (!isReserved && isAvailable()) {
isReserved = true;
return true;
}
return false;
}
void unreserveSpot() {
isReserved = false;
}
bool isReservedSpot() {
return isReserved;
}
};
// Class to track parking duration and fee calculation
class ParkingTicket {
private:
chrono::time_point<chrono::system_clock> entryTime;
chrono::time_point<chrono::system_clock> exitTime;
double hourlyRate;
public:
ParkingTicket(double rate = 5.0) : hourlyRate(rate) {
entryTime = chrono::system_clock::now();
}
void setExitTime() {
exitTime = chrono::system_clock::now();
}
double calculateFee() {
chrono::duration<double> duration = exitTime - entryTime;
return duration.count() * hourlyRate;
}
};
// Class to represent a parking level
class ParkingLevel {
private:
int floorNumber;
vector<ParkingSpot> spots;
int availableSpots;
int totalSpots;
public:
ParkingLevel(int floor, int numberOfSpots) : floorNumber(floor), availableSpots(numberOfSpots), totalSpots(numberOfSpots) {
for (int i = 0; i < numberOfSpots; ++i) {
spots.push_back(ParkingSpot(COMPACT, i));
}
}
bool parkVehicle(Vehicle* vehicle) {
int spotsNeeded = vehicle->getSpotsNeeded();
for (int i = 0; i < spots.size(); ++i) {
if (spots[i].canFitVehicle(vehicle)) {
spots[i].parkVehicle(vehicle);
availableSpots--;
return true;
}
}
return false;
}
void removeVehicle(int spotNumber) {
spots[spotNumber].removeVehicle();
availableSpots++;
}
int getAvailableSpots() const {
return availableSpots;
}
int getTotalSpots() const {
return totalSpots;
}
bool reserveSpot(int spotNumber) {
if (spots[spotNumber].isAvailable()) {
spots[spotNumber].reserveSpot();
availableSpots--;
return true;
}
return false;
}
void unreserveSpot(int spotNumber) {
if (spots[spotNumber].isReservedSpot()) {
spots[spotNumber].unreserveSpot();
availableSpots++;
}
}
};
// Class to represent the parking lot
class ParkingLot {
private:
vector<ParkingLevel> levels;
public:
ParkingLot(int numLevels, int spotsPerLevel) {
for (int i = 0; i < numLevels; ++i) {
levels.push_back(ParkingLevel(i, spotsPerLevel));
}
}
bool parkVehicle(Vehicle* vehicle) {
for (auto& level : levels) {
if (level.parkVehicle(vehicle)) {
return true;
}
}
return false;
}
void removeVehicle(int levelNumber, int spotNumber) {
levels[levelNumber].removeVehicle(spotNumber);
}
void displayAvailableSpots() {
for (int i = 0; i < levels.size(); ++i) {
cout << "Level " << i << ": " << levels[i].getAvailableSpots() << " spots available." << endl;
}
}
bool reserveSpot(int levelNumber, int spotNumber) {
return levels[levelNumber].reserveSpot(spotNumber);
}
void unreserveSpot(int levelNumber, int spotNumber) {
levels[levelNumber].unreserveSpot(spotNumber);
}
};
// Main function to test the system
int main() {
// Create a parking lot with 3 levels and 10 spots per level
ParkingLot parkingLot(3, 10);
// Create vehicles
Vehicle* car = new Car("CAR123");
Vehicle* motorcycle = new Motorcycle("MOTO456");
Vehicle* bus = new Bus("BUS789");
// Park vehicles
parkingLot.parkVehicle(car);
parkingLot.parkVehicle(motorcycle);
parkingLot.parkVehicle(bus);
// Display available spots
parkingLot.displayAvailableSpots();
// Reserve a spot
if (parkingLot.reserveSpot(0, 2)) {
cout << "Spot 2 on Level 0 reserved successfully." << endl;
} else {
cout << "Failed to reserve spot 2 on Level 0." << endl;
}
// Unreserve a spot
parkingLot.unreserveSpot(0, 2);
// Display available spots again
parkingLot.displayAvailableSpots();
return 0;
}
Output:
Level 0: 8 spots available.
Level 1: 10 spots available.
Level 2: 10 spots available.
Spot 2 on Level 0 reserved successfully.
Level 0: 8 spots available.
Level 1: 10 spots available.
Level 2: 10 spots available.
Explanation:
- Vehicle Registration and Identification: The Vehicle class now includes a licensePlate attribute, which tracks the registration number of each vehicle.
- Parking Charges: The ParkingTicket class calculates parking fees based on the entry and exit time using a simple hourly rate.
- Dynamic Spot Allocation: Vehicles are parked based on their size (MOTORCYCLE, COMPACT, LARGE), and different types of vehicles can fit into other spots.
- Reservation System: Users can reserve parking spots. The system prevents vehicles from occupying reserved spots, and reservations can be cancelled to free up space.
- Displaying Available Spots: The system displays the number of available parking spots on each level.
Conclusion:
In summary, this basic C++ parking lot system demonstrates the organization of vehicles and the management of available spaces across multiple levels. There is potential to improve the design by incorporating advanced features like managing payment options, enabling dynamic spot reservation through mobile devices, and providing real-time updated information. This framework serves as a foundation for developing more complex parking solutions.