add csci-1200-hw-2
This commit is contained in:
@@ -10,7 +10,7 @@ author:
|
||||
link: https://www.jamesflare.com
|
||||
email:
|
||||
avatar: /site-logo.avif
|
||||
description:
|
||||
description: 这篇博客文章详细介绍了如何在C++中实现一个简单的拼车应用程序,作为CSCI-1200课程作业的一部分。该实现涉及使用向量存储数据来处理乘客请求和司机取消操作,并遵循特定的输入和输出文件格式。
|
||||
keywords: ["C++", "编程", "作业", "String", "Vector", "Class"]
|
||||
license:
|
||||
comment: true
|
||||
@@ -29,7 +29,7 @@ hiddenFromHomePage: false
|
||||
hiddenFromSearch: false
|
||||
hiddenFromRss: false
|
||||
hiddenFromRelated: false
|
||||
summary:
|
||||
summary: 这篇博客文章详细介绍了如何在C++中实现一个简单的拼车应用程序,作为CSCI-1200课程作业的一部分。该实现涉及使用向量存储数据来处理乘客请求和司机取消操作,并遵循特定的输入和输出文件格式。
|
||||
resources:
|
||||
- name: featured-image
|
||||
src: featured-image.jpg
|
||||
@@ -396,6 +396,10 @@ A: 与 Uber 相同。保留一位小数。直接截断即可。例如,如果
|
||||
- 成员变量是公开的。 (-2)
|
||||
````
|
||||
|
||||
## 支持文件
|
||||
|
||||
{{< link href="ride_sharing.7z" content="ride_sharing.7z" title="Download ride_sharing.7z" download="ride_sharing.7z" card=true >}}
|
||||
|
||||
## 程序设计
|
||||
|
||||
由于这次作业比较复杂,我们在开始前最好好好构思一下怎么实现。这里我借用两种情况,也就是指令是“request”和“cancel”两种情况分别设计它们单独的流程,然后在主程序中使用这两部分。姑且把它们称作`handleRequest()`以及`handleCancel()`。
|
||||
@@ -461,3 +465,829 @@ flowchart TD
|
||||
```
|
||||
|
||||
有了流程图我们就可以慢慢实现它们了。当然,不一定要真写`handleRequest()`和`handleCancel()`两个function。把它们的逻辑直接在`main()`中实现也是可以的,我这里只是为了思路清晰而已。
|
||||
|
||||
此外,我们要设计两个Class,因为这是作业要求,也是为了方便我们实现功能。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Rider {
|
||||
%% 数据成员
|
||||
- firstName :
|
||||
- lastName : string
|
||||
- gender : string
|
||||
- age : int
|
||||
- phoneNumber : string
|
||||
- rating : double
|
||||
- pickupLocationName : string
|
||||
- pickupLatitude : double
|
||||
- pickupLongitude : double
|
||||
- dropoffLocationName : string
|
||||
- dropoffLatitude : double
|
||||
- dropoffLongitude : double
|
||||
- vehiclePref : string
|
||||
- currentState : string
|
||||
- driverFirstName : string
|
||||
- driverLastName : string
|
||||
- driverPhoneNumber : string
|
||||
|
||||
%% 构造函数
|
||||
+ Rider()
|
||||
|
||||
%% 方法
|
||||
+ getFirstName()
|
||||
+ getLastName()
|
||||
+ getGender()
|
||||
+ getAge()
|
||||
+ getPhoneNumber()
|
||||
+ getRating()
|
||||
+ getPickupLocationName()
|
||||
+ getPickupLatitude()
|
||||
+ getPickupLongitude()
|
||||
+ getDropoffLocationName()
|
||||
+ getDropoffLatitude()
|
||||
+ getDropoffLongitude()
|
||||
+ getVehiclePref()
|
||||
+ getCurrentState()
|
||||
+ getDriverFirstName()
|
||||
+ getDriverLastName()
|
||||
+ getDriverPhoneNumber()
|
||||
+ setCurrentState()
|
||||
+ setDriverInfo()
|
||||
+ toFileString()
|
||||
}
|
||||
|
||||
class Driver {
|
||||
%% 数据成员
|
||||
- firstName : string
|
||||
- lastName : string
|
||||
- gender : string
|
||||
- age : int
|
||||
- phoneNumber : string
|
||||
- rating : double
|
||||
- latitude : double
|
||||
- longitude : double
|
||||
- vehicleType : string
|
||||
- currentState : string
|
||||
- riderFirstName : string
|
||||
- riderLastName : string
|
||||
- riderPhoneNumber : string
|
||||
|
||||
%% 构造函数
|
||||
+ Driver()
|
||||
|
||||
%% 方法
|
||||
+ getFirstName()
|
||||
+ getLastName()
|
||||
+ getGender()
|
||||
+ getAge()
|
||||
+ getPhoneNumber()
|
||||
+ getRating()
|
||||
+ getLatitude()
|
||||
+ getLongitude()
|
||||
+ getVehicleType()
|
||||
+ getCurrentState()
|
||||
+ getRiderFirstName()
|
||||
+ getRiderLastName()
|
||||
+ getRiderPhoneNumber()
|
||||
+ setCurrentState()
|
||||
+ setRiderInfo()
|
||||
+ toFileString()
|
||||
}
|
||||
```
|
||||
|
||||
## 踩坑内容
|
||||
|
||||
1. 在打印`output0.txt`时,looking for 后面要跟一个 Rider 期望的vehicle。但是这个vehicle可能有元音字母,所以要判断一下,到底是用a还是an。这是一个小问题,实现起来并不复杂,但是别忘了。我用了一个function来返回a还是an。
|
||||
|
||||
```cpp
|
||||
std::string autoAAn(const std::string &word) {
|
||||
if (word.empty()) return "";
|
||||
if (word[0] == 'A' || word[0] == 'E' || word[0] == 'I' || word[0] == 'O' || word[0] == 'U') {
|
||||
return "an";
|
||||
}
|
||||
return "a";
|
||||
}
|
||||
```
|
||||
|
||||
然后在后面配合`<sstream>`的`ostringstream`的方式拼接从Rider Class获取的字段。下面的代码就展示以下逻辑和结构,不必较真。
|
||||
|
||||
```cpp
|
||||
#include <sstream>
|
||||
//...
|
||||
Rider &r = riders[rIdx]; //just consider `r` as your rider class
|
||||
std::ostringstream msg;
|
||||
msg << "Ride requested for rider " << r.getFirstName()
|
||||
<< ", looking for " << autoAAn(r.getVehiclePref()) << " "
|
||||
<< r.getVehiclePref() << " vehicle.\n"
|
||||
<< "Pick Up Location: " << r.getPickupLocationName()
|
||||
<< ", Drop Off Location: " << r.getDropoffLocationName() << ".\n";
|
||||
```
|
||||
|
||||
2. 在处理司机状态的时候要特别小心,一旦有变化要马上更新,因为一些逻辑是依赖于司机状态的。比如当司机从`On_the_way_to_pickup`变为`Available`时,需要清空Rider关联信息,并且再自动为Rider找新司机。重新寻找司机的时候,也要避免重新找到之前已经分配过的司机。
|
||||
3. Class的变量不能是Public(作业要求)的,调用内容必须用方法,而不是直接对变量操作。
|
||||
4. 根据作业要求,我们不能用`auto`类型,这导致我不得不修改了for循环的内容,比如:
|
||||
|
||||
```diff
|
||||
void exportDrivers(const std::string &filename, const std::vector<Driver> &drivers) {
|
||||
//...
|
||||
std::ofstream ofs(filename);
|
||||
- for (const auto &d : drivers) {
|
||||
+ for (int i = 0; i < (int)drivers.size(); i++) {
|
||||
+ const Driver &d = drivers[i];
|
||||
ofs << d.toFileString() << "\n";
|
||||
}
|
||||
ofs.close();
|
||||
}
|
||||
```
|
||||
|
||||
## 参考代码
|
||||
|
||||
### nyrider.cpp
|
||||
|
||||
```cpp
|
||||
//An implement of CSCI-1200 HW2 Ride Sharing
|
||||
//Author: JamesFlare
|
||||
//Date: 2025/1/20
|
||||
//#include <algorithm>
|
||||
//#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "Driver.h"
|
||||
#include "Rider.h"
|
||||
|
||||
void debug_print(const std::string &msg) {
|
||||
std::cout << "DEBUG: " << msg << std::endl;
|
||||
}
|
||||
|
||||
bool isPhoneNumberValid(const std::string &phone)
|
||||
{
|
||||
if (phone.size() != 12) return false;
|
||||
//xxx-xxx-xxxx
|
||||
for (int i = 0; i < 12; i++) {
|
||||
if (i == 3 || i == 7) {
|
||||
if (phone[i] != '-') return false;
|
||||
} else {
|
||||
if (!std::isdigit((unsigned char)phone[i])) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void loadDrivers(std::ifstream &ifs, std::vector<Driver> &drivers) {
|
||||
//read the file line by line, total of 13
|
||||
while (!ifs.eof()) {
|
||||
std::string fName, lName, gender, phone, vehicleType, state;
|
||||
std::string rF, rL, rP;
|
||||
int age;
|
||||
double rating, lat, lon;
|
||||
ifs >> fName >> lName >> gender >> age >> phone >> rating >> lat >> lon
|
||||
>> vehicleType >> state >> rF >> rL >> rP;
|
||||
if (!ifs.fail()) {
|
||||
//change "null" to empty string
|
||||
if (rF == "null") rF = "";
|
||||
if (rL == "null") rL = "";
|
||||
if (rP == "null") rP = "";
|
||||
//create driver
|
||||
Driver d(fName, lName, gender, age, phone, rating, lat, lon,
|
||||
vehicleType, state, rF, rL, rP);
|
||||
drivers.push_back(d);
|
||||
}
|
||||
}
|
||||
ifs.close();
|
||||
}
|
||||
|
||||
void loadRiders(std::ifstream &ifs, std::vector<Rider> &riders) {
|
||||
//read the file line by line, total of 17
|
||||
while (!ifs.eof()) {
|
||||
std::string fName, lName, gender, phone, pickupLoc, dropoffLoc, vPref, state;
|
||||
std::string dF, dL, dP;
|
||||
int age;
|
||||
double rating, pickupLat, pickupLon, dropoffLat, dropoffLon;
|
||||
ifs >> fName >> lName >> gender >> age >> phone >> rating
|
||||
>> pickupLoc >> pickupLat >> pickupLon
|
||||
>> dropoffLoc >> dropoffLat >> dropoffLon
|
||||
>> vPref >> state
|
||||
>> dF >> dL >> dP;
|
||||
if (!ifs.fail()) {
|
||||
//fill null with empty string
|
||||
if (dF == "null") dF = "";
|
||||
if (dL == "null") dL = "";
|
||||
if (dP == "null") dP = "";
|
||||
//create rider
|
||||
Rider r(fName, lName, gender, age, phone, rating,
|
||||
pickupLoc, pickupLat, pickupLon,
|
||||
dropoffLoc, dropoffLat, dropoffLon,
|
||||
vPref, state, dF, dL, dP);
|
||||
riders.push_back(r);
|
||||
}
|
||||
}
|
||||
ifs.close();
|
||||
}
|
||||
|
||||
std::ifstream loadFile(const std::string &filename) {
|
||||
//read file and return ifstream
|
||||
std::ifstream ifs(filename);
|
||||
if (!ifs) {
|
||||
std::cerr << "Error opening file: " << filename << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
return ifs;
|
||||
}
|
||||
|
||||
void saveFile(const std::string &filename, const std::string &msg) {
|
||||
std::ofstream ofs(filename);
|
||||
if (!ofs) {
|
||||
std::cerr << "Error opening file: " << filename << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
ofs << msg;
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
void exportDrivers(const std::string &filename, const std::vector<Driver> &drivers) {
|
||||
//save drivers to file
|
||||
std::ofstream ofs(filename);
|
||||
if (!ofs) {
|
||||
std::cerr << "Error opening output file: " << filename << std::endl;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < (int)drivers.size(); i++) {
|
||||
const Driver &d = drivers[i];
|
||||
ofs << d.toFileString() << "\n";
|
||||
}
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
void exportRiders(const std::string &filename, const std::vector<Rider> &riders) {
|
||||
//save riders to file
|
||||
std::ofstream ofs(filename);
|
||||
if (!ofs) {
|
||||
std::cerr << "Error opening output file: " << filename << std::endl;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < (int)riders.size(); i++) {
|
||||
const Rider &r = riders[i];
|
||||
ofs << r.toFileString() << "\n";
|
||||
}
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
// calculate the distance between two coordinates using Haversine formula
|
||||
double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
|
||||
const double radiusOfEarth = 6371.0; // Earth's radius in kilometers
|
||||
// convert latitude and longitude from degrees to radians
|
||||
lat1 *= M_PI / 180.0;
|
||||
lon1 *= M_PI / 180.0;
|
||||
lat2 *= M_PI / 180.0;
|
||||
lon2 *= M_PI / 180.0;
|
||||
// Haversine formula
|
||||
double dLat = lat2 - lat1;
|
||||
double dLon = lon2 - lon1;
|
||||
double a = sin(dLat / 2.0) * sin(dLat / 2.0) + cos(lat1) * cos(lat2) * sin(dLon / 2.0) * sin(dLon / 2.0);
|
||||
double c = 2.0 * atan2(sqrt(a), sqrt(1.0 - a));
|
||||
// distance in kilometers
|
||||
double distanceKM = radiusOfEarth * c;
|
||||
// convert it to distance in miles
|
||||
double distanceMiles = distanceKM * 0.621371;
|
||||
|
||||
return distanceMiles;
|
||||
}
|
||||
|
||||
int findClosestDriver(const std::vector<Driver> &drivers,
|
||||
const Rider &rider) {
|
||||
double minDistance = 1e9;
|
||||
int bestIndex = -1;
|
||||
for (int i = 0; i < (int)drivers.size(); i++) {
|
||||
const Driver &drv = drivers[i];
|
||||
if (drv.getCurrentState() == "Available" &&
|
||||
drv.getVehicleType() == rider.getVehiclePref()) {
|
||||
double dist = calculateDistance(drv.getLatitude(), drv.getLongitude(),
|
||||
rider.getPickupLatitude(), rider.getPickupLongitude());
|
||||
if (dist < minDistance) {
|
||||
minDistance = dist;
|
||||
bestIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestIndex;
|
||||
}
|
||||
|
||||
int findRiderIndexByPhone(const std::vector<Rider> &riders, const std::string &phone) {
|
||||
for (int i = 0; i < (int)riders.size(); i++) {
|
||||
if (riders[i].getPhoneNumber() == phone) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int findDriverIndexByPhone(const std::vector<Driver> &drivers, const std::string &phone) {
|
||||
for (int i = 0; i < (int)drivers.size(); i++) {
|
||||
if (drivers[i].getPhoneNumber() == phone) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string autoAAn(const std::string &word) {
|
||||
if (word.empty()) return "";
|
||||
if (word[0] == 'A' || word[0] == 'E' || word[0] == 'I' || word[0] == 'O' || word[0] == 'U') {
|
||||
return "an";
|
||||
}
|
||||
return "a";
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
//take 3 arguments
|
||||
if (argc < 8) {
|
||||
std::cout << "Usage: nyride drivers.txt riders.txt output0.txt output1.txt output2.txt phoneNumber [request|cancel]\n" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
//load arguments
|
||||
const std::string drivers_fName = argv[1];
|
||||
const std::string riders_fName = argv[2];
|
||||
std::string msg_fName = argv[3];
|
||||
std::string updated_drivers_fName = argv[4];
|
||||
std::string updated_riders_fName = argv[5];
|
||||
std::string phone_number = argv[6];
|
||||
std::string command = argv[7];
|
||||
//turn on debug mode is last argument is debug
|
||||
bool debug_mode = false;
|
||||
if (std::string(argv[argc - 1]) == "debug") {
|
||||
debug_mode = true;
|
||||
}
|
||||
|
||||
if (debug_mode) {
|
||||
debug_print("drivers_fName = " + drivers_fName);
|
||||
debug_print("riders_fName = " + riders_fName);
|
||||
debug_print("msg_fName = " + msg_fName);
|
||||
debug_print("updated_drivers_fName = " + updated_drivers_fName);
|
||||
debug_print("updated_riders_fName = " + updated_riders_fName);
|
||||
debug_print("phone_number = " + phone_number);
|
||||
debug_print("command = " + command);
|
||||
}
|
||||
//load drivers
|
||||
std::vector<Driver> drivers;
|
||||
std::ifstream drivers_file = loadFile(drivers_fName);
|
||||
loadDrivers(drivers_file, drivers);
|
||||
//load riders
|
||||
std::vector<Rider> riders;
|
||||
std::ifstream riders_file = loadFile(riders_fName);
|
||||
loadRiders(riders_file, riders);
|
||||
if (debug_mode) {
|
||||
debug_print("drivers.size() = " + std::to_string(drivers.size()));
|
||||
debug_print("riders.size() = " + std::to_string(riders.size()));
|
||||
}
|
||||
//check if phone number is valid
|
||||
std::ostringstream msg;
|
||||
if (!isPhoneNumberValid(phone_number)) {
|
||||
std::cout << "Error: Invalid phone number" << std::endl;
|
||||
msg << "Phone number is invalid.\n";
|
||||
saveFile(msg_fName, msg.str());
|
||||
return 1;
|
||||
}
|
||||
//check if command is valid
|
||||
if (command != "request" && command != "cancel") {
|
||||
std::cout << "Error: Invalid command" << std::endl;
|
||||
return 1;
|
||||
} else if (command == "request") {
|
||||
//for request cases
|
||||
int rIdx = findRiderIndexByPhone(riders, phone_number);
|
||||
if (rIdx == -1) {
|
||||
//if rider does not exist
|
||||
msg << "Account does not exist.\n";
|
||||
saveFile(msg_fName, msg.str());
|
||||
return 1;
|
||||
}
|
||||
Rider &r = riders[rIdx];
|
||||
//check rider
|
||||
if (r.getCurrentState() == "Driver_on_the_way") {
|
||||
msg << "You have already requested a ride and your driver is on the way to the pickup location.\n";
|
||||
saveFile(msg_fName, msg.str());
|
||||
return 1;
|
||||
}
|
||||
if (r.getCurrentState() == "During_the_trip") {
|
||||
msg << "You can not request a ride at this moment as you are already on a trip.\n";
|
||||
saveFile(msg_fName, msg.str());
|
||||
return 1;
|
||||
}
|
||||
if (r.getCurrentState() == "Ready_to_request") {
|
||||
msg << "Ride requested for rider " << r.getFirstName()
|
||||
<< ", looking for " << autoAAn(r.getVehiclePref()) << " "
|
||||
<< r.getVehiclePref() << " vehicle.\n"
|
||||
<< "Pick Up Location: " << r.getPickupLocationName()
|
||||
<< ", Drop Off Location: " << r.getDropoffLocationName() << ".\n";
|
||||
//find closest driver
|
||||
int dIdx = findClosestDriver(drivers, r);
|
||||
if (dIdx == -1) {
|
||||
//no driver
|
||||
msg << "Sorry we can not find a driver for you at this moment.\n";
|
||||
} else {
|
||||
Driver &d = drivers[dIdx];
|
||||
double dist = calculateDistance(d.getLatitude(), d.getLongitude(),
|
||||
r.getPickupLatitude(), r.getPickupLongitude());
|
||||
dist = (int)(dist * 10) / 10.0; //cut to 1 decimal
|
||||
msg << "We have found the closest driver " << d.getFirstName() << "("
|
||||
<< std::fixed << std::setprecision(1) << d.getRating() << ") for you.\n"
|
||||
<< d.getFirstName() << " is now "
|
||||
<< std::fixed << std::setprecision(1) << dist
|
||||
<< " miles away from you.\n";
|
||||
//update status
|
||||
d.setCurrentState("On_the_way_to_pickup");
|
||||
d.setRiderInfo(r.getFirstName(), r.getLastName(), r.getPhoneNumber());
|
||||
r.setCurrentState("Driver_on_the_way");
|
||||
r.setDriverInfo(d.getFirstName(), d.getLastName(), d.getPhoneNumber());
|
||||
}
|
||||
}
|
||||
} else if (command == "cancel") {
|
||||
//for cancel cases
|
||||
//find phone_number in riders
|
||||
int rIdx = findRiderIndexByPhone(riders, phone_number);
|
||||
if (rIdx == -1) {
|
||||
//in case of driver's cancel
|
||||
int dIdx = findDriverIndexByPhone(drivers, phone_number);
|
||||
if (dIdx == -1) {
|
||||
//in case of not both rider and driver
|
||||
msg << "Account does not exist.\n";
|
||||
saveFile(msg_fName, msg.str());
|
||||
return 1;
|
||||
}
|
||||
Driver &driver = drivers[dIdx];
|
||||
if (driver.getCurrentState() != "On_the_way_to_pickup") {
|
||||
msg << "You can only cancel a ride request if you are currently on the way to the pickup location.\n";
|
||||
saveFile(msg_fName, msg.str());
|
||||
return 1;
|
||||
}
|
||||
//get rider's phone number
|
||||
std::string rPh = driver.getRiderPhoneNumber();
|
||||
//clean driver's rider info
|
||||
driver.setCurrentState("Available");
|
||||
driver.setRiderInfo("", "", "");
|
||||
msg << "Your driver " << driver.getFirstName()
|
||||
<< " has canceled the ride request. We will now find a new driver for you.\n";
|
||||
//find rider
|
||||
int theRiderIdx = findRiderIndexByPhone(riders, rPh);
|
||||
Rider &r = riders[theRiderIdx];
|
||||
//reset rider
|
||||
r.setCurrentState("Ready_to_request");
|
||||
r.setDriverInfo("", "", "");
|
||||
//find a new driver
|
||||
msg << "Ride requested for rider " << r.getFirstName()
|
||||
<< ", looking for " << autoAAn(r.getVehiclePref()) << " "
|
||||
<< r.getVehiclePref() << " vehicle.\n"
|
||||
<< "Pick Up Location: " << r.getPickupLocationName()
|
||||
<< ", Drop Off Location: " << r.getDropoffLocationName() << ".\n";
|
||||
int newDIdx = findClosestDriver(drivers, r);
|
||||
if (newDIdx == -1) {
|
||||
msg << "Sorry we can not find a driver for you at this moment.\n";
|
||||
} else {
|
||||
Driver &newDriver = drivers[newDIdx];
|
||||
double dist = calculateDistance(newDriver.getLatitude(), newDriver.getLongitude(),
|
||||
r.getPickupLatitude(), r.getPickupLongitude());
|
||||
dist = (int)(dist * 10) / 10.0; //cut to 1 decimal
|
||||
msg << "We have found the closest driver " << newDriver.getFirstName() << "("
|
||||
<< std::fixed << std::setprecision(1) << newDriver.getRating() << ") for you.\n"
|
||||
<< newDriver.getFirstName() << " is now "
|
||||
<< std::fixed << std::setprecision(1) << dist
|
||||
<< " miles away from you.\n";
|
||||
//update driver's status
|
||||
newDriver.setCurrentState("On_the_way_to_pickup");
|
||||
newDriver.setRiderInfo(r.getFirstName(), r.getLastName(), r.getPhoneNumber());
|
||||
//update rider's status
|
||||
r.setCurrentState("Driver_on_the_way");
|
||||
r.setDriverInfo(newDriver.getFirstName(), newDriver.getLastName(), newDriver.getPhoneNumber());
|
||||
}
|
||||
} else {
|
||||
//in case of rider's cancel
|
||||
Rider &rider = riders[rIdx];
|
||||
if (rider.getCurrentState() != "Driver_on_the_way") {
|
||||
msg << "You can only cancel a ride request if your driver is currently on the way to the pickup location.\n";
|
||||
saveFile(msg_fName, msg.str());
|
||||
return 1;
|
||||
}
|
||||
//find driver's phone_number
|
||||
std::string dPh = rider.getDriverPhoneNumber();
|
||||
msg << "Ride request for rider " << rider.getFirstName()
|
||||
<< " is now canceled by the rider.\n";
|
||||
//set driver's status to Available
|
||||
int dIdx = findDriverIndexByPhone(drivers, dPh);
|
||||
if (dIdx != -1) {
|
||||
Driver &drv = drivers[dIdx];
|
||||
drv.setCurrentState("Available");
|
||||
drv.setRiderInfo("", "", "");
|
||||
}
|
||||
//set rider's status to Ready_to_request
|
||||
rider.setCurrentState("Ready_to_request");
|
||||
rider.setDriverInfo("", "", "");
|
||||
}
|
||||
}
|
||||
//save msg
|
||||
saveFile(msg_fName, msg.str());
|
||||
//save updated drivers and riders
|
||||
exportDrivers(updated_drivers_fName, drivers);
|
||||
exportRiders(updated_riders_fName, riders);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### Rider.h
|
||||
|
||||
```cpp
|
||||
#ifndef __RIDER_H
|
||||
#define __RIDER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class Rider {
|
||||
private:
|
||||
std::string firstName;
|
||||
std::string lastName;
|
||||
std::string gender;
|
||||
int age;
|
||||
std::string phoneNumber;
|
||||
double rating;
|
||||
std::string pickupLocationName;
|
||||
double pickupLatitude;
|
||||
double pickupLongitude;
|
||||
std::string dropoffLocationName;
|
||||
double dropoffLatitude;
|
||||
double dropoffLongitude;
|
||||
std::string vehiclePref;
|
||||
std::string currentState;
|
||||
//driver's info
|
||||
std::string driverFirstName;
|
||||
std::string driverLastName;
|
||||
std::string driverPhoneNumber;
|
||||
|
||||
public:
|
||||
//init
|
||||
Rider();
|
||||
Rider(const std::string &fName, const std::string &lName,
|
||||
const std::string &gen, int a, const std::string &phone,
|
||||
double r, const std::string &pickupLocName, double pickupLat, double pickupLon,
|
||||
const std::string &dropoffLocName, double dropoffLat, double dropoffLon,
|
||||
const std::string &vehiclePref, const std::string &state,
|
||||
const std::string &dF, const std::string &dL, const std::string &dP);
|
||||
|
||||
//getters & setters
|
||||
const std::string& getFirstName() const;
|
||||
const std::string& getLastName() const;
|
||||
const std::string& getGender() const;
|
||||
int getAge() const;
|
||||
const std::string& getPhoneNumber() const;
|
||||
double getRating() const;
|
||||
const std::string& getPickupLocationName() const;
|
||||
double getPickupLatitude() const;
|
||||
double getPickupLongitude() const;
|
||||
const std::string& getDropoffLocationName() const;
|
||||
double getDropoffLatitude() const;
|
||||
double getDropoffLongitude() const;
|
||||
const std::string& getVehiclePref() const;
|
||||
const std::string& getCurrentState() const;
|
||||
const std::string& getDriverFirstName() const;
|
||||
const std::string& getDriverLastName() const;
|
||||
const std::string& getDriverPhoneNumber() const;
|
||||
|
||||
void setCurrentState(const std::string &state);
|
||||
void setDriverInfo(const std::string &df, const std::string &dl, const std::string &dp);
|
||||
//return a string representation of the rider
|
||||
std::string toFileString() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
```
|
||||
|
||||
### Rider.cpp
|
||||
|
||||
```cpp
|
||||
#include "Rider.h"
|
||||
#include <sstream>
|
||||
|
||||
Rider::Rider()
|
||||
: age(0), rating(0.0), pickupLatitude(0.0), pickupLongitude(0.0),
|
||||
dropoffLatitude(0.0), dropoffLongitude(0.0) {}
|
||||
|
||||
Rider::Rider(const std::string &fName, const std::string &lName,
|
||||
const std::string &gen, int a, const std::string &phone,
|
||||
double r, const std::string &pickupLocName, double pickupLat, double pickupLon,
|
||||
const std::string &dropoffLocName, double dropoffLat, double dropoffLon,
|
||||
const std::string &vPref, const std::string &state,
|
||||
const std::string &dF, const std::string &dL, const std::string &dP)
|
||||
: firstName(fName), lastName(lName), gender(gen), age(a),
|
||||
phoneNumber(phone), rating(r),
|
||||
pickupLocationName(pickupLocName), pickupLatitude(pickupLat), pickupLongitude(pickupLon),
|
||||
dropoffLocationName(dropoffLocName), dropoffLatitude(dropoffLat), dropoffLongitude(dropoffLon),
|
||||
vehiclePref(vPref), currentState(state),
|
||||
driverFirstName(dF), driverLastName(dL), driverPhoneNumber(dP) {}
|
||||
|
||||
const std::string& Rider::getFirstName() const { return firstName; }
|
||||
const std::string& Rider::getLastName() const { return lastName; }
|
||||
const std::string& Rider::getGender() const { return gender; }
|
||||
int Rider::getAge() const { return age; }
|
||||
const std::string& Rider::getPhoneNumber() const { return phoneNumber; }
|
||||
double Rider::getRating() const { return rating; }
|
||||
const std::string& Rider::getPickupLocationName() const { return pickupLocationName; }
|
||||
double Rider::getPickupLatitude() const { return pickupLatitude; }
|
||||
double Rider::getPickupLongitude() const { return pickupLongitude; }
|
||||
const std::string& Rider::getDropoffLocationName() const { return dropoffLocationName; }
|
||||
double Rider::getDropoffLatitude() const { return dropoffLatitude; }
|
||||
double Rider::getDropoffLongitude() const { return dropoffLongitude; }
|
||||
const std::string& Rider::getVehiclePref() const { return vehiclePref; }
|
||||
const std::string& Rider::getCurrentState() const { return currentState; }
|
||||
const std::string& Rider::getDriverFirstName() const { return driverFirstName; }
|
||||
const std::string& Rider::getDriverLastName() const { return driverLastName; }
|
||||
const std::string& Rider::getDriverPhoneNumber() const { return driverPhoneNumber; }
|
||||
|
||||
void Rider::setCurrentState(const std::string &state) {
|
||||
currentState = state;
|
||||
}
|
||||
|
||||
void Rider::setDriverInfo(const std::string &df, const std::string &dl, const std::string &dp) {
|
||||
driverFirstName = df;
|
||||
driverLastName = dl;
|
||||
driverPhoneNumber = dp;
|
||||
}
|
||||
|
||||
std::string Rider::toFileString() const {
|
||||
//Isabella
|
||||
//Richard
|
||||
//Female
|
||||
//39
|
||||
//301-144-6533
|
||||
//3.2
|
||||
//Top_of_the_Rock
|
||||
//40.7593 -73.979
|
||||
//Gowanus
|
||||
//40.6733
|
||||
//-73.99
|
||||
//Economy
|
||||
//Ready_to_request
|
||||
//null
|
||||
//null
|
||||
//null
|
||||
std::ostringstream oss;
|
||||
oss << firstName << " "
|
||||
<< lastName << " "
|
||||
<< gender << " "
|
||||
<< age << " "
|
||||
<< phoneNumber << " "
|
||||
<< rating << " "
|
||||
<< pickupLocationName << " "
|
||||
<< pickupLatitude << " "
|
||||
<< pickupLongitude << " "
|
||||
<< dropoffLocationName << " "
|
||||
<< dropoffLatitude << " "
|
||||
<< dropoffLongitude << " "
|
||||
<< vehiclePref << " "
|
||||
<< currentState << " "
|
||||
<< (driverFirstName.empty() ? "null" : driverFirstName) << " "
|
||||
<< (driverLastName.empty() ? "null" : driverLastName) << " "
|
||||
<< (driverPhoneNumber.empty() ? "null" : driverPhoneNumber);
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
```
|
||||
|
||||
### Driver.h
|
||||
|
||||
```cpp
|
||||
#ifndef __DRIVER_H
|
||||
#define __DRIVER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class Driver {
|
||||
private:
|
||||
std::string firstName;
|
||||
std::string lastName;
|
||||
std::string gender;
|
||||
int age;
|
||||
std::string phoneNumber;
|
||||
double rating;
|
||||
double latitude;
|
||||
double longitude;
|
||||
std::string vehicleType;
|
||||
std::string currentState;
|
||||
//rider's info
|
||||
std::string riderFirstName;
|
||||
std::string riderLastName;
|
||||
std::string riderPhoneNumber;
|
||||
|
||||
public:
|
||||
//init
|
||||
Driver();
|
||||
Driver(const std::string &firstName, const std::string &lastName,
|
||||
const std::string &gender, int age, const std::string &phoneNumber,
|
||||
double rating, double latitude, double longitude,
|
||||
const std::string &vehicleType, const std::string ¤tState,
|
||||
const std::string &riderFirstName, const std::string &riderLastName,
|
||||
const std::string &riderPhoneNumber);
|
||||
|
||||
//getters & setters
|
||||
const std::string& getFirstName() const;
|
||||
const std::string& getLastName() const;
|
||||
const std::string& getGender() const;
|
||||
int getAge() const;
|
||||
const std::string& getPhoneNumber() const;
|
||||
double getRating() const;
|
||||
double getLatitude() const;
|
||||
double getLongitude() const;
|
||||
const std::string& getVehicleType() const;
|
||||
const std::string& getCurrentState() const;
|
||||
const std::string& getRiderFirstName() const;
|
||||
const std::string& getRiderLastName() const;
|
||||
const std::string& getRiderPhoneNumber() const;
|
||||
|
||||
void setCurrentState(const std::string &state);
|
||||
void setRiderInfo(const std::string &rf, const std::string &rl, const std::string &rp);
|
||||
//return a string representation of the driver
|
||||
std::string toFileString() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
```
|
||||
|
||||
### Driver.cpp
|
||||
|
||||
```cpp
|
||||
#include "Driver.h"
|
||||
#include <sstream>
|
||||
|
||||
Driver::Driver() : age(0), rating(0.0), latitude(0.0), longitude(0.0) {}
|
||||
|
||||
Driver::Driver(const std::string &fName, const std::string &lName,
|
||||
const std::string &gen, int a, const std::string &phone,
|
||||
double r, double lat, double lon,
|
||||
const std::string &vehType, const std::string &state,
|
||||
const std::string &rF, const std::string &rL,
|
||||
const std::string &rP)
|
||||
: firstName(fName), lastName(lName), gender(gen), age(a),
|
||||
phoneNumber(phone), rating(r), latitude(lat), longitude(lon),
|
||||
vehicleType(vehType), currentState(state),
|
||||
riderFirstName(rF), riderLastName(rL), riderPhoneNumber(rP) {}
|
||||
|
||||
//getters
|
||||
const std::string& Driver::getFirstName() const { return firstName; }
|
||||
const std::string& Driver::getLastName() const { return lastName; }
|
||||
const std::string& Driver::getGender() const { return gender; }
|
||||
int Driver::getAge() const { return age; }
|
||||
const std::string& Driver::getPhoneNumber() const { return phoneNumber; }
|
||||
double Driver::getRating() const { return rating; }
|
||||
double Driver::getLatitude() const { return latitude; }
|
||||
double Driver::getLongitude() const { return longitude; }
|
||||
const std::string& Driver::getVehicleType() const { return vehicleType; }
|
||||
const std::string& Driver::getCurrentState() const { return currentState; }
|
||||
const std::string& Driver::getRiderFirstName() const { return riderFirstName; }
|
||||
const std::string& Driver::getRiderLastName() const { return riderLastName; }
|
||||
const std::string& Driver::getRiderPhoneNumber() const { return riderPhoneNumber; }
|
||||
|
||||
//setters
|
||||
void Driver::setCurrentState(const std::string &state) {
|
||||
currentState = state;
|
||||
}
|
||||
|
||||
void Driver::setRiderInfo(const std::string &rf, const std::string &rl, const std::string &rp) {
|
||||
riderFirstName = rf;
|
||||
riderLastName = rl;
|
||||
riderPhoneNumber = rp;
|
||||
}
|
||||
|
||||
std::string Driver::toFileString() const {
|
||||
//Sandra
|
||||
//Huang
|
||||
//Female
|
||||
//25
|
||||
//853-977-5304
|
||||
//3.1
|
||||
//40.4269
|
||||
//-73.0753
|
||||
//Standard
|
||||
//On_the_way_to_pickup
|
||||
//Michael
|
||||
//Richard
|
||||
//445-915-1645
|
||||
std::ostringstream oss;
|
||||
oss << firstName << " "
|
||||
<< lastName << " "
|
||||
<< gender << " "
|
||||
<< age << " "
|
||||
<< phoneNumber << " "
|
||||
<< rating << " "
|
||||
<< latitude << " "
|
||||
<< longitude << " "
|
||||
<< vehicleType << " "
|
||||
<< currentState << " "
|
||||
<< (riderFirstName.empty() ? "null" : riderFirstName) << " "
|
||||
<< (riderLastName.empty() ? "null" : riderLastName) << " "
|
||||
<< (riderPhoneNumber.empty() ? "null" : riderPhoneNumber);
|
||||
return oss.str();
|
||||
}
|
||||
```
|
||||
|
||||
BIN
content/zh-cn/posts/csci-1200/hw-2/ride_sharing.7z
Normal file
BIN
content/zh-cn/posts/csci-1200/hw-2/ride_sharing.7z
Normal file
Binary file not shown.
Reference in New Issue
Block a user