Description
- Write C++ programs
- Compile C++ programs
- Implement programs that involve method method overriding, and polymorhpism.
Additional Reading
This lab exercise requires an understanding of some concepts to solve the problems. You are strongly encouraged to read the following tutorials to help you answer the problems.
- Organizing C++ files: function prototypes, implementations, and drivers.
- Using objects as parameters and return values in functions
- Passing arrays as parameters to functions
- File reading and writing (also includes dealing with arrays)
Instructions
Answer the programming problems sequentially (i.e., answer prob01 before prob02). If you have questions let your instructor or the lab assistant know. You can also consult your classmates.
When you answer two programming problems correctly, let your instructor know and wait for further instruction.
Lab exercise guide
Here’s a link to the Lab exercise guide in case you need to review the lab exercise objectives, grading scheme, or evaluation process.
Driving management software
You will be creating a base class Car
 and two derived classes GasolineCar
 and ElectricCar
. The user interface is mostly implemented for you. The focus of this exercise is to demonstrate polymorphism through virtual functions and pointers to derived classes.
Car class
This class is almost complete so you only need to implement two functions:Â drive
 and is_empty
. However, here is a rundown of the member functions you will have to use/create.
Data members
Create a class called Car
. It will have the following data members
name_
 which is anÂstd::string
 that will be the name of the caryear_
 which is anÂint
 that will be the manufacturing year for that carspeed_
 which is aÂdouble
 that will be the current speed of the car
Member functions
Public Methods
default constructor
name_
 should be initialized toÂ"Steam automobile"
.year_
 should be initialized toÂ1769
speed_
 should be initialized toÂ0
non default constructor
The constructor initializes the following variables
For parameters it needs:
std::string name
 for the name of the car.double year
 for year if the car.
and it initializes the member variables name_
 and year_
 with these parameters. additionally, speed_
 gets initialized to 0
accessors
Create functions that will return each of our data members.
std::string name()
 returns theÂname_
 of the carint year()
 returns theÂyear_
 of the cardouble speed()
 returns theÂspeed_
 of the car
mutators
Create functions that will modify the member variables
void set_name()
 sets theÂname_
 of the carvoid set_year()
 sets theÂyear_
 of the car
drive
Receives a single double
 parameter that sets the speed_
 of the car according to the value provided. This should be a virtual function that derived classes can use/override.
is_empty
Define this as a virtual function that always returns false. It will be overridden in the derived classes.
ElectricCar class
Data members
Create a class called ElectricCar
It will be a class we create that inherits from the Car
 class. It will have one additional data member
battery_percentage_
 which is a double
 that represents the battery percentage.
Member functions
Public Methods
non default constructor
The constructor initializes the following variables
For parameters it needs:
std::string name
 for the name of the carint year
 for the year of the car
and it initializes the appropriate member variables with these parameters. additionally it sets speed_
 to 0
, and sets battery_percentage_
 to 100.0
default constructor
The default constructor should set name_
 to "Electric carriage"
, year_
 to 1832
, speed_
 to 0
 and battery_percentage_
 to100.0
.
bool is_empty()
Returns true if battery_percentage_
 is 0.
drive(double speed)
This override function will perform two steps.
- IF the battery percentage is above 0, then it should callÂ
drive
 from theÂCar
 object and updateÂbattery_percentage_
. The value subtracted from the battery percentage is equal toÂ(speed/4)
. Specifically,Âbattery_percentage_ -=(speed/4)
- IF the remainingÂ
battery_percentage_
 after Step 1 has fallen to or below 0, then callÂCar
‘s drive method to set its speed to 0.
GasolineCar class
Data members
Create a class called GasolineCar
 It will be a class derived from the Car
 class and has two additional data members.
tank_
 which is aÂdouble
 that represents the number of gallons a car’s fuel tank can store.mpg_
 which is aÂdouble
 that represents the miles per gallon a car can travel.
Member functions
Public Methods
non default constructor
The constructor initializes the following variables
For parameters it needs:
std::string name
 for the name of the carint year
 for the year of the cardouble tank
 for the amount of fuel this car can storedouble mpg
 for the fuel efficiency for this car.
and it initializes the appropriate member variables with these parameters. additionally it sets speed_
 to 0.
default constructor
The default constructor should set name_
 to "Gasoline car"
, year_
 to 1885
, tank_
 to 12
, mpg_
 to 24, and speed_
 to 0.
bool is_empty()
Returns true if tank_
 is 0.
