I see you have done it correctly. You have implemented the Ingredient struct correctly.
On Dish.hpp file, you will need to change the member variable std::vector<std::string> ingredients_;
to using the Ingredient
struct.
like this:
std::vector<Ingredient> ingredients_;
Now that you have chanded ingredients_
member variable from a vector of strings to a vector of Ingredient
structs, you will need to change the getIngredients()
and setIngredients()
member functions.
On Dish.hpp file, you will need to change the getIngredients()
member function to return a vector of Ingredient
structs.
std::vector<Ingredient> getIngredients() const;
And on Dish.cpp file, change the vector return type as well and you'll fine.
On Dish.hpp file, you will need to change the setIngredients()
member function to take a vector of Ingredient
structs as a parameter.
void setIngredients(const std::vector<Ingredient>& ingredients);
And on Dish.cpp file, change the vector parameter type as well and you'll fine.
You have done a great job declaring the private data members of the KitchenStation according to the instructions.
Both constructors and destructors are already implemented correctly. I don't really know if you have difficulty with understanding them. Let me know if any concept about Constructors/Destructors is not clear. Understanding those is the key to it. Everyone forgets the syntax and code, but the concept is what stays with us.
All the accessors getName()
, setName()
getDishes()
and getIngredients()
are implemented correctly. I see there's no documentation header for any function other than getName()
. Do add those before submitting as you'll be graded on it I guess.
It seems good as well. There are other easier ways to loop through a vector but if for
loop seems more natural to you, then go for it.
This function is implemented amazingly well. You are using the auto
keyword to loop through the vector of Ingredient
structs I see. You can also use for loop here like you have used in the other functions.
There are some polishing needed here. You were headed to the right direction. below is the pseudocode for the function.
bool dish_present_in_kitchen = false;
for (each dish in dishes) {
if dish.name == given_dish_name
dish_present_in_kitchen = true;
break; // we found the dish, so we can break out of this loop
}
// if dish was not present in kitchen station, we can immidietly return false
// as we cannot complete complete an order that our kitchen doesn't make
if (!dish_present_in_kitchen) return false;
// Now check if we have all the ingredients we need or not
bool single_ingredient_available_in_full_quantity;
for (every required_ingredient in dish.ingredients) {
single_ingredient_available_in_full_quantity = false;
for (every available_ingredient in indient_stock) {
// check if we have that ingredient and we have equal to or more than the quantity of ingredients needed
if (available_ingredient.name == required_ingredient) and (available_ingredient.quantity >= required_ingredient.quantiy)
single_ingredient_available_in_full_quantity = true;
break;
}
if !(single_ingredient_available_in_full_quantity) return false;
}
// if we reach this portion of the code, that mean all the ingredients were present in sufficient quantity.
// we can safely return true now
return true;
For this, we will first check if we canCompleteOrder
. If we can, then we will find the Dish in our kitchen and loop through the required ingredients. Inside that loop, like we did in the previous function, we loop through the available ingredients and decrease its amount if we need it in the dish. We also remove that Ingredient from the vector of IngredientStock if the quantity deplets to 0. Now the pseudocode:
if (!canCompleteOrder) return false;
Dish target_dish = null;
for (every dish in dishes) {
if dish.name == dish_name
target_dish = dish
break
}
required_ingredients = target_dish.getIngredients()
for (each required_ingredient in required_ingredients) {
for (each available_ingredient in ingredient_stoc) {
if available_ingredient.name == required_ingredient.name
available_ingredient.quanty -= required_ingredient.quantity
if available_ingredient.quantity <= 0:
remove available_ingredient
}
}
return true;
Your current constructor is writely written except it doesn't initialize the LinkedList class that StationManager inherited from. To do that, you need to do something like this:
StationManager::StationManager() : LinkedList<KitchenStation*>() {}
And in the destructor, since we need to delete a LinkedList of KitchenStation, we traverse through it and delete one by one. Pseudocode for that will look something like this:
KitchenStation node current = get_head_of_linked_list()
while (current node is not null) {
delete current item;
current = current.next;
}
For this, we first check if the station that was passed to us is a valid pointer or not. If not, we return false. Then we check if the station with the same name already exists. If it exists, we return false. If not, we call the insert function of our LinkedList and insert it in the head position. Below is the pseudocode for this:
FUNCTION addStation(station: KitchenStation*) RETURNS boolean
// Check if station pointer is null
IF station IS null THEN
RETURN false
END IF
// Check if station with same name already exists
SET current = headNode
WHILE current IS NOT null
IF current->data->getName() EQUALS station->getName() THEN
RETURN false // Station with same name exists
END IF
SET current = current->next
END WHILE
// Insert station at beginning of list
CALL insert(0, station)
RETURN true
END FUNCTION
For a simple check, we first see if our linked list is empty or not. If it's empty, we can return false right away and there is no need to advance further. If not, we loop through the linked lists and check if any of the KitchenStation's name matches our gieven name. If it does, we set our found flag to true and save the position (index) of it in our position variable. Then we just delete the pointer and remove it from linked list using the remove function. Below is the pseudocode for that:
FUNCTION removeStation(station_name: STRING) -> BOOLEAN
// If list is empty, return false
IF list is empty THEN
RETURN false
END IF
// Initialize variables
SET current_node = head node
SET previous_node = nullptr
SET found = false
SET position = 0
// Search for the station with matching name
WHILE current_node is not null
IF current_node's station name equals station_name THEN
SET found = true
BREAK
END IF
SET previous_node = current_node
SET current_node = next node
INCREMENT position
END WHILE
// If station not found, return false
IF not found THEN
RETURN false
END IF
// Delete the station object
DELETE current_node's station pointer
// Remove the node from the linked list using inherited remove function
CALL remove(position)
RETURN true
END FUNCTION
This is gonna be simple. We have been doing this 'finding' in all the other previous functions as well. We just get the head of the linked list and set it to variable current. Then we loop through until the 'current' variable is not null and check if the name of current kitchen station matches the given name or not. Below is the pseudocode for it.
Function findStation(station_name) -> KitchenStation*:
// Initialize current node to head of linked list
current = getHeadNode()
// Traverse the linked list while current is not null
While current is not null:
// Get the KitchenStation pointer from current node
station = current->getItem()
// Check if station name matches the search parameter
If station->getName() equals station_name:
// Return the matching station
Return station
// Move to next node
current = current->getNext()
// If no matching station found, return nullptr
Return nullptr
End Function
First we check if moving is necessary (list empty or has one single item). After that, we search through the list and keep track of the current and previous node of the list. If we did not find the station, we return flase immidietly. Then it is the part of moving. We check if the station we want to move is already at the front or not. If it's already at the front, there's no need to move.
For the moving part, I am trying to explain it with some flow diagrams. Suppose we have a linked list of kitchen station with names like "Prep Station", "Grill Station" and "Dessert Station". We want to move "Grill Station" to the front. This is how the linked list currently looks like:
Initial State:
graph LR
Head --> A["Prep Station"] --> B["Grill Station"] --> C["Dessert Station"] --> null
Step by Step Movement:
- Find the node and its previous node:
previous = Prep Station
current = Grill Station
- Update previous node's next pointer to skip current:
graph LR
Head --> A["Prep Station"] --> C["Dessert Station"] --> null
B["Grill Station"]
- Set current node's next pointer to head:
graph LR
Head --> A["Prep Station"] --> C["Dessert Station"] --> null
B["Grill Station"] --> A
- Update head pointer to current:
graph LR
Head --> B["Grill Station"] --> A["Prep Station"] --> C["Dessert Station"] --> null
Pseudocode for this will look something like this:
moveStationToFront(station_name):
// If list is empty or has only one node, return false
IF getLength() <= 1 THEN
RETURN false
END IF
// Initialize pointers
SET current = getHeadNode()
SET previous = nullptr
SET found = false
// Search for the station with matching name
WHILE current is not nullptr DO
IF current->getItem()->getName() equals station_name THEN
SET found = true
BREAK
END IF
SET previous = current
SET current = current->getNext()
END WHILE
// If station not found, return false
IF not found THEN
RETURN false
END IF
// If station is already at front, return false
IF previous is nullptr THEN
RETURN false
END IF
// Move the station to front
previous->setNext(current->getNext())
current->setNext(getHeadNode())
SET head_ptr_ = current
RETURN true
END FUNCTION
For this, we first check if both the stations exists or not. Then just add all ingredients from station 2 to station 1 and then delete station 2.
function mergeStations(station_name1, station_name2):
// Find both stations in the list
station1 = findStation(station_name1)
station2 = findStation(station_name2)
// If either station doesn't exist, return false
if station1 is null OR station2 is null:
return false
// Merge dishes from station2 into station1
for each dish in station2's dishes:
add dish to station1's dishes
// Merge ingredients from station2 into station1
for each ingredient in station2's ingredients:
if ingredient exists in station1:
add quantities together
else:
add new ingredient to station1
// Remove station2 from the list
removeStation(station_name2)
return true
This is a simple function that needs to just finding the Station and assigning a dish
FUNCTION assignDishToStation(station_name: STRING, dish: DISH*) RETURNS BOOLEAN
// Find the station with the given name
station = findStation(station_name)
// If station not found, return false
IF station IS NULL THEN
RETURN false
END IF
// Try to assign the dish to the found station
RETURN station->assignDishToStation(dish)
END FUNCTION
Plain and simple like the previous function. Just find the station and call the replenish method on it.
function replenishIngredientAtStation(station_name, ingredient):
// Find the station with the given name
station = findStation(station_name)
// If station not found, return false
if station is nullptr:
return false
// Call the station's replenishStationIngredients method
station->replenishStationIngredients(ingredient)
// Return true since operation was successful
return true
end function
For this, we need to loop through all the stations and call the canCompleteOrder on it. As soon as we find any station that returns true, we return true as well.
canCompleteOrder(dish_name):
current_station = head()
while (current_station is not null)
if current_station->canCompleteOrder(dish_name)
return true
current_station = current_station.next()
// Since we have reached this point, that means no station can complete this order
return false;
At first, we find the station and then call prepareDish method on that KitchenStation instance.
prepareDish(station_name, dish_name):
station = findStation(station_name);
if (station = nullptr)
return false;
return station->prepareDish(dish_name);