// // Assignment 2 21T3 COMP1511: CS Pizzeria // pizzeria.c // // This program was written by YOUR-NAME-HERE (z5555555) // on INSERT-DATE-HERE // // TODO: INSERT-DESCRIPTION-HERE // // Version 1.0.0: Release #include #include #include // TODO: add any extra #includes your code needs here. #include "pizzeria.h" // TODO: add your own #defines here. struct ingredient { // TODO: add your own fields in Stage 2. struct ingredient *next; char *ingredient_name; int amount; double price; }; struct order { // TODO: add your own fields in Stage 1. // Looking to store a price field? Try putting in "double price;" here! // orderid created in order to keep track of all the orders // Added Name, pizza price and time allowed in stage 1 // Added ingredients in stage 2 int orderid; struct order *next; char *pizza_name; char *customer_name; double price; int time_allowed; struct ingredient *ingredients; }; struct pizzeria { // TODO: add your own fields if required. struct order *orders; //Added to run the selected order functionality. //Added order in stage 2 //Added stock in stage 3 struct order *order_selected; struct ingredient *stock; }; // TODO: add any other structs you define here. ////////////////////////////////////////////////////////////////////// // TODO: add prototypes for any helper functions you create here. // Prints a single order void print_order( int num, char *customer, char *pizza_name, double price, int time_allowed ); // Prints an ingredient given the name, amount and price in the required format. // This will be needed for stage 2. void print_ingredient(char *name, int amount, double price); //////////////////////////////////////////////////////////////////////// // Stage 1 Functions // //////////////////////////////////////////////////////////////////////// struct pizzeria *create_pizzeria() { // Allocates memory to store a `struct pizzeria` and returns a pointer to // it. The variable `new` holds this pointer! struct pizzeria *new = malloc(sizeof(struct pizzeria)); new->orders = NULL; new->order_selected=NULL; new->stock=NULL; // TODO: this function has already been implemented for the current // struct pizzeria. When you decide to change struct pizzeria, change // this function as well. //Initializing selected_order to NULL return new; } int add_order( struct pizzeria *pizzeria, char *customer, char *pizza_name, double price, int time_allowed ) { static int id=0; //Check Price if (price < 0) { return INVALID_PRICE; } //Check Time Allowed if (time_allowed <= 0) { return INVALID_TIME; } //Create New Order Object //Initialize the struct members with values provided struct order *norder = malloc(sizeof(struct order)); norder->orderid=++id; norder->customer_name = strdup(customer); norder->pizza_name = strdup(pizza_name); norder->price= price; norder->time_allowed=time_allowed; norder->next=NULL; norder->ingredients=NULL; //printf("%s",norder->customer_name); //Adding order to pizzeria //If null then a new order is added or else it will be pointed to the last order if(pizzeria->orders==NULL) { pizzeria->orders= norder; return SUCCESS; } else { struct order *temp = pizzeria->orders; while(temp->next!= NULL) temp=temp->next; temp->next=norder; return SUCCESS; } } void print_all_orders(struct pizzeria *pizzeria) { // TODO: fill in the rest of this function // `print_all_orders` should print out each order separated by a // newline ('\n'). Printing each order should be done by calling the // provided `print_order` function. struct order *temp = pizzeria->orders; while(temp !=NULL) { print_order(temp->orderid,temp->customer_name,temp->pizza_name,temp->price,temp->time_allowed); temp= temp->next; } // Do not change this part of the function print_selected_order(pizzeria); return; } int next_deadline(struct pizzeria *pizzeria) { // TODO: fill in the rest of this function struct order *temp = pizzeria->orders; // Temporary order for traaversal of linked list if(temp != NULL) { int tempTime=temp->time_allowed; //Traversed and found the minimum time in all the orders while(temp !=NULL) { if(tempTime > temp->time_allowed) tempTime = temp->time_allowed; temp= temp->next; } return tempTime; } else { // - `INVALID_CALL` -- if there are no orders in the pizzeria. return INVALID_CALL; } } //////////////////////////////////////////////////////////////////////// // Stage 2 Functions // //////////////////////////////////////////////////////////////////////// //Order Selection void select_next_order(struct pizzeria *pizzeria) { //////////////////////////////////////////////////////////////////////// // SELECT THE NEXT ORDER IN THE PIZZERIA - Command '>' // // Given a Pizzeria, sets the selected order to the order after the // currently selected order. // // For example, if the current selected order below is the second one // // [order]->[order]->[order]->[order]->X // ^ // selected // // Then, this command will move the selected to the next order after it // // [order]->[order]->[order]->[order]->X // ^ // selected // // If this command is input again, the last order will be selected // // [order]->[order]->[order]->[order]->X // ^ // selected if(pizzeria->orders==NULL) return; else { struct order *temp = pizzeria->orders; if(pizzeria->order_selected==NULL) { pizzeria->order_selected=temp; return; } while(temp != NULL) { if(temp == pizzeria->order_selected) { if(temp->next==NULL) { pizzeria->order_selected = NULL; break; } else { pizzeria->order_selected = temp->next; break; } } temp = temp->next; } } return; } void select_previous_order(struct pizzeria *pizzeria) { // TODO: fill in the rest of this function //If there are no orders return back to main screen if(pizzeria->orders==NULL) return; else { //If the order_selected equals the 1st order then order_selected will be null. if(pizzeria->order_selected==pizzeria->orders) { pizzeria->order_selected=NULL; return; } //If the above condition is not true and selected_order is NULL then the order_selected will be the last order if(pizzeria->order_selected == NULL) { struct order *temp = pizzeria->orders; while(temp != NULL) { if(temp->next!=NULL) { pizzeria->order_selected = temp; } temp = temp->next; } } //If both the above scenario fails and we are in between then the order selected will be checked by 2 orders a previous_order and a current order. // For example, if the current selected order below is the last one // // [order]->[order]->[order]->[order]->X // ^ // selected // // Then, this command will move the selected to the one before it // // [order]->[order]->[order]->[order]->X // ^ // selected // // If this command is input again, the second order will be selected // // [order]->[order]->[order]->[order]->X // ^ // selected // else { struct order *temp = pizzeria->orders; struct order *prev_order = pizzeria->orders; while(temp!= NULL) { if(pizzeria->order_selected == temp) { pizzeria->order_selected=prev_order; break; } temp = temp->next; prev_order = temp; } } } return; } void print_selected_order(struct pizzeria *pizzeria) { // TODO: Change this once you have implemented the selected order // functionality. if(pizzeria->order_selected== NULL) printf("\nNo selected order.\n"); else { struct order *temp = pizzeria->order_selected; printf("\nThe selected order is %s's %s pizza ($%.2lf) due in %d minutes.\n",temp->customer_name, temp->pizza_name,temp->price, temp->time_allowed); struct ingredient *ingredient = temp->ingredients; while (ingredient != NULL) { printf("\t%s: %d @ $%.2lf\n", ingredient->ingredient_name,ingredient->amount, ingredient->price); ingredient = ingredient->next; } } } //Add Ingredient Function Implementation int add_ingredient( struct pizzeria *pizzeria, char *ingredient, int amount, double price ) { // TODO: fill in the rest of this function // If price is lesser than 0 exception thrown if(price < 0 ) return INVALID_PRICE; // If amount is lesser than or equal to 0 exception thrown if(amount <= 0) return INVALID_AMOUNT; // If the selected order pointer is null exception thrown if(pizzeria->order_selected==NULL) return INVALID_ORDER; // Else a new ingredient object is created struct ingredient *temp=malloc(sizeof(struct ingredient)); temp->ingredient_name= strdup(ingredient); temp->amount=amount; temp->price=price; temp->next=NULL; //And added into the selected order. struct order *selected = pizzeria->order_selected; if(selected->ingredients == NULL) selected->ingredients= temp; else { struct ingredient *ingredient = selected->ingredients; while (ingredient != NULL) { if (strcmp(temp->ingredient_name, ingredient->ingredient_name) == 0) { ingredient->amount = ingredient->amount + temp->amount; free(ingredient->ingredient_name); free(ingredient->next); free(ingredient); break; } else if (strcmp(temp->ingredient_name, ingredient->ingredient_name) > 0) { struct ingredient *next_ingredient = ingredient->next; if (ingredient->next == NULL) { ingredient->next = temp; break; } else if (strcmp(temp->ingredient_name, next_ingredient->ingredient_name) < 0) { temp->next = next_ingredient; ingredient->next = temp; break; } } else { selected->ingredients = temp; temp->next = ingredient; break; } ingredient = ingredient->next; } } return SUCCESS; } double calculate_total_profit(struct pizzeria *pizzeria) { // TODO: fill in the rest of this function //INVALID_ORDER thrown if orders were null //Although the assumptions shows that it cannot be null we still handled this exception if(pizzeria->orders == NULL) return INVALID_ORDER; //Else the profit will calculated. else { double total_profit=0; struct order *temp = pizzeria->order_selected; struct ingredient *temp_ingredient = temp->ingredients; double ingredient_price = 0; //Traversed the ingredients pointer and summed it's price. while(temp_ingredient!= NULL) { ingredient_price += temp_ingredient->price*temp_ingredient->amount; temp_ingredient=temp_ingredient->next; } total_profit = temp->price-ingredient_price; return total_profit; } } //////////////////////////////////////////////////////////////////////// // Stage 3 Functions // //////////////////////////////////////////////////////////////////////// int cancel_order(struct pizzeria *pizzeria) { // TODO: fill in the rest of this function if (pizzeria->order_selected == NULL) { return INVALID_ORDER; } struct order *temp = pizzeria->orders; struct order *temp_order; //For the cancellation of starting Order if (pizzeria->order_selected == pizzeria->orders) { if(pizzeria->orders->next != NULL) temp_order = pizzeria->orders->next; else temp_order = NULL; struct ingredient *current_ingredient = temp->ingredients; struct ingredient *temp_ingredients; while (current_ingredient != NULL) { temp_ingredients = current_ingredient; current_ingredient = current_ingredient->next; free(temp_ingredients->ingredient_name); free(temp_ingredients->next); free(temp_ingredients); } free(temp->customer_name); free(temp->ingredients); free(temp->pizza_name); free(temp); pizzeria->orders = temp_order; pizzeria->order_selected = temp_order; } //For the cancellation of in between order or end order.... else { temp = pizzeria->orders; struct order *previous_order = pizzeria->orders; while (temp != NULL) { if (temp == pizzeria->order_selected) { previous_order->next = temp->next; pizzeria->order_selected = previous_order->next; struct ingredient *current_ingredient = temp->ingredients; struct ingredient *temp_ingredient; while (current_ingredient != NULL) { temp_ingredient = current_ingredient; current_ingredient = current_ingredient->next; free(temp_ingredient->ingredient_name); free(temp_ingredient->next); free(temp_ingredient); } free(temp->customer_name); free(temp->ingredients); free(temp->pizza_name); free(temp); break; } previous_order = temp; temp = temp->next; } } return SUCCESS; } void free_pizzeria(struct pizzeria *pizzeria) { // TODO: fill in the rest of this function //This function frees the memory of all the program // The inbuild function free is used for clearing the pointers from memory struct order *orders = pizzeria->orders; struct order *temp_order = pizzeria->orders; while(temp_order!=NULL) { struct ingredient *ingredients = temp_order->ingredients; struct ingredient *temp; while (ingredients != NULL) { temp = ingredients; ingredients = ingredients->next; free(temp->ingredient_name); free(temp->next); free(temp); } temp_order = orders; orders = orders->next; //Free function. free(temp_order->customer_name); free(temp_order->next); free(temp_order->pizza_name); free(temp_order); } struct ingredient *temp_stock = pizzeria->stock; struct ingredient *temp; while(temp_stock != NULL) { temp=temp_stock; free(temp->ingredient_name); free(temp->next); free(temp); temp_stock=temp_stock->next; } pizzeria->orders = NULL; pizzeria->stock = NULL; pizzeria->order_selected = NULL; free(pizzeria); return ; } int refill_stock( struct pizzeria *pizzeria, char *ingredient_name, int amount, double price ) { // TODO: fill in the rest of this function //This function refills the stock in pizzeria class if(amount<= 0) return INVALID_AMOUNT; if(price < 0 ) return INVALID_PRICE; struct ingredient *temp=malloc(sizeof(struct ingredient)); temp->ingredient_name= strdup(ingredient_name); temp->amount=amount; temp->price=price; temp->next=NULL; if(pizzeria->stock==NULL) pizzeria->stock=temp; else { //Insertion of stocks in alphabatical order is done in following way. struct ingredient *temp_stock = pizzeria->stock; while (temp_stock != NULL) { //Compared new object name with the old one and checked that wheter it is same //if yes then replaced that object with the new one increasing the amount if (strcmp(temp->ingredient_name, temp_stock->ingredient_name) == 0) { temp_stock->amount = temp_stock->amount + temp->amount; free(temp->ingredient_name); free(temp->next); free(temp); break; } //Else checked whether the alphabet is greater else if (strcmp(temp->ingredient_name, temp_stock->ingredient_name) > 0) { //If the next stock was null we added the new stock in the last if (temp_stock->next == NULL) { temp_stock->next = temp; free(temp->ingredient_name); free(temp->next); free(temp); break; } else { //Else we checked whether the next is smaller we added it as a next stock. struct ingredient *nxt_stock = temp_stock->next; if (strcmp(temp->ingredient_name, temp_stock->ingredient_name) < 0) { temp->next = nxt_stock; temp_stock->next = temp; break; } } } else { pizzeria->stock = temp; temp->next = temp_stock; break; } //Looping through temp_stock = temp_stock->next; } } return SUCCESS; } void print_stock(struct pizzeria *pizzeria) { // TODO: fill in the rest of this function //This is print stock function using print_ingredient a defined function. struct ingredient *temp = pizzeria->stock; while(temp != NULL) { print_ingredient(temp->ingredient_name,temp->amount,temp->price); temp= temp->next; } return; } int can_complete_order(struct pizzeria *pizzeria) { // TODO: fill in the rest of this function //This function checks whether the selected order can be completed or not //As per the specs if there was no selected order we need to send exception INVALID_ORDER if (pizzeria->order_selected == NULL) { return INVALID_ORDER; } //We created a temporary object for traversal of the ingredients struct order *temp = pizzeria->order_selected; struct ingredient *temp_ingredient = temp->ingredients; //If the ingredient was NULL an exception INVALID_ORDER was thrown if (temp_ingredient == NULL) { return INVALID_ORDER; } //Traversal of pizzeria-> stock pointer is done using temp_stock. struct ingredient *temp_stock = pizzeria->stock; while (temp_ingredient != NULL) { int match=0; while(temp_stock!=NULL) { if(temp_stock->ingredient_name==temp_ingredient->ingredient_name) { //If temp_stock amount's matches or is greater then temp_ingredient amount //this means that the order can be completed so we returned 1 if(temp_stock->amount >= temp_ingredient->amount) { match= 1; break; } } } //If the match stays 0 this means that ingredient was either not found or the ingredient's amount was lesser if(match==0) { return INSUFFICIENT_STOCK; } temp_ingredient = temp_ingredient->next; } return SUCCESS; } //////////////////////////////////////////////////////////////////////// // Stage 4 Functions // //////////////////////////////////////////////////////////////////////// int complete_order(struct pizzeria *pizzeria) { return SUCCESS; } int save_ingredients(struct pizzeria *pizzeria, char *file_name) { return SUCCESS; } int load_ingredients(struct pizzeria *pizzeria, char *file_name) { return SUCCESS; } //////////////////////////////////////////////////////////////////////// // HELPER FUNCTIONS - Add your own here // //////////////////////////////////////////////////////////////////////// // Prints a single order // // `print_order` will be given the parameters: // - `num` -- the integer that represents which order it is sequentially. // - `customer` -- the name of the customer for that order. // - `pizza_name` -- the pizza the customer ordered. // - `price` -- the price the customer is paying for the pizza. // - `time_allowed` -- the time the customer will wait for the order. // // `print_order` assumes all parameters are valid. // // `print_order` returns nothing. // // This will be needed for Stage 1. void print_order( int num, char *customer, char *pizza_name, double price, int time_allowed ) { printf("%02d: %s ordered a %s pizza ($%.2lf) due in %d minutes.\n", num, customer, pizza_name, price, time_allowed); return; } // Prints a single ingredient // // `print_ingredient` will be given the parameters: // - `name` -- the string which contains the ingredient's name. // - `amount` -- how many of the ingredient we either need or have. // - `price` -- the price the ingredient costs. // // `print_ingredient` assumes all parameters are valid. // // `print_ingredient` returns nothing. // // This will be needed for Stage 2. void print_ingredient(char *name, int amount, double price) { printf(" %s: %d @ $%.2lf\n", name, amount, price); }