void drive(double speed)
This override function will perform two steps.
- IF the amount of fuel left in theÂ
tank_
 is above 0, then it should callÂdrive
 from theÂCar
 object and updateÂtank_
. The value subtracted fromÂtank_
 is equal toÂ(speed/mpg_)
. Specifically,Âtank_ -=(speed/mpg_)
- IF the remaining amount inÂ
tank_
 after Step 1 has fallen to or below 0, then callÂCar
‘s drive method to set its speed to 0.
Other instructions
Complete the main
 function as described. Place your classes in car.hpp
. Member functions that take more than five lines or use complex constructs should have their function prototype in car.hpp
 and implementation in car.cpp
.
Sample Output 1
Ubiquitous on-board driving management software test: - Gas/battery level sensor - What type of car is being tested? 1 - Gasoline Car 2 - Electric Car 0 - Exit 1 What is the name of the car? Toyota What year is the car? 1996 How many gallons of gas can this car store? 13 How much MPG does this car have? 27 How fast do you want to drive this car for an hour? 50 It took Toyota about 8 hour(s) of driving to empty the tank
Sample Output2
Ubiquitous on-board driving management software test: - Gas/battery level sensor - What type of car is being tested? 1 - Gasoline Car 2 - Electric Car 0 - Exit 2 What is the name of the car? Tesla What year is the car? 2017 How fast do you want to drive this car for an hour? 60 It took Tesla about 7 hour(s) of driving to empty the battery
Submission checklist
- Created function prototype and stored inÂ
.hpp
 file. - Created function implementation and stored inÂ
.cpp
 file (see reference). - Call function in the driver
- Compiled and ran the driver (
main
). - Manually checked for compilation and logical errors.
- Ensured no errors on the unit test (
make test
). - Followed advice from the stylechecker (
make stylecheck
). - Followed advice from the formatchecker to improve code readbility (
make formatcheck
).
Code evaluation
Open the terminal and navigate to the folder that contains this exercise. Assuming you have pulled the code inside of /home/student/labex02-tuffy
 and you are currently in /home/student
 you can issue the following commands
cd labex02-tuffy
You also need to navigate into the problem you want to answer. To access the files needed to answer problem 1, for example, you need to issue the following command.
cd prob01
When you want to answer another problem, you need to go back up to the parent folder and navigate into the next problem. Assuming you are currently in prob01
, you can issue the following commands to go to the parent folder then go into another problem you want to answer;Â prob02
 for example.
cd ..
cd prob02
Use the clang++
 command to compile your code and the ./
 command to run it. The sample code below shows how you would compile code saved in car.cpp
 and main.cpp
, and into the executable file main
. Make sure you use the correct filenames required in this problem. Take note that if you make any changes to your code, you will need to compile it first before you see changes when running it.
clang++ -std=c++17 main.cpp car.cpp -o main
./main
You can run one, two, or all the commands below to test
 your code, stylecheck
 your code’s design, or formatcheck
 your work. Kindly make sure that you have compiled and executed your code before issuing any of the commands below to avoid errors.
make test
make stylecheck
make formatcheck
A faster way of running all these tests uses the all
 parameter.
make all
Weapons classes
This program uses four classes:Â Weapon
, Dagger
, ShortSword
, and Enemy
. Implement the classes in weapons.hpp
 and weapons.cpp
.
Weapon class
Create a Weapon
 class with the data members int
 attack_min_
, int
 attack_max_
, and std::string
 name
.
Create a default constructor for Weapon
 that sets the attack_min_
 to 1, attack_max_
 to 2, and name_
 to "weapon"
; in that order.
Create a constructor that receives two int
s for attack min and max, and an std::string
 for its name.
Create accessors for all data members.
Create a virtual function attack
 that returns an int
 representing the amount of damage done by the weapon. The math for the attack function should be: (random_number % (max - min)) + min
Random numbers can be generated by calling the rand()
 function that is declared in the random
 header. That is, you need to #include <random>
.
Daggers class
Create a Daggers
 class with data members int
 crit_
, and int
 crit_dice_
. Daggers inherit from Weapon
.
Create a default constructor for Dagger
 that will set attack_min_
 to 2, attack_max_
 to 3, and the name_
 to "daggers"
. It should also set crit_
 to 1, and crit_dice_
 to 18.
Create a constructor that receives two int
s for attack_min_
 and attack_max_
, an std::string
 for the name_
, an int
 for crit_
, and an int
 for crit_dice_
