# Chapter 9 - Worked Exercises

## Exercise 1 - Drones Delivering Pizzas&#x20;

You are to create a program that simulates a pizza delivery service handled by drones.&#x20;

Each delivery runs as follows:

* A pizza of weight, `weight`, grams is prepared.
* The pizza is cooked and loaded onto a drone at location, described as a set of coordinates, `x` and `y`, and an altitude, `altitude`.&#x20;
* The drone ascends to a certain altitude, then flies to another location, then descends.&#x20;
* The drone then releases the pizza.&#x20;

You are given the following class definitions and method prototypes, your task is to implement each of the methods.

```cpp
class Pizza {
private:
    float weight;
public:
    Pizza(float weight);  // Creates a pizza with an initial weight 
    
    void cook();  // Cooks the pizza, which reduces its weight by 15%
}
```

```cpp
class Drone {
private:
    int x, y, altitude;
    Pizza* pizza;

public:
    Drone(int x, int y);  // Each drone starts at altitude 0
    
    void load(Pizza* pizza);  // Loads the pizza onto the drone 
    
    void flyTo(int x, int y);  // Flies the drone to position x, y
    
    void flyTo(int altitude);  // Ascends/descends the drone to the given altitude
    
    Pizza* release();  // Releases the pizza, and returns it to the caller 
}
```

### Example&#x20;

Here is an example of how the program should run:

```cpp
int main() {
    // A Margherita pizza of weight 512 grams is prepared
    Pizza* pizza = new Pizza(512);
    
    // The pizza is cooked and then loaded onto a drone at
    // location (10, 12)
    pizza->cook();
    Drone* drone = new Drone(10, 12);
    drone->load(pizza);
    
    // The drone climbs to altitude 80m
    drone->flyTo(80);
    
    // The drone flies to location (50, -10, 31.5) where it
    // descends and releases the pizza
    drone->flyTo(50, -10);
    drone->flyTo(0);
    Pizza* receive = drone->release();
    
    /*
     The drone returns to location (10, 12, 0)
    */
    drone->flyTo(10, 12, 0);
    
    delete drone;  // Delete the drone 
    delete pizza;  // Delete the pizza 
}
```

The program should output the following:

```
Cooking pizza of weight 512g.
Done cooking - new pizza weight is 435.2g.
Ascending to 80 meters...
Travelling to 50, -10...
Descending to 0 meters...
Dropping the pizza...
Travelling to 10, 12...
```

### Keep In Mind

* Make sure that in all cases your classes do not leak memory.&#x20;
  * If a drone was deleted before the pizza it was holding was released, it must make sure to clean up after itself.
  * The drone should print `This drone is not carrying any pizza!` and return a `nullptr` if no pizza was loaded onto it, and `drone->release()` was called
* Use list initialisers whenever possible.

## Exercise 2 - Security System&#x20;

You are to create a program that simulates a security system, consisting of "properties", and "guards".&#x20;

You are given the following class definition for `Guard`:&#x20;

```cpp
class Guard {
private:
    std::string name;
    Property* property;  // A pointer to the property that the guard is guarding 
    
public:
    // Each guard initially guards nothing (i.e. property == nullptr)
    Guard(std::string name) : name(name), property(nullptr) {};
    
    void alert() {
        std::cout << name << " has been alerted!" << std::endl;
    }
    
    std::string getName() {
        return name;
    }
    
    std::string setProperty(Property* some_property) {
        property = some_property;
    }
}
```

You are to create a `Property` class with the following characteristics:

* Each property has a name, and an array of `Guard`s that guard its premise&#x20;
* Each property is said to "own" its guards, meaning if a property is destroyed, it is responsible for deleting any guards assigned to it.&#x20;

with the following methods:

* `alertAllGuards`: calls the `.alert()` method on all its guards&#x20;
* `addGuard`: which accepts a pointer to a `Guard`, which then guards its premises&#x20;
* `removeGuard`: which accepts a pointer to a `Guard`, and removes it from the list of guards guarding its premises&#x20;

### Example&#x20;

Here is an example of how the program should run:

```cpp
int main() {
    // Kensington Palace is a property 
    Property* kensington = new Property("Kensington Palace"); 
    
    // We create three guards
    Guard* alice = new Guard("Alice");
    Guard* bob = new Guard("Bob");
    Guard* charlie = new Guard("Charlie");
    
    // and then add them each to Kensington Palace 
    kensington->addGuard(alice);
    kensington->addGuard(bob);
    kensington->addGuard(charlie);
    
    // We alert all the guards in Kensington Palace 
    kensington->alertAllGuards();
    
    // We remove Alice from Kensington Palace
    kensington->removeGuard(alice);
    
    // We alert all the guards once more 
    kensington->alertAllGuards();
    
    // Since Bob and Charlie are owned by this property
    // they should be automatically deleted here 
    delete kensington; 
    // Delete Alice manually since she was removed earlier 
    delete alice;
}
```

The program should output the following:

```
Alice is now guarding Kensington Palace.
Bob is now guarding Kensington Palace.
Charlie is now guarding Kensington Palace.
Alice has been alerted!
Bob has been alerted!
Charlie has been alerted!
Alice has been removed from Kensington Palace.
Bob has been alerted!
Charlie has been alerted!
```

### Hints&#x20;

* You may find using `std::vector<Guard*>` a useful data structure to store the guards at a particular property.&#x20;

## Exercise 3 - Best Friends&#x20;

You are to create a `Person` class, with the following specifications:&#x20;

* Each `Person` has a name&#x20;
* Each `Person` has a pointer to another `Person`, indicating that that person is their best friend. If a person has no best friend, the variable shall be `nullptr`.&#x20;

If person `A` is the best friend of person `B`, it is **not** necessarily so that person `B` is the best friend of person `A`.

### Part 1&#x20;

Create 5 instances of `Person`, and set their best friends such that:&#x20;

* Elliot is the best friend of Daniel
* Daniel is the best friend of Charlie&#x20;
* Charlie is the best friend of Bob
* Bob is the best friend of Alice
* Elliot has no best friends.&#x20;

The chain of best friends should be:

* Nobody -> Elliot -> Daniel -> Charlie -> Bob -> Alice.&#x20;

### Part 2&#x20;

Create a function, with the signature `void inspect(Person* person)` which takes a pointer to a `Person`, and prints their best friend, and the best friend of their best friend, and the best friend of their best friend of their best friend... so on so forth, until it reaches a person whom does not have a best friend.&#x20;

Using the example from Part 1, calling `inspect(alice)` should print the following lines:

```
The best friend of Alice is Bob.
The best friend of Bob is Charlie.
The best friend of Charlie is Daniel.
The best friend of Daniel is Elliot.
Elliot has no best friends.
```

*Bonus points: can you create three implementations of this function - one using a **for loop**, and another using a **while loop**, and the last using **recursion**?*&#x20;
