CSCI 235 Spring 2024 Term Project
Algorithmic Adventures II: Exponential Creature Odyssey
Ingredient
struct and the Pantry
class that will allow the management of recipes and the crafting of new Ingredients so simple, even our Creatures will be able to whip up the most delicious recipes!!!
The link to accept the GitHub Classroom assignment can be found on Blackboard
This project consists of three tasks:
You will implement the Ingredient
struct within the interface of the Pantry
class (Pantry.hpp
) but outside of the Pantry
class definition.
You will implement the Pantry class
to store POINTERS to Ingredient
objects as a subclass of LinkedList
.
You will TEST the Pantry class
with the provided debug file debug.csv
.
Linked list
Work through the tasks sequentially (implement and test). Only move on to a task when you are positive that the previous one has been completed correctly. Remember that the names of classes and methods must exactly match those in this specification (FUNCTION NAMES, PARAMETER TYPES, RETURNS, PRE AND POST CONDITIONS MUST MATCH EXACTLY).
**Remember, you must thoroughly document your code!!!
Ingredient
struct
Ingredient
struct in Pantry.hpp
but outside of the Pantry
class definition, as follows:The Ingredient
struct should consist of the following data members
- A string representing the ingredient name
- A string representing the ingredient description
- An integer representing if the ingredient quantity
- An integer representing the ingredient price
- A vector of Ingredient pointers representing the ingredient's recipe
The Ingredient
struct must also define the following:
/**
Default Constructor
@post: Creates a new Ingredient object with default values. String defaults to empty string.
Default quantity is 0, default price is 1.
*/
/**
Parameterized Constructor
@param: A string representing a ingredient name
@param: A string representing ingredient description
@param: An int representing the ingredient's quantity
@param: An int representing the ingredient's price
@param: A vector holding Ingredient pointers representing the ingredient's recipe
@post: Creates a new Ingredient object with the given parameters
*/
You can write the implementation of the constructors directly in the Ingredient
struct definition.
Note:
A ingredient's recipe can be thought of as a list of prerequisite ingredients that must be crafted before this ingredient can be crafted.
Pantry
class as a subclass of LinkedList
We will now organize all the ingredients in a Pantry
so that even our Creatures
will be able to easily find the ingredients to execute any recipe.
The Pantry
class will store POINTERS to Ingredient
objects, and must have the following public member functions:
x/**
Default Constructor
*/
/**
@param: the name of an input file
@pre: Formatting of the csv file is as follows:
Name: A string
Description: A string
Quantity: A non negative integer
Price: A non negative integer
Recipe: A list of Ingredient titles of the form [NAME1] [NAME2];
For example, to make this ingredient, you need (Ingredient 1 AND Ingredient 2)
The value may be NONE.
Notes:
- The first line of the input file is a header and should be ignored.
- The recipe are separated by a semicolon and may be NONE.
- The recipe may be in any order.
- If any of the recipe are not in the list, they should be created as new ingredients with the following information:
- Title: The name of the ingredient
- Description: "UNKNOWN"
- Quantity: 0
- Price: 0
- Recipe: An empty vector
- However, if you eventually encounter a ingredient that matches one of the "UNKNOWN" ingredients while parsing the file, you should update all the ingredient details.
For example, given a row in the file:
Inferno_Espresso,An energizing elixir brewed with mystical flames providing resistance to caffeine crashes for a limited time.,1,50,Fiery_Bean Ember_Spice
The order of the ingredients in the list:
Fiery_Bean, Ember_Spice, Inferno_Espresso
Hint: update as needed using addIngredient()
@post: Each line of the input file corresponds to a ingredient to be added to the list. No duplicates are allowed.
Hint: use std::ifstream and getline()
*/
/**
Destructor
@post: Explicitly deletes every dynamically allocated Ingredient object
*/
xxxxxxxxxx
/**
@param: A const string reference to a ingredient name
@return: The integer position of the given ingredient if it is in the Pantry, -1 if not found. REMEMBER, indexing starts at 0.
*/
getPosOf
/**
@param: A const string reference to a ingredient name
@return: True if the ingredient information is already in the Pantry
*/
contains
/**
@param: A pointer to an Ingredient object
@post: Inserts the given ingredient pointer into the Pantry, unless an ingredient of the same name is already in the pantry.
Each of its Ingredients in its recipe are also added to the Pantry IF not already in the list.
@return: True if the ingredient was added successfully, false otherwise.
*/
addIngredient
/**
@param: A const string reference representing a ingredient name
@param: A const string reference representing ingredient description
@param: A const int reference representing the ingredient's quantity
@param: A const int reference representing the ingredient's price
@param: A const reference to a vector holding Ingredient pointers representing the ingredient's recipe
@post: Creates a new Ingredient object and inserts a pointer to it into the Pantry.
Each of its Ingredients in its recipe are also added to the Pantry IF not already in the list.
@return: True if the ingredient was added successfully
*/
addIngredient
/**
@param: A Ingredient pointer
@return: A boolean indicating if all the given ingredient can be created (all of the ingredients in its recipe can be created, or if you have enough of each ingredient in its recipe to create it)
*/
canCreate
/**
@param: A Ingredient pointer
@post: Prints the ingredient name, quantity, and description.
The output should be of the form:
[Ingredient Name]: [Quantity]\n
[Ingredient Description]\n
Price: [Price]\n
Recipe:\n
[Ingredient0] [Ingredient1]\n
If the ingredient has no recipe, print "Recipe:\nNONE\n\n" after the price.
*/
printIngredient
/**
@param: A const string reference to a ingredient name
@post: Prints a list of ingredients that must be created before the given ingredient can be created (missing ingredients for its recipe, where you have 0 of the needed ingredient).
If the ingredient is already in the pantry, print "In the pantry([quantity])\n"
If there are no instances of the ingredient, if it cannot be crafted because of insufficient ingredients, print "[Ingredient Name](0)\nMISSING INGREDIENTS"
If it can be crafted, recursively print the ingredients that need to be used (if there are instances of them) or created (if there are no instances of them) in the order that the ingredients appear in the recipe, joined by "<-".
If the ingredient has no recipe, print "UNCRAFTABLE\n" at the end of the function.
Below are some of the expected forms. "Scenario: [scenario] is not part of the output. It is just to help you understand the expected output.":
Scenario: The Ingredient does not exist in the list
Query: [Ingredient Name]
No such ingredient
Scenario: The Ingredient exists in the list, and there are >0 instances of it
Query: [Ingredient Name]
In the pantry ([Quantity])
Scenario: The Ingredient exists in the list, and there are 0 instances of it, and it is craftable by using an ingredient that is already in the pantry
Query: [Ingredient Name0]
[Ingredient Name0](C)
[Ingredient Name1](1)
Scenario: The Ingredient exists in the list, and there are 0 instances of it, and it is craftable by using an ingredient that has to be crafted
Query: [Ingredient Name0]
[Ingredient Name0](C)
[Ingredient Name1](C) <- [Ingredient Name2](3)
Scenario: The Ingredient exists in the list, and there are 0 instances of it, and there are multiple ingredients that have to be crafted (each row represents a different ingredient inå the original recipe)
Query: [Ingredient Name0]
[Ingredient Name0](C)
[Ingredient Name1](C) <- [Ingredient Name2](3)
[Ingredient Name3](C) <- [Ingredient Name4](C) <- [Ingredient Name5] (3)
Scenario: The Ingredient exists in the list, and there are 0 instances of it, and it is not craftable (it has no recipe)
Query: [Ingredient Name0]
UNCRAFTABLE
Scenario: The Ingredient exists in the list, and there are 0 instances of it, and it has a recipe, but you do not have enough of the ingredients to craft it
Query: [Ingredient Name0]
[Ingredient Name0](0)
MISSING INGREDIENTS
HINT: Use canCreate() to determine if the ingredient can be created.
*/
ingredientQuery
/**
@return: An integer sum of the price of all the ingredients currently in the list.
Note: This should only include price values from ingredients that you have 1 or more of. Do not consider ingredients that you have 0 of, even if you have the ingredients to make them.
*/
calculatePantryValue()
/**
@param: A const string reference to a filter with a default value of "NONE".
@post: With default filter "NONE": Print out every ingredient in the list.
With filter "CONTAINS": Only print out the ingredients with >0 instances in the list.
With filter "MISSING": Only print out the ingredients with 0 instances in the list.
With filter "CRAFTABLE": Only print out the ingredients where you have all the ingredients to craft them.
If an invalid filter is passed, print "INVALID FILTER\n"
Printing ingredients should be of the form:
[Ingredient name]: [Quantity]
[Ingredient description]\n
Price: [price]\n
Recipe:\n
[Ingredient0] [Ingredient1]\n\n
If the ingredient has no recipe, print "Recipe:\nNONE\n\n" after the price.
*/
pantryList
You have been provided with the file debug.csv
to help test your code for ingredientQuery
. This is in addition to the incremental unit-testing you will do for each method you implement.
Upon instantiating a Pantry
from debug.csv
, and running ingredientQuery
as follows:
pantry.ingredientQuery("in1"); std::cout<<std::endl; pantry.ingredientQuery("in2"); std::cout<<std::endl; pantry.ingredientQuery("in3"); std::cout<<std::endl; pantry.ingredientQuery("in4"); std::cout<<std::endl; pantry.ingredientQuery("in5"); std::cout<<std::endl; pantry.ingredientQuery("in6"); std::cout<<std::endl; pantry.ingredientQuery("in7"); std::cout<<std::endl; pantry.ingredientQuery("in8"); You should produce this output. For readability, a new line was printed after each query.
Query: in1 In the pantry (3) UNCRAFTABLE
Query: in2 in2(C) in1(3)
Query: in3 in3(C) in2(C) <- in1(3)
Query: in4 in4(C) in2(C) <- in1(3) in3(C) <- in2(C) <- in1(3)
Query: in5 in5(C) in4(C) <- in2(C) <- in1(3) in3(C) <- in2(C) <- in1(3)
Query: in6 in6(C) in1(3) in5(C) <- in4(C) <- in2(C) <- in1(3) in3(C) <- in2(C) <- in1(3)
Query: in7 UNCRAFTABLE
Query: in8 in8(0) MISSING INGREDIENTS
Although you will no longer submit your test file, you must continue to thoroughly and methodically test your code.
Start by stubbing all expected functions. Have all function declarations in the .hpp and stubs for all functions in the .cpp. When submitted as such, your program will compile, although you will fail all tests, since you have not implemented any functions yet. If your program compiles, you will have at least established that all functions have correct name, parameters and return-type.
What is a stub? A stub is a dummy implementation that always returns a single value for testing (or has an empty body, if void). Don’t forget to go back and implement the stub!!! If you put the word STUB in a comment, some editors will make it more visible.
Now you can start implementing and testing your project, ONE FUNCTION AT A TIME!
Write a main()
function to test your implementation. Choose the order in which you implement your methods so that you can test incrementally: i.e. implement constructors then accessor functions, then mutator functions.
For each class, test each function you implement with all edge cases before you move on to implement the next function. This includes all constructors.
Make sure you include all packages and libraries you use.
How to compile with your Makefile:
In terminal, in the same directory as your Makefile and your source files, use the following command
make rebuild
This assumes you did not rename the Makefile
and that it is the only one in the current directory.
Correctness 80% (distributed across unit testing of your submission)
Documentation 15%
Style and Design 5% (proper naming, modularity, and organization)
Important: You must start working on the projects as soon as they are assigned to detect any problems with submitting your code and to address them with us well before the deadline so that we have time to get back to you before the deadline.
We will grade the following :
Pantry.hpp
Pantry.cpp
Although Gradescope allows multiple submissions, it is not a platform for testing and/or debugging and it should not be used for that. You MUST test and debug your program locally. To help you not rely too much on Gradescope for testing, we will only allow 5 submissions per day. Before submitting to Gradescope you MUST ensure that your program compiles using the provided Makefile
and runs correctly on the Linux machines in the labs at Hunter (see detailed instructions on how to upload, compile and run your files in the “Programming Guidelines” document). That is your baseline, if it runs correctly there it will run correctly on Gradescope, and if it does not, you will have the necessary feedback (compiler error messages, debugger or program output) to guide you in debugging, which you don’t have through Gradescope. “But it ran on my machine!” is not a valid argument for a submission that does not compile. Once you have done all the above you submit it to Gradescope.
This project is due April 4
No late submissions will be accepted.
You must start working on the projects as soon as they are assigned to detect any problems and to address them with us well before the deadline so that we have time to get back to you before the deadline. There will be no extensions and no negotiation about project grades after the submission deadline.
Help is available via drop-in tutoring in Lab 1001B (see website for schedule). You will be able to get help if you start early and go to the lab early. We only have 3 UTAs in the lab, the days leading up to the due date will be crowded and you will not be able to get much help then.
Authors: Georgina Woo, Tiziana Ligorio