. Take note that you can call Weapon
s constructor.
Create accessors for all data members.
Unlike the usual Weapon
 that only computes damage once, daggers can do damage twice and also have a chance to critically damage an enemy. See the details below to get the value returned by attack()
.
Damage 1:
- Compute damage the same way as theÂ
Weapon
‘s attack function:Â(random_number % (max - min)) + min
. - Randomly generate a number between 1 and 20. If the number is greater than or equal toÂ
crit_dice_
 then multiply the damage from step 1 by the value ofÂcrit_
.
Damage 2:
- Compute damage the same way as theÂ
weapon
‘s attack function:Â(random_number % (max - min)) + min
. - Randomly generate a number between 1 and 20. If the number is greater than or equal toÂ
crit_dice_
 then multiply the damage from step 1 by the value ofÂcrit_
.
The attack()
 function should return the sum of damage 1 and damage 2 described above. Take note that damage 1 and damage 2 could produce different values.
ShortSword class
Create a ShortSword
 class with the data member int
 multiplier_
. ShortSword
 inherits from Weapon
.
Create a default constructor for ShortSword
 that sets attack_min_
 to 6, attack_max_
 to 7, the name_
 to "shortsword"
, and multiplier_
 to 1.
Create a constructor that receives two int
s for attack_min_
 and atack_max_
, an std::string
 for name_
 and a int
 for the multiplier_
.
Create accessors for all data members.
Override the attack
 function to provide a damage multiplier. The steps below describe how to compute the output of the function.
- Compute damage the same way as theÂ
Weapon
‘s attack function:Â(random_number % (max - min)) + min
. - Randomly generate a number between 1 and theÂ
multiplier_
 (for example, 1 to 4 if the multiplier is 4). The function should return the damage multiplied to the randomly generated number.
Enemy class
Create an Enemy
 class with two data members, an std::string
 name_
, an int
 health_
.
Create a default constructor for Enemy
 that sets name_
 to "dragon"
 and health_
 to 500.
Create a constructor that receives an std::string
 name
 and int
 health
 the assigns it to the data members accordingly.
Create a function called receive_attack
 that receives a pointer to a Weapon
 object. Call the Weapon
 object’s attack
 function and reduce the Enemy
‘s health by that damage, then print out the damage statement:Â <weapon> dealt <X> damage to <enemy>
. If the enemy takes lethal damage, print out:Â <enemy> has been slain!
 (replace the values inside < > with the actual values of the object). See the output below to see an actual example.
Other instructions
Complete the main
 function as described. Place your classes in weapons.hpp
. Member functions that take more than five lines or use complex constructs should have their function prototype in weapons.hpp
 and implementation in weapons.cpp
.
Sample Output:
Please enter the name of an enemy: goblin Please enter the enemy's health: 10 daggers dealt 4 damage to goblin shortsword dealt 6 damage to goblin goblin has been slain!
Submission checklist
- Created function prototype and stored inÂ
.hpp
 file. - Created function implementation and stored inÂ
.cpp
 file (see reference). - Call function in the driver
- Compiled and ran the driver (
main
). - Manually checked for compilation and logical errors.
- Ensured no errors on the unit test (
make test
). - Followed advice from the stylechecker (
make stylecheck
). - Followed advice from the formatchecker to improve code readbility (
make formatcheck
).
Code evaluation
Open the terminal and navigate to the folder that contains this exercise. Assuming you have pulled the code inside of /home/student/labex02-tuffy
 and you are currently in /home/student
 you can issue the following commands
cd labex02-tuffy
You also need to navigate into the problem you want to answer. To access the files needed to answer problem 1, for example, you need to issue the following command.
cd prob01
When you want to answer another problem, you need to go back up to the parent folder and navigate into the next problem. Assuming you are currently in prob01
, you can issue the following commands to go to the parent folder then go into another problem you want to answer;Â prob02
 for example.
cd ..
cd prob02
Use the clang++
 command to compile your code and the ./
 command to run it. The sample code below shows how you would compile code saved in weapons.cpp
 and main.cpp
, and into the executable file main
. Make sure you use the correct filenames required in this problem. Take note that if you make any changes to your code, you will need to compile it first before you see changes when running it.
clang++ -std=c++17 main.cpp weapons.cpp -o main
./main
You can run one, two, or all the commands below to test
 your code, stylecheck
 your code’s design, or formatcheck
 your work. Kindly make sure that you have compiled and executed your code before issuing any of the commands below to avoid errors.
make test
make stylecheck
make formatcheck
A faster way of running all these tests uses the all
 parameter.
make all