version: 1.0 last updated: 2026-10-29 09:00

Assignment 2 - CS Alchemy

Overview

Welcome to CS Alchemy! 🧙⚗️🧪🔮

In assignment 2, your task is to implement CS Alchemy, a potion brewing simulator. In this program, wizards fill their cauldrons with ingredients, simmer them into potions, and duel each other with their brews to rise through the ranks and become a MASTER alchemist!

This assignment will test your ability to create, use, manipulate, and solve problems using linked lists. You will represent wizards, cauldrons, ingredients and potions using linked lists within a central apothecary structure.

COMP1511 Students

If you are a COMP1511 student, you will be assessed on your performance in Stages 1, 2, 3, and 4, which will make up the performance component of your grade. Style will be marked as usual and will make up the remaining 20% of the marks for this assignment.

COMP1911 Students

If you are a COMP1911 student, you will be assessed on your performance in up to and including Stage 3.3 ONLY for this assignment, which will make up the performance component of your grade. Style will be marked as usual and will make up the remaining 20% of the marks for this assignment. You are not required to attempt Stages 3.4 and beyond. You may attempt the later stages if you wish, but you will not be awarded any marks for work beyond Stage 3.3.

Getting Started

There are a few steps to getting started with CS Alchemy.

  1. Create a new folder for your assignment work and move into it.
mkdir ass2
cd ass2
  1. Use this command on your CSE account to copy the file into your current directory:
1511 fetch-activity cs_alchemy
  1. Run 1511 autotest cs_alchemy to make sure you have correctly downloaded the file.
1511 autotest cs_alchemy
  1. Read through this introduction and Stage 1.

  2. Spend a few minutes playing with the reference solution.

 1511 cs_alchemy
  1. Think about your solution, draw some diagrams to help you get started.

  2. Start coding!

Assignment Structure & Starter Code

This assignment utilises a multi-file system. There are three files we use in CS Alchemy:

  • Main File (main.c): This file contains the main function, which serves as an entry point for the program. It is responsible for printing a welcome banner, setting the name of the apothecary, creating the apothecary, and initiating a command loop so users can interact with the program.

A main() function has been provided in main.c to get you started.

int main(void) {
    print_welcome_banner();

    printf("Enter the name of the apothecary: ");
    char apothecary_name[MAX_SIZE];
    scan_name(apothecary_name);
    struct apothecary *my_apothecary = create_apothecary(apothecary_name);

    command_loop(my_apothecary);

    printf("\nThank you for brewing potions!\n");
    return 0;
}

Printing a Welcome Banner

The first statement in main() calls the provided print_welcome_banner() function to print a welcome banner:

void print_welcome_banner() {

    printf(
    "                  Welcome to....\n"
    "                .       o      .       o\n"
    "      o    .        O       .       O       .    o\n"
    "       T H E   P O T I O N   A P O T H E C A R Y\n"
    "     .   o  .   O   .   o   .   O   .   o   .   O\n"
    " (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)\n"
    "oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO\n"
    "~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o\n\n"
    );

}

Scanning the Apothecary Name

In this section, the program receives input from the user for the name of the apothecary.

It declares apothecary_name, a character array of size MAX_SIZE to store the name of the apothecary.

It then uses the provided scan_name() function, which reads user input and stores it in the apothecary_name string.

printf("Enter the name of the apothecary: ");
char apothecary_name[MAX_SIZE];
scan_name(apothecary_name);

Creating the Apothecary

Next, the program creates the apothecary itself. It:

  • Declares a pointer my_apothecary to a struct apothecary.
  • Calls create_apothecary(), passing apothecary_name as an argument.
  • Stores the pointer returned by create_apothecary() in my_apothecary.

struct apothecary *my_apothecary = create_apothecary(apothecary_name);

The create_apothecary() function is currently incomplete. You will need to implement this in Stage 1.1. It is responsible for setting up the initial state of the apothecary, including allocating memory and setting default values.

Starting the Command Loop

After creating the apothecary, the program starts a command loop by calling the command_loop() function which you will need to implement in Stage 1.2. This function allows users to interact with the program to add wizards, cauldrons, ingredients, and more!

command_loop(my_apothecary);

Exiting the Program

The last statement in main() prints a thank you message:

printf("\nThank you for brewing potions!\n");

  • Header File (cs_alchemy.h): This file declares constants, enums, structs, and function prototypes for the program. You will need to add prototypes for any functions you create in this file. You should also add any of your own constants and/or enums to this file.

  • Implementation File (cs_alchemy.c): This file is where most of the assignment work will be done, as you will implement the logic and functionality required by the assignment here. This file also contains stubs of Stage 1 functions for you to implement. It does not contain a main function, so you will need to compile it alongside main.c. You will need to define any additional functions you may need for later stages in this file.

The implementation file cs_alchemy.c contains some "Provided Function Definitions" to help simplify some stages of this assignment. These functions have been implemented and should not need to be modified to complete this assignment.

These provided functions will be explained in the relevant stages of this assignment. Please read the function comments and the specification as we will suggest certain provided functions for you to use.

We have defined some structs in cs_alchemy.h to get you started. You may add fields to any of the structs if you wish.

The Apothecary

struct apothecary {
    char name[MAX_SIZE];

    struct wizard *wizards;
    struct cauldron *cauldrons;
};

Purpose: To store all the information about the apothecary. It contains:

  • The name of the apothecary.
  • A list of wizards in the apothecary.
  • A list of cauldrons in the apothecary.

Wizards

struct wizard {
    char name[MAX_SIZE];
    enum wizard_rank rank;

    struct potion *potions;
    struct wizard *next;
};

Purpose: To represent a wizard in the apothecary. It contains:

  • The wizard's name.
  • The wizard's rank (either Novice, Apprentice or Master).
  • A pointer to the list of the wizard's potions.
  • A pointer to the next wizard in the apothecary.

Cauldrons

struct cauldron {
    char assigned_wizard_name[MAX_SIZE];

    enum brew_status status;
    int brew_potency;
    enum wizard_rank required_rank;

    struct ingredient *ingredients;
    struct cauldron *next;
};

Purpose: To represent a cauldron in the apothecary. It contains:

  • The name of the wizard this cauldron is assigned to.
  • The current status of the cauldron (either Ready, Simmering or Brewed).
  • The total potency of the brew inside the cauldron as an integer.
  • The minimum wizard rank required to use this cauldron.
  • A pointer to the list of ingredients in this cauldron.
  • A pointer to the next cauldron in the apothecary.

Ingredients

struct ingredient {
    enum ingredient_type type;
    enum ingredient_effect effect;
    int potency;

    struct ingredient *next;
};

Purpose: To represent a single ingredient, which makes up the contents of a cauldron or a potion. It contains:

  • The ingredient's effect (either Energetic, Slowing, Chilling, Scorching, Flying, Sinking or Inert).
  • The ingredient's type (either Mushroom, Crystal, Root or Flower).
  • The ingredient's potency, stored as an integer.
  • A pointer to the next ingredient in the list.

Potions

struct potion {
    char name[MAX_SIZE];

    int brew_potency;

    struct ingredient *ingredients;
    struct potion *next;
};

Purpose: To represent a potion that a wizard has bottled. It contains:

  • The potion's name.
  • The potency of the potion's broth, stored as an integer.
  • A pointer to the list of ingredients in this potion.
  • A pointer to the next potion in the wizard's list.

The following enum definitions are provided for you in cs_alchemy.h. You can create your own enums if you would like, but you should not need to modify the provided enums.

Ingredient Effect

enum ingredient_effect {
    ENERGETIC,
    SLOWING,
    CHILLING,
    SCORCHING,
    FLYING,
    SINKING,
    INERT,
    INVALID_EFFECT
};
Purpose: To represent the magical effect of an ingredient.


Ingredient Type

enum ingredient_type {
    MUSHROOM,
    CRYSTAL,
    ROOT,
    FLOWER,
    INVALID_TYPE
};
Purpose: To represent the type of an ingredient.


Wizard Rank

enum wizard_rank {
    NOVICE,
    APPRENTICE,
    MASTER,
    INVALID_RANK
};
Purpose: To represent the rank a wizard has attained.


Brew Status

enum brew_status {
    READY,
    SIMMERING,
    BREWED,
    INVALID_STATUS
};
Purpose: To represent the status of a cauldron.

Reference Implementation

To help you understand the expected behaviour of CS Alchemy, we have provided a reference implementation. If you have any questions about the behaviour of your assignment, you can compare its output to the reference implementation.

To run the reference implementation, use the following command:

 1511 cs_alchemy

Input:

CS_Alchemy
?
[CTRL + D]

Input and Output:

1511 cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: ?
===========================[ Usage Info ]==========================
                                                                   
  ?                                                                
    Show this help information.                                    
  a w [wizard_name] [rank]                                         
    Add a new wizard with the given rank.                          
  a c [wizard_name] [required_rank]                                
    Add a new cauldron, assigned to the given wizard.              
  a i [cauldron_number] [type] [effect]                            
    Add a new ingredient to the given cauldron.                    
  c [cauldron_number]                                              
    Inspect a single cauldron.                                     
  i [cauldron_number] [depth] [type] [effect]                      
    Insert an ingredient at a given depth.                         
  b [cauldron_number] [potion_name]                                
    Bottle a cauldron into a potion.                               
  o [cauldron_number]                                              
    Reorder the ingredients in a cauldron.                         
  r p [potion_name]                                                
    Remove a potion.                                               
  r c [cauldron_number]                                            
    Remove a cauldron.                                             
  r w [wizard_name]                                                
    Remove a wizard and redistribute their potions.                
  l [cauldron_number] [turns]                                      
    Light a cauldron to simmer for a number of turns.              
  s [cauldron_number]                                              
    Simmer a cauldron for one turn.                                
  p [cauldron_number] [turns]                                      
    Peek at what the next simmer turns would do.                   
  d [wizard_a] [wizard_b]                                          
    Duel two wizards with their potions.                           
  *                                                                
    Print the apothecary.                                          
  q                                                                
    Quits the apothecary.                                          
                                                                   
===================================================================
Enter command: 
Thank you for brewing potions!

Allowed C Features

This assignment must be implemented exclusively using linked lists for all core data structures and logic.

Other than arrays, there are no restrictions on C features in this assignment, except for those outlined in the Style Guide. If you choose to use features beyond what has been taught in COMP1511, be aware that course staff may not be able to assist you.

FAQ

Q: Can I edit the provided code?

Yes! Feel free to modify, replace, or discard any of the provided code.

For example: you may wish to add fields to the provided struct cauldron definition.

You are also encouraged to create your own constants, enums, structs, and helper functions.

Q: What C features can I use?

For everything not taught in the course, check the Style Guide:

  • If the guide says "avoid", it may incur a style mark penalty if not used correctly.
  • If the guide says "illegal" or "do not use", it will result in a style mark penalty (see the Style Marking Rubric).

These rules exist to ensure that everyone develops the required foundational knowledge and to maintain a level playing field for all students.

Q: Can I use arrays?

A: No, you cannot use arrays in any part of this assignment. The only exception is when using strings. Using arrays for any part of this assignment will result in a performance mark of zero. Whilst the provided structs contain strings (char arrays), you cannot use arrays for anything else.

Stages

The assignment has been divided into incremental stages.

Stage 1

  • Stage 1.1 - Create and Initialise Structs.
  • Stage 1.2 - Command Loop and Help.
  • Stage 1.3 - Adding Wizards, Cauldrons and Ingredients.
  • Stage 1.4 - Printing the Apothecary.
  • Stage 1.5 - Handling Errors.

Stage 2

  • Stage 2.1 - Inspect a Cauldron.
  • Stage 2.2 - Insert an Ingredient.
  • Stage 2.3 - Bottle a Potion.
  • Stage 2.4 - Reorder a Cauldron.

Stage 3

  • Stage 3.1 - Quit the Apothecary.
  • Stage 3.2 - Remove Potions and Cauldrons.
  • Stage 3.3 - Remove a Wizard.
  • Stage 3.4 - Light and Simmer a Cauldron.

Stage 4

  • Stage 4.1 - Peek at a Brew.
  • Stage 4.2 - Annihilating Ingredients.
  • Stage 4.3 - Duelling Wizards.

Extension (not for marks)

  • SplashKit - Create and Share a Graphical User Interface.

Video Overview

A video explanation to help you get started with the assignment can be found here:

Your Tasks

This assignment consists of four stages. Each stage builds on the work of the previous stage, and each stage has a higher complexity than its predecessor. You should complete the stages in order.

Stage 1

In Stage 1, you will implement some basic commands to turn the starter code into the foundation of our CS Alchemy apothecary!

This milestone has been divided into four substages:

  • Stage 1.1 - Create and Initialise Structs.
  • Stage 1.2 - Command Loop and Help.
  • Stage 1.3 - Adding Wizards, Cauldrons and Ingredients.
  • Stage 1.4 - Printing the Apothecary.
  • Stage 1.5 - Handling Errors.

Stage 1.1 - Create and Initialise Structs

In this stage, we’re going to set up the core data structures that make up our apothecary!

Your first task is to implement the following functions:

  1. create_apothecary()
  2. create_wizard()
  3. create_cauldron()
  4. create_ingredient()
  5. create_potion()

Each of these functions creates a new struct and returns a pointer to it. You can find the parameters each function takes in its prototype in cs_alchemy.h.

You will find unimplemented function stubs for these functions in cs_alchemy.c.

// Stage 1.1
// Function to create the Apothecary
// Params:
//      name - the name of the apothecary
// Returns: a pointer to the apothecary
struct apothecary *create_apothecary(char name[MAX_SIZE]) {

    // TODO: Implement this function
    printf("create_apothecary() not implemented yet!\n");

    return NULL;
}
// Stage 1.1
// Function to create a wizard
// Params:
//      name - the name of the wizard
//      rank - the rank the wizard has attained
// Returns: a pointer to the wizard
struct wizard *create_wizard(char name[MAX_SIZE], enum wizard_rank rank) {

    // TODO: Implement this function
    printf("create_wizard() not implemented yet!\n");

    return NULL;
}
// Stage 1.1
// Function to create a cauldron
// Returns: a pointer to the cauldron
struct cauldron *create_cauldron() {

    // TODO: Implement this function
    printf("create_cauldron() not implemented yet!\n");

    return NULL;
}
// Stage 1.1
// Function to create an ingredient
// Params:
//      type - the ingredient_type of the ingredient
//      effect - the effect_type of the ingredient
//      potency - the ingredients numerical strength
// Returns: a pointer to the ingredient
struct ingredient *create_ingredient(
    enum ingredient_type type,
    enum ingredient_effect effect,
    int potency
) {

    // TODO: Implement this function
    printf("create_ingredient() not implemented yet!\n");

    return NULL;
}
// Stage 1.1
// Function to create a potion
// Params:
//      name - the name of potion
// Returns: a pointer to the potion
struct potion *create_potion(char name[MAX_SIZE]) {

    // TODO: Implement this function
    printf("create_potion() not implemented yet!\n");

    return NULL;
}

To implement these functions:

  1. Find the function stubs in cs_alchemy.c and read the provided comments.
  2. Malloc the space required for the struct.
  3. Assign the provided parameters to the struct’s fields.
  4. Initialise all remaining struct fields to some reasonable values.
  5. Return a pointer to the newly-created struct.

Assumptions / Restrictions / Clarifications

  • No error handling is required for this stage.
  • All cauldrons should have an initial brew_status of READY.
  • All cauldrons and potions should have an initial brew_potency of 0.
  • A new cauldron has not been assigned to a wizard yet, so its assigned_wizard_name should be an empty string. You will fill this in when you implement Stage 1.3.
  • A new cauldron should have an initial required_rank of NOVICE. This will also be overwritten in Stage 1.3.

Testing

There are no autotests for Stage 1.1.

You will need to test your work by:

  1. Compiling your code with dcc to ensure there are no warnings or errors.
  2. Writing temporary testing code to confirm that your functions behave as expected.

You can copy the following testing code into your main() function in main.c.

#include <string.h>
#include <stdio.h>

#include "cs_alchemy.h"

int main(void) {
    // Initialise the apothecary
    char apothecary_name[MAX_SIZE];
    strcpy(apothecary_name, "CS_Alchemy");

    struct apothecary *my_apothecary = create_apothecary(apothecary_name);

    // Print apothecary details
    printf("Apothecary created:\n");
    printf("    Name: %s\n", my_apothecary->name);
    printf("    Wizards: ");
    if (my_apothecary->wizards == NULL) {
        printf("NULL\n");
    } else {
        printf("not set to NULL\n");
    }
    printf("    Cauldrons: ");
    if (my_apothecary->cauldrons == NULL) {
        printf("NULL\n\n");
    } else {
        printf("not set to NULL\n\n");
    }

    // Create a wizard
    char wizard_name[MAX_SIZE];
    strcpy(wizard_name, "Merlin");
    struct wizard *wizard = create_wizard(wizard_name, NOVICE);

    printf("Wizard created: \n");
    printf("    Name: %s\n", wizard->name);
    printf("    Rank: %s\n", wizard_rank_to_string(wizard->rank));
    printf("    Potions: ");
    if (wizard->potions == NULL) {
        printf("NULL\n");
    } else {
        printf("not set to NULL\n");
    }
    printf("    Next wizard: ");
    if (wizard->next == NULL) {
        printf("NULL\n\n");
    } else {
        printf("not set to NULL\n\n");
    }

    // Create a cauldron
    struct cauldron *cauldron = create_cauldron();

    printf("Cauldron created: \n");
    printf("    Assigned wizard name: '%s'\n", cauldron->assigned_wizard_name);
    printf("    Status: %s\n", brew_status_to_string(cauldron->status));
    printf("    Brew potency: %d\n", cauldron->brew_potency);
    printf("    Required rank: %s\n",
        wizard_rank_to_string(cauldron->required_rank));
    printf("    Ingredients: ");
    if (cauldron->ingredients == NULL) {
        printf("NULL\n");
    } else {
        printf("not set to NULL\n");
    }
    printf("    Next cauldron: ");
    if (cauldron->next == NULL) {
        printf("NULL\n\n");
    } else {
        printf("not set to NULL\n\n");
    }

    // Create an ingredient
    struct ingredient *ingredient = create_ingredient(ROOT, CHILLING, 15);

    printf("Ingredient created: \n");
    printf("    Type: %s\n", ingredient_type_to_string(ingredient->type));
    printf("    Effect: %s\n",
        ingredient_effect_to_string(ingredient->effect));
    printf("    Potency: %d\n", ingredient->potency);
    printf("    Next ingredient: ");
    if (ingredient->next == NULL) {
        printf("NULL\n\n");
    } else {
        printf("not set to NULL\n\n");
    }

    // Create a potion
    char potion_name[MAX_SIZE];
    strcpy(potion_name, "White_Phial");
    struct potion *potion = create_potion(potion_name);

    printf("Potion created: \n");
    printf("    Name: %s\n", potion->name);
    printf("    Brew potency: %d\n", potion->brew_potency);
    printf("    Ingredients: ");
    if (potion->ingredients == NULL) {
        printf("NULL\n");
    } else {
        printf("not set to NULL\n");
    }
    printf("    Next potion: ");
    if (potion->next == NULL) {
        printf("NULL\n\n");
    } else {
        printf("not set to NULL\n\n");
    }

    return 0;
}

This code calls create_apothecary(), create_wizard(), create_cauldron(), create_ingredient() and create_potion(), then prints the values stored in the fields of the returned structs.

You can compile and run your program with the following command:

dcc cs_alchemy.c main.c -o cs_alchemy
./cs_alchemy

When you run it, it should print the following:

Apothecary created:
    Name: CS_Alchemy
    Wizards: NULL
    Cauldrons: NULL

Wizard created: 
    Name: Merlin
    Rank: NOVICE
    Potions: NULL
    Next wizard: NULL

Cauldron created: 
    Assigned wizard name: ''
    Status: READY
    Brew potency: 0
    Required rank: NOVICE
    Ingredients: NULL
    Next cauldron: NULL

Ingredient created: 
    Type: ROOT
    Effect: CHILLING
    Potency: 15
    Next ingredient: NULL

Potion created: 
    Name: White_Phial
    Brew potency: 0
    Ingredients: NULL
    Next potion: NULL

Visually, this can be represented as below:

Apothecary, wizard, cauldron, ingredient and potion structs after creation

Stage 1.2 - Command Loop and Help

In this stage, we will implement a command loop, allowing your program to take in commands and perform tasks for our CS Alchemy apothecary!

To do this, we will begin implementing the command_loop() function. This function is called by the main() function in main.c after the apothecary is created.

A function stub has been provided in the cs_alchemy.c starter code.

// Stage 1.2
// Function to run the main command loop for the program
// Params:
//      apothecary - a pointer to the apothecary
// Returns: None
void command_loop(struct apothecary *apothecary) {

    // TODO: Implement this function
    printf("command_loop() not yet implemented!\n");

    return;
}

Your program should continually scan in commands from the user and perform the respective task until [CTRL + D] is entered. To do so, your command_loop() function should:

  1. Print "Enter command: " to prompt the user to enter a command.
  2. Scan in a command.
  3. Execute the task associated with the command.
  4. Repeat steps 1 to 3 until [CTRL + D] is entered.

When [CTRL + D] is entered, the function should end and immediately return to the main() function. The program will then print the goodbye message, as included in the starter code in main.c and end.

The command loop will be extended with new commands as you progress through each stage of the assignment.

The first command you will implement is the Help command, which is described below.

Command

The Help command is called as follows:

?

Description

When the character '?' is entered into your program, it should run the Help command. This doesn't read in any arguments following the initial command and should display a message which lists the different commands and their arguments.

The purpose of this command is to allow anyone using our program to easily look up the different commands. It does not require any further input to be entered after ?.

A helper function: print_usage() in cs_alchemy.c has been provided to help you print and format this message.

// Function to print the program usage information
// Params: None
// Returns: None
void print_usage() {

    printf(
       "===========================[ Usage Info ]==========================\n"
       "                                                                   \n"
       "  ?                                                                \n"
       "    Show this help information.                                    \n"

       "  a w [wizard_name] [rank]                                         \n"
       "    Add a new wizard with the given rank.                          \n"
       "  a c [wizard_name] [required_rank]                                \n"
       "    Add a new cauldron, assigned to the given wizard.              \n"
       "  a i [cauldron_number] [type] [effect]                            \n"
       "    Add a new ingredient to the given cauldron.                    \n"

       "  c [cauldron_number]                                              \n"
       "    Inspect a single cauldron.                                     \n"
       "  i [cauldron_number] [depth] [type] [effect]                      \n"
       "    Insert an ingredient at a given depth.                         \n"
       "  b [cauldron_number] [potion_name]                                \n"
       "    Bottle a cauldron into a potion.                               \n"
       "  o [cauldron_number]                                              \n"
       "    Reorder the ingredients in a cauldron.                         \n"
       "  r p [potion_name]                                                \n"
       "    Remove a potion.                                               \n"
       "  r c [cauldron_number]                                            \n"
       "    Remove a cauldron.                                             \n"
       "  r w [wizard_name]                                                \n"
       "    Remove a wizard and redistribute their potions.                \n"
       "  l [cauldron_number] [turns]                                      \n"
       "    Light a cauldron to simmer for a number of turns.              \n"
       "  s [cauldron_number]                                              \n"
       "    Simmer a cauldron for one turn.                                \n"
       "  p [cauldron_number] [turns]                                      \n"
       "    Peek at what the next simmer turns would do.                   \n"
       "  d [wizard_a] [wizard_b]                                          \n"
       "    Duel two wizards with their potions.                           \n"

       "  *                                                                \n"
       "    Print the apothecary.                                          \n"

       "  q                                                                \n"
       "    Quits the apothecary.                                          \n"
       "                                                                   \n"
       "===================================================================\n"
    );

}

Once the Help command finishes, the program should continue prompting the user for a command until [CTRL + D] is entered as outlined in steps 1 to 3 above.

If an invalid command is entered, your program should print ERROR: Invalid command.\n.

Examples

Input:

CS_Alchemy
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
?
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: ?
===========================[ Usage Info ]==========================
                                                                   
  ?                                                                
    Show this help information.                                    
  a w [wizard_name] [rank]                                         
    Add a new wizard with the given rank.                          
  a c [wizard_name] [required_rank]                                
    Add a new cauldron, assigned to the given wizard.              
  a i [cauldron_number] [type] [effect]                            
    Add a new ingredient to the given cauldron.                    
  c [cauldron_number]                                              
    Inspect a single cauldron.                                     
  i [cauldron_number] [depth] [type] [effect]                      
    Insert an ingredient at a given depth.                         
  b [cauldron_number] [potion_name]                                
    Bottle a cauldron into a potion.                               
  o [cauldron_number]                                              
    Reorder the ingredients in a cauldron.                         
  r p [potion_name]                                                
    Remove a potion.                                               
  r c [cauldron_number]                                            
    Remove a cauldron.                                             
  r w [wizard_name]                                                
    Remove a wizard and redistribute their potions.                
  l [cauldron_number] [turns]                                      
    Light a cauldron to simmer for a number of turns.              
  s [cauldron_number]                                              
    Simmer a cauldron for one turn.                                
  p [cauldron_number] [turns]                                      
    Peek at what the next simmer turns would do.                   
  d [wizard_a] [wizard_b]                                          
    Duel two wizards with their potions.                           
  *                                                                
    Print the apothecary.                                          
  q                                                                
    Quits the apothecary.                                          
                                                                   
===================================================================
Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
z
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: z
ERROR: Invalid command.
Enter command: [CTRL+D]
Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

You may assume that:

  • All commands begin with a single char and may be followed by additional arguments. The number of arguments will depend on each command.
  • Commands will always be given the correct number of arguments.
  • Commands will always be given arguments of the correct type.

Stage 1.3 - Adding Wizards, Cauldrons and Ingredients

At the moment, when CS Alchemy first runs, a new apothecary is created by calling create_apothecary() from the provided main.c file.

The created empty apothecary should look something like this:

Empty apothecary with no wizards or cauldrons

In order to get our potions brewing, we first need to add three key components: the wizards, cauldrons and ingredients!

Your task is to complete the following function stubs in cs_alchemy.c. These functions should then be called inside the command loop depending on which Add command has been entered.

// Stage 1.3
// Function to add a wizard
// Params:
//      apothecary - a pointer to the apothecary
// Returns: None
void add_wizard(struct apothecary *apothecary) {

    // TODO: Implement this function
    printf("add_wizard() not yet implemented!\n");

    return;
}
// Stage 1.3
// Function to add a cauldron, assigned to an existing wizard
// Params:
//      apothecary - a pointer to the apothecary
// Returns: None
void add_cauldron(struct apothecary *apothecary) {

    // TODO: Implement this function
    printf("add_cauldron() not yet implemented!\n");

    return;
}
// Stage 1.3
// Function to add an ingredient to a cauldron
// Params:
//      apothecary - a pointer to the apothecary
// Returns: None
void add_ingredient(struct apothecary *apothecary) {

    // TODO: Implement this function
    printf("add_ingredient() not yet implemented!\n");

    return;
}

Command 1: Add Wizard

The Add Wizard command is called as follows:

a w [wizard_name] [rank]

For example, the command a w merlin NOVICE will add a wizard called merlin with a rank of NOVICE to the apothecary.

Description

When an Add Wizard command is entered, your program should:

  1. Scan in the wizard name using the provided scan_name() function.

  2. Scan in the rank using the provided scan_wizard_rank() function.

  3. Create a new wizard.

  4. Insert the wizard at the head of the apothecary’s wizard list.

  5. Print a message to confirm that the command was successful:

    Wizard: '[name]' added!\n. [name] is the name of the new wizard.

After adding one wizard, the apothecary might look something like this:

Apothecary with one wizard

Command 2: Add Cauldron

The Add Cauldron command is called as follows:

a c [wizard_name] [required_rank]

For example, the command a c merlin NOVICE will add a cauldron assigned to the wizard merlin, which requires a rank of at least NOVICE to use.

Description

When an Add Cauldron command is entered, your program should:

  1. Scan in the wizard name using the provided scan_name() function.

  2. Scan in the required_rank using the provided scan_wizard_rank() function.

  3. Create a cauldron using create_cauldron(), then set its assigned_wizard_name and required_rank to the scanned values.

  4. Insert the cauldron at the tail of the apothecary’s list of cauldrons.

  5. Print a message to confirm that the command was successful:

    Cauldron: assigned to '[wizard_name]'!\n.

[wizard_name] is the name of the wizard the cauldron was assigned to.

After adding one wizard and one cauldron, the apothecary might look something like this:

Apothecary with one wizard and one cauldron

Command 3: Add Ingredient

The Add Ingredient command is called as follows:

a i [cauldron_number] [type] [effect]

For example, the command a i 1 MUSHROOM ENERGETIC will add an ingredient of type MUSHROOM with an effect of ENERGETIC to cauldron 1.

Description

When an Add Ingredient command is entered, your program should:

  1. Scan in the cauldron_number using scanf().
  2. Scan in the type using the provided scan_ingredient_type() function.
  3. Scan in the effect using the provided scan_ingredient_effect() function.
  4. Find the cauldron at position cauldron_number in the apothecary’s list of cauldrons, where the first cauldron is at position 1.
  5. Create the ingredient, giving it the potency for its type (see the table below).
  6. Insert the ingredient at the tail of that cauldron’s list of ingredients.
  7. Increase the cauldron’s brew_potency by the value of the ingredient's starting potency.
  8. Print a message to confirm that the command was successful: Ingredient: [type] [effect] added to cauldron [cauldron_number]!\n. [type] and [effect] are the ingredient's type and effect, converted to strings using the provided ingredient_type_to_string() and ingredient_effect_to_string() functions, and [cauldron_number] is the number of the cauldron it was added to.

An ingredient's potency is a measure of its magical strength, and it is this value that gets added to a cauldron's brew_potency whenever an ingredient is added. In later stages, potency will also determine how ingredients decay over time as a cauldron simmers, and how strong the resulting potion is in a duel against another wizard's potion.

Every ingredient starts with a potency determined by its type:

Type Starting potency
MUSHROOM 30
CRYSTAL 30
ROOT 15
FLOWER 15

After adding one wizard, cauldron and ingredient, the apothecary might look something like this:

Apothecary with one wizard, one cauldron and one ingredient

After adding an additional wizard, cauldron and ingredient, the apothecary might then look something like this:

Apothecary with two wizards, two cauldrons and two ingredients

Examples

Input:

CS_Alchemy
a w merlin NOVICE
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin NOVICE
Wizard: 'merlin' added!
Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin NOVICE
a c merlin NOVICE
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin NOVICE
Wizard: 'merlin' added!
Enter command: a c merlin NOVICE
Cauldron: assigned to 'merlin'!
Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin NOVICE
a c merlin NOVICE
a i 1 CRYSTAL ENERGETIC
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin NOVICE
Wizard: 'merlin' added!
Enter command: a c merlin NOVICE
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL ENERGETIC
Ingredient: CRYSTAL ENERGETIC added to cauldron 1!
Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin NOVICE
a w morgana APPRENTICE
a c merlin NOVICE
a c morgana APPRENTICE
a c merlin NOVICE
a i 1 CRYSTAL ENERGETIC
a i 2 ROOT CHILLING
a i 1 FLOWER SCORCHING
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin NOVICE
Wizard: 'merlin' added!
Enter command: a w morgana APPRENTICE
Wizard: 'morgana' added!
Enter command: a c merlin NOVICE
Cauldron: assigned to 'merlin'!
Enter command: a c morgana APPRENTICE
Cauldron: assigned to 'morgana'!
Enter command: a c merlin NOVICE
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL ENERGETIC
Ingredient: CRYSTAL ENERGETIC added to cauldron 1!
Enter command: a i 2 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 2!
Enter command: a i 1 FLOWER SCORCHING
Ingredient: FLOWER SCORCHING added to cauldron 1!
Enter command: [CTRL+D]
Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • No error handling is required in this stage.
  • The character following a will only ever be w, c, or i. Any other character will not be tested.
  • [wizard_name] is a string with no spaces or punctuation, and will always have length less than MAX_SIZE. This applies for all future stages.
  • Name arguments, such as [wizard_name] here and [potion_name] in later stages, should always be read using the provided scan_name() function. You do not need fgets() or any string handling of your own.
  • [rank] and [required_rank] will be entered as an uppercase string and converted to the correct enum wizard_rank by the scan_wizard_rank() function.
  • [type] will be entered as an uppercase string and converted to the correct enum ingredient_type by the scan_ingredient_type() function.
  • [effect] will be entered as an uppercase string and converted to the correct enum ingredient_effect by the scan_ingredient_effect() function.
  • Until Stage 1.5, you can assume that the returned enums will never be INVALID_RANK, INVALID_TYPE or INVALID_EFFECT, and that the given [wizard_name] and [cauldron_number] will always exist.

Stage 1.4 - Printing the Apothecary

In this stage, you will implement a function to print out our CS Alchemy apothecary!

Command

The Print command is called as follows:

*

Description

When the Print command is entered, your program should print out the contents of the apothecary in the following format:

=-=-=-=-=-=-=-=[Apothecary: [apothecary_name]]=-=-=-=-=-=-=-=
Wizards:
    [List of wizards]

Cauldrons:
    [List of cauldrons] 

Where [apothecary_name] is the name of the apothecary, and [List of wizards] and [List of cauldrons] are replaced with the list of wizards and list of cauldrons in the apothecary respectively. The exact format is as follows:

Under the Wizards: heading, your program should:

  • Print the name and rank of all wizards in the apothecary's wizard list from head to tail, in the format   [name] - [rank]\n, along with each wizard's list of potions. [rank] is the wizard's rank, converted to a string using the provided wizard_rank_to_string() function.
  • If there are no wizards, just print   No wizards yet!\n.

Under the Cauldrons: heading, your program should:

  • Print a numbered list (1-indexed) of all cauldrons in the apothecary's cauldron list from head to tail, along with each cauldron's list of ingredients.
  • If there are no cauldrons, just print   No cauldrons yet!\n.

To see how this should be displayed when printing, see the 1.4 examples below.

To implement this, a function stub has been provided in the cs_alchemy.c starter code.

// Stage 1.4
// Function to print out the apothecary
// Params:
//      apothecary - a pointer to the alchemist's apothecary
// Returns: None
void print_apothecary(struct apothecary *apothecary) {

    // TODO: Implement this function
    printf("print_apothecary() not yet implemented!\n");

    return;
}

// Helper function to print out the potion information
// PARAMS:
//      potion - a pointer to a single potion
// RETURNS: None
void print_potion_list(struct potion *potion) {
    if (potion == NULL) {
        printf("    No potions at the moment!\n\n");
        return;
    }
    while (potion != NULL) {
        printf("    %s [Potency: %d]\n", potion->name, potion->brew_potency);
        printf("      Ingredients: ");
        print_ingredients_horizontally(potion->ingredients);
        printf("\n\n");
        potion = potion->next;
    }
}
// Helper function to print out the cauldron information (including the
// ingredients it holds)
// PARAMS:
//      cauldron - a pointer to a single cauldron
//      index - the 1-indexed position of the cauldron
// RETURNS: None
void print_cauldron(struct cauldron *cauldron, int index) {
    printf("  %d. |%s| [%s]\n", index, cauldron->assigned_wizard_name,
        brew_status_to_string(cauldron->status));
    printf("  Required rank: %s\n",
        wizard_rank_to_string(cauldron->required_rank));
    printf("  Brew potency: %d\n", cauldron->brew_potency);

    printf("\n  ==================================================\n");
    if (cauldron->ingredients == NULL) {
        printf("    No ingredients yet\n");
    } else {
        struct ingredient *ingredient = cauldron->ingredients;
        while (ingredient != NULL) {
            // You might not have seen something like %8s before: this pads
            // the string with spaces if it is less than 8 characters long,
            // making our ingredients appear right-aligned when printed!
            printf("    %8s ::::: %s (%d)\n",
                ingredient_type_to_string(ingredient->type),
                ingredient_effect_to_string(ingredient->effect),
                ingredient->potency);
            ingredient = ingredient->next;
        }
    }

    printf("  ==================================================\n\n");

}
// Helper function to print out a list of ingredients, separated by commas
// PARAMS:
//      head - a pointer to a list of ingredients
// RETURNS: None
void print_ingredients_horizontally(struct ingredient *head) {
    if (head == NULL) {
        return;
    }
    struct ingredient *curr = head;
    while (curr->next != NULL) {
        printf("%s %s, ", ingredient_type_to_string(curr->type),
            ingredient_effect_to_string(curr->effect));
        curr = curr->next;
    }
    printf("%s %s", ingredient_type_to_string(curr->type),
        ingredient_effect_to_string(curr->effect));
}

Examples

Input:

CS_Alchemy
*
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  No wizards yet!

Cauldrons:
  No cauldrons yet!

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin NOVICE
*
a w morgana MASTER
*
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin NOVICE
Wizard: 'merlin' added!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - NOVICE
    No potions at the moment!


Cauldrons:
  No cauldrons yet!

Enter command: a w morgana MASTER
Wizard: 'morgana' added!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - MASTER
    No potions at the moment!

  merlin - NOVICE
    No potions at the moment!


Cauldrons:
  No cauldrons yet!

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin NOVICE
*
a c merlin MASTER
*
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin NOVICE
Cauldron: assigned to 'merlin'!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    No potions at the moment!


Cauldrons:
  1. |merlin| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    No potions at the moment!


Cauldrons:
  1. |merlin| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================

  2. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w morgana MASTER
a c morgana MASTER
a c morgana NOVICE
a i 1 ROOT ENERGETIC
a i 1 MUSHROOM SLOWING
*
a i 2 ROOT SCORCHING
*
a i 2 FLOWER CHILLING
*
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w morgana MASTER
Wizard: 'morgana' added!
Enter command: a c morgana MASTER
Cauldron: assigned to 'morgana'!
Enter command: a c morgana NOVICE
Cauldron: assigned to 'morgana'!
Enter command: a i 1 ROOT ENERGETIC
Ingredient: ROOT ENERGETIC added to cauldron 1!
Enter command: a i 1 MUSHROOM SLOWING
Ingredient: MUSHROOM SLOWING added to cauldron 1!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - MASTER
    No potions at the moment!


Cauldrons:
  1. |morgana| [READY]
  Required rank: MASTER
  Brew potency: 45

  ==================================================
        ROOT ::::: ENERGETIC (15)
    MUSHROOM ::::: SLOWING (30)
  ==================================================

  2. |morgana| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: a i 2 ROOT SCORCHING
Ingredient: ROOT SCORCHING added to cauldron 2!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - MASTER
    No potions at the moment!


Cauldrons:
  1. |morgana| [READY]
  Required rank: MASTER
  Brew potency: 45

  ==================================================
        ROOT ::::: ENERGETIC (15)
    MUSHROOM ::::: SLOWING (30)
  ==================================================

  2. |morgana| [READY]
  Required rank: NOVICE
  Brew potency: 15

  ==================================================
        ROOT ::::: SCORCHING (15)
  ==================================================


Enter command: a i 2 FLOWER CHILLING
Ingredient: FLOWER CHILLING added to cauldron 2!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - MASTER
    No potions at the moment!


Cauldrons:
  1. |morgana| [READY]
  Required rank: MASTER
  Brew potency: 45

  ==================================================
        ROOT ::::: ENERGETIC (15)
    MUSHROOM ::::: SLOWING (30)
  ==================================================

  2. |morgana| [READY]
  Required rank: NOVICE
  Brew potency: 30

  ==================================================
        ROOT ::::: SCORCHING (15)
      FLOWER ::::: CHILLING (15)
  ==================================================


Enter command: [CTRL+D]
Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • Cauldrons are numbered starting from 1, in the order they appear in the apothecary's list of cauldrons.

Stage 1.5 - Handling Errors

In this stage, you will modify your Stage 1.3 code to add some restrictions.

Error conditions

If any of the following errors occur, the command should not be executed and the corresponding error message should be printed.

When adding a wizard:

  • If the rank returned by the scan_wizard_rank() function is INVALID_RANK, the following error should be printed:
    Error: Invalid wizard rank.\n.
  • If there is already an existing wizard with the given [wizard_name], the following error should be printed:
    Error: Wizard [wizard_name] already exists.\n.

When adding a cauldron:

  • If the required_rank returned by the scan_wizard_rank() function is INVALID_RANK, the following error should be printed:
    Error: Invalid wizard rank.\n.
  • If there is no existing wizard with the given [wizard_name], the following error should be printed:
    Error: No wizard with name [wizard_name].\n.
  • If the wizard's rank is lower than the cauldron's required_rank, the following error should be printed:
    Error: Wizard [wizard_name] is not of a high enough rank.\n.

When adding an ingredient:

  • If there is no cauldron at the given [cauldron_number], the following error should be printed:
    Error: Cauldron [cauldron_number] does not exist.\n.
  • If the type returned by the scan_ingredient_type() function is INVALID_TYPE, the following error should be printed:
    Error: Invalid ingredient type.\n.
  • If the effect returned by the scan_ingredient_effect() function is INVALID_EFFECT, the following error should be printed:
    Error: Invalid ingredient effect.\n.

Examples

Input:

CS_Alchemy
a w merlin NOVICE
a w merlin APPRENTICE
*
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin NOVICE
Wizard: 'merlin' added!
Enter command: a w merlin APPRENTICE
Error: Wizard merlin already exists.
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - NOVICE
    No potions at the moment!


Cauldrons:
  No cauldrons yet!

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin NOVICE
a c morgana NOVICE
*
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin NOVICE
Wizard: 'merlin' added!
Enter command: a c morgana NOVICE
Error: No wizard with name morgana.
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - NOVICE
    No potions at the moment!


Cauldrons:
  No cauldrons yet!

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin NOVICE
a c merlin APPRENTICE
a c merlin MASTER
*
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin NOVICE
Wizard: 'merlin' added!
Enter command: a c merlin APPRENTICE
Error: Wizard merlin is not of a high enough rank.
Enter command: a c merlin MASTER
Error: Wizard merlin is not of a high enough rank.
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - NOVICE
    No potions at the moment!


Cauldrons:
  No cauldrons yet!

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin ADEPT
a w morgana NOVICE
a c morgana ADEPT
*
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin ADEPT
Error: Invalid wizard rank.
Enter command: a w morgana NOVICE
Wizard: 'morgana' added!
Enter command: a c morgana ADEPT
Error: Invalid wizard rank.
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - NOVICE
    No potions at the moment!


Cauldrons:
  No cauldrons yet!

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 2 MUSHROOM ENERGETIC
a i 1 PEBBLE ENERGETIC
a i 1 MUSHROOM SPARKLY
a i 1 MUSHROOM ENERGETIC
*
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 2 MUSHROOM ENERGETIC
Error: Cauldron 2 does not exist.
Enter command: a i 1 PEBBLE ENERGETIC
Error: Invalid ingredient type.
Enter command: a i 1 MUSHROOM SPARKLY
Error: Invalid ingredient effect.
Enter command: a i 1 MUSHROOM ENERGETIC
Ingredient: MUSHROOM ENERGETIC added to cauldron 1!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    No potions at the moment!


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 30

  ==================================================
    MUSHROOM ::::: ENERGETIC (30)
  ==================================================


Enter command: [CTRL+D]
Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • If more than one error occurs, only the first error in the order specified above should be addressed by printing an error message. This is the same for all future commands.
  • When checking if a wizard name already exists in the apothecary, the comparison is case-sensitive. For example, if a wizard called merlin is already in the apothecary, trying to add a wizard called Merlin will not be treated as a duplicate, and no error will be raised. This is the same for all future commands.
  • A wizard may use a cauldron whose required_rank is equal to or lower than their own rank. Ranks are ordered NOVICE < APPRENTICE < MASTER.

Testing and Submission

Remember to do your own testing! Are you finished with this stage? If so, you should make sure to do the following:
  • Run 1511 style and clean up any issues a human may have reading your code. Don't forget -- 20% of your mark in the assignment is based on style and readability!
  • Autotest for this stage of the assignment by running the autotest-stage command as shown below.
  • Remember -- give early and give often. Only your last submission counts, but why not be safe and submit right now?
1511 style cs_alchemy.c
1511 style cs_alchemy.h
1511 style main.c
1511 autotest-stage 01 cs_alchemy
give cs1511 ass2_cs_alchemy cs_alchemy.c cs_alchemy.h main.c

Stage 2

This milestone has been divided into four substages:

  • Stage 2.1 - Inspect a Cauldron.
  • Stage 2.2 - Insert an Ingredient.
  • Stage 2.3 - Bottle a Potion.
  • Stage 2.4 - Reorder a Cauldron.

Stage 2.1 - Inspect a Cauldron

Now that wizards can fill their cauldrons with ingredients, they need a way to look inside and see exactly what they're working with!

Command

The Inspect command is called as follows:

c [cauldron_number]

The Inspect command consists of c and then the number of the cauldron to inspect.

For example, the command c 1 will inspect cauldron 1.

Description

When the Inspect command is entered, your program should print the ingredients of the cauldron at the given [cauldron_number], split into two regions, TOP and BOTTOM, based on their position in the cauldron's list of ingredients. The first half of the list is the TOP of the cauldron, and the second half is the BOTTOM.

Every ingredient has a preferred region, based on its type:

Type Preferred region
CRYSTAL TOP
FLOWER TOP
MUSHROOM BOTTOM
ROOT BOTTOM

An ingredient's actual region is determined by its position (depth) in the cauldron's list of ingredients, not its type. If a cauldron has n ingredients, the first half (the first n / 2 ingredients, rounding down) are in the TOP region, and the remaining ingredients are in the BOTTOM region.

An ingredient is misplaced if its actual region does not match its preferred region.

To print a cauldron's ingredients, your program should:

  1. Print the cauldron's number and status, followed by the assigned wizard's name, the cauldron's required_rank and its brew_potency.
  2. Print a TOP divider.
  3. Number each ingredient from first to last, starting at 1. When the halfway point is reached, print a BOTTOM divider before continuing.
  4. For each ingredient, print its type, effect and potency. If the ingredient is misplaced, also print &lt; misplaced after it.
  5. Print a closing divider, followed by a count of how many ingredients in the cauldron are misplaced.

To see the exact format expected, see the examples below.

// The format strings used by the Inspect command, in the order they print.

printf("=-=-= Cauldron %d =-=-= [%s]\n", cauldron_number, status);
printf("  Wizard: %s | Required rank: %s | Brew potency: %d\n\n",
    wizard_name, required_rank, brew_potency);

printf("  ------------------ TOP ------------------\n");
printf("  ----------------- BOTTOM ----------------\n");
printf("  -----------------------------------------\n");

printf("    No ingredients yet\n");

printf("  %2d. %s ::::: %s (%d)", depth, type, effect, potency);
printf("   < misplaced");
printf("\n");

printf("\n  %d of %d ingredients are misplaced.\n\n",
    num_misplaced, num_ingredients);

The cauldron's status and required_rank, and each ingredient's type and effect, should be converted to strings using the provided brew_status_to_string(), wizard_rank_to_string(), ingredient_type_to_string() and ingredient_effect_to_string() functions.

Errors

  • If there is no cauldron at the given [cauldron_number], the following error message should be printed:
    Error: Cauldron [cauldron_number] does not exist.\n.

Examples

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL SLOWING
a i 1 MUSHROOM ENERGETIC
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: a i 1 MUSHROOM ENERGETIC
Ingredient: MUSHROOM ENERGETIC added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 60

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (30)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: ENERGETIC (30)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 ROOT SLOWING
a i 1 FLOWER ENERGETIC
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 ROOT SLOWING
Ingredient: ROOT SLOWING added to cauldron 1!
Enter command: a i 1 FLOWER ENERGETIC
Ingredient: FLOWER ENERGETIC added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 30

  ------------------ TOP ------------------
   1. ROOT ::::: SLOWING (15)   < misplaced
  ----------------- BOTTOM ----------------
   2. FLOWER ::::: ENERGETIC (15)   < misplaced
  -----------------------------------------

  2 of 2 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 0

  ------------------ TOP ------------------
    No ingredients yet
  ----------------- BOTTOM ----------------
    No ingredients yet
  -----------------------------------------

  0 of 0 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL SLOWING
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 30

  ------------------ TOP ------------------
  ----------------- BOTTOM ----------------
   1. CRYSTAL ::::: SLOWING (30)   < misplaced
  -----------------------------------------

  1 of 1 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
c 1
a c merlin MASTER
c 0
c 2
c -1
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: c 1
Error: Cauldron 1 does not exist.
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: c 0
Error: Cauldron 0 does not exist.
Enter command: c 2
Error: Cauldron 2 does not exist.
Enter command: c -1
Error: Cauldron -1 does not exist.
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 0

  ------------------ TOP ------------------
    No ingredients yet
  ----------------- BOTTOM ----------------
    No ingredients yet
  -----------------------------------------

  0 of 0 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • Cauldrons are numbered starting from 1, in the order they appear in the apothecary's list of cauldrons, as in previous stages.
  • If a cauldron has no ingredients, both its TOP and BOTTOM regions should print No ingredients yet in place of a list of ingredients, and there are 0 of 0 ingredients misplaced.

Stage 2.2 - Insert an Ingredient

So far, ingredients have only ever been added to the tail of a cauldron's list of ingredients. In this stage, wizards will be able to insert an ingredient at any depth they choose!

Command

The Insert Ingredient command is called as follows:

i [cauldron_number] [depth] [type] [effect]

The Insert Ingredient command consists of i and then the number of the cauldron, the depth at which to insert the new ingredient, followed by the ingredient's type and effect.

For example, the command i 1 2 CRYSTAL CHILLING will insert a CRYSTAL ingredient with a CHILLING effect at depth 2 in cauldron 1.

Description

When an Insert Ingredient command is entered, your program should:

  1. Find the cauldron at the given [cauldron_number].
  2. Create the ingredient, giving it the potency for its type, using the same table introduced in Stage 1.3.
  3. Insert the ingredient into that cauldron's list of ingredients so that it becomes the ingredient at the given [depth].
  4. Add the ingredient's potency to the cauldron's brew_potency.
  5. Print a message to confirm that the command was successful:
    Ingredient: [type] [effect] inserted into cauldron [cauldron_number] at depth [depth]!\n.

Before any ingredients are added, the apothecary might look something like this:

Apothecary with one wizard and an empty cauldron

After adding an ingredient with a i 1 MUSHROOM ENERGETIC, the cauldron has a single ingredient:

Cauldron with one ingredient

Inserting an ingredient at depth 1 with i 1 1 FLOWER SLOWING places it at the head of the list, in front of the existing ingredient:

Cauldron after inserting an ingredient at the head

Then, inserting an ingredient at depth 2 with i 1 2 CRYSTAL CHILLING places it in the middle of the list, so that it becomes the ingredient at depth 2:

Cauldron after inserting an ingredient in the middle

Errors

The following errors should be checked in order:

  • If there is no cauldron at the given [cauldron_number], the following error message should be printed:
    Error: Cauldron [cauldron_number] does not exist.\n.
  • If [depth] is less than 1, or greater than the number of ingredients currently in the cauldron plus 1, the following error message should be printed:
    Error: Invalid depth.\n.
  • If the type returned by the scan_ingredient_type() function is INVALID_TYPE, the following error message should be printed:
    Error: Invalid ingredient type.\n.
  • If the effect returned by the scan_ingredient_effect() function is INVALID_EFFECT, the following error message should be printed:
    Error: Invalid ingredient effect.\n.

Examples

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 ROOT CHILLING
a i 1 MUSHROOM INERT
c 1
i 1 1 CRYSTAL SLOWING
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 45

  ------------------ TOP ------------------
   1. ROOT ::::: CHILLING (15)   < misplaced
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (30)
  -----------------------------------------

  1 of 2 ingredients are misplaced.

Enter command: i 1 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING inserted into cauldron 1 at depth 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 75

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (30)
  ----------------- BOTTOM ----------------
   2. ROOT ::::: CHILLING (15)
   3. MUSHROOM ::::: INERT (30)
  -----------------------------------------

  0 of 3 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL SLOWING
a i 1 FLOWER ENERGETIC
c 1
i 1 3 MUSHROOM INERT
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: a i 1 FLOWER ENERGETIC
Ingredient: FLOWER ENERGETIC added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 45

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (30)
  ----------------- BOTTOM ----------------
   2. FLOWER ::::: ENERGETIC (15)   < misplaced
  -----------------------------------------

  1 of 2 ingredients are misplaced.

Enter command: i 1 3 MUSHROOM INERT
Ingredient: MUSHROOM INERT inserted into cauldron 1 at depth 3!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 75

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (30)
  ----------------- BOTTOM ----------------
   2. FLOWER ::::: ENERGETIC (15)   < misplaced
   3. MUSHROOM ::::: INERT (30)
  -----------------------------------------

  1 of 3 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL SLOWING
a i 1 MUSHROOM INERT
i 1 0 ROOT FLYING
i 1 4 ROOT FLYING
i 1 -1 ROOT FLYING
c 1
i 1 3 ROOT FLYING
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: i 1 0 ROOT FLYING
Error: Invalid depth.
Enter command: i 1 4 ROOT FLYING
Error: Invalid depth.
Enter command: i 1 -1 ROOT FLYING
Error: Invalid depth.
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 60

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (30)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (30)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: i 1 3 ROOT FLYING
Ingredient: ROOT FLYING inserted into cauldron 1 at depth 3!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 75

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (30)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (30)
   3. ROOT ::::: FLYING (15)
  -----------------------------------------

  0 of 3 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
i 1 1 PEBBLE SLOWING
i 1 1 CRYSTAL SPARKLY
i 1 1 PEBBLE SPARKLY
i 1 1 CRYSTAL SLOWING
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: i 1 1 PEBBLE SLOWING
Error: Invalid ingredient type.
Enter command: i 1 1 CRYSTAL SPARKLY
Error: Invalid ingredient effect.
Enter command: i 1 1 PEBBLE SPARKLY
Error: Invalid ingredient type.
Enter command: i 1 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING inserted into cauldron 1 at depth 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 30

  ------------------ TOP ------------------
  ----------------- BOTTOM ----------------
   1. CRYSTAL ::::: SLOWING (30)   < misplaced
  -----------------------------------------

  1 of 1 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • Depths are 1-indexed, counting from the head of the cauldron's list of ingredients.
  • An ingredient's misplaced status (from Stage 2.1) is always recalculated based on its position after insertion, since inserting an ingredient changes the total number of ingredients in the cauldron, and therefore where the TOP/BOTTOM boundary falls.

Stage 2.3 - Bottle a Potion

A cauldron's brew is not exactly usable until it is decanted into a magnificent bottle! In this stage, wizards will be able to bottle the contents of a cauldron into a potion.

Command

The Bottle Cauldron command is called as follows:

b [cauldron_number] [potion_name]

The Bottle Cauldron command consists of b and then the number of the cauldron to bottle, followed by the name to give the resulting potion.

For example, the command b 1 White_Phial will bottle the contents of cauldron 1 into a new potion called White_Phial.

Description

When a Bottle Cauldron command is entered, your program should:

  1. Create a new potion with the given [potion_name].
  2. Find the cauldron at the given [cauldron_number].
  3. Move the cauldron's entire list of ingredients into the new potion's list of ingredients, and set the potion's brew_potency to the cauldron's brew_potency.
  4. Empty the cauldron, ready to be filled again: its list of ingredients should become empty, and its brew_potency should reset to 0.
  5. Find the wizard assigned to the cauldron, and add the new potion to the tail of that wizard's list of potions.
  6. Print a message to confirm that the command was successful:
    Potion: '[potion_name]' bottled by [wizard_name]!\n. [wizard_name] is the name of the wizard the cauldron is assigned to.

Before bottling, the cauldron holds three ingredients:

Cauldron with three ingredients before bottling

After b 1 White_Phial, the ingredients are moved into the new potion and the cauldron is emptied:

Wizard with a bottled potion holding the ingredients, and an empty cauldron

Errors

The following errors should be checked in order:

  • If there is no cauldron at the given [cauldron_number], the following error message should be printed:
    Error: Cauldron [cauldron_number] does not exist.\n.
  • If the cauldron has no ingredients, the following error message should be printed:
    Error: Cauldron [cauldron_number] is empty.\n.

Examples

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL SLOWING
a i 1 MUSHROOM INERT
b 1 elixir_of_haste
*
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: b 1 elixir_of_haste
Potion: 'elixir_of_haste' bottled by merlin!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    elixir_of_haste [Potency: 60]
      Ingredients: CRYSTAL SLOWING, MUSHROOM INERT


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL SLOWING
a i 1 MUSHROOM INERT
c 1
b 1 elixir_of_haste
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 60

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (30)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (30)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: b 1 elixir_of_haste
Potion: 'elixir_of_haste' bottled by merlin!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 0

  ------------------ TOP ------------------
    No ingredients yet
  ----------------- BOTTOM ----------------
    No ingredients yet
  -----------------------------------------

  0 of 0 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
b 1 nothing_brew
a i 1 CRYSTAL SLOWING
b 1 real_brew
b 1 nothing_again
*
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: b 1 nothing_brew
Error: Cauldron 1 is empty.
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: b 1 real_brew
Potion: 'real_brew' bottled by merlin!
Enter command: b 1 nothing_again
Error: Cauldron 1 is empty.
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    real_brew [Potency: 30]
      Ingredients: CRYSTAL SLOWING


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
b 1 ghost_brew
a c merlin MASTER
a i 1 CRYSTAL SLOWING
b 0 ghost_brew
b 2 ghost_brew
b -1 ghost_brew
b 1 real_brew
*
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: b 1 ghost_brew
Error: Cauldron 1 does not exist.
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: b 0 ghost_brew
Error: Cauldron 0 does not exist.
Enter command: b 2 ghost_brew
Error: Cauldron 2 does not exist.
Enter command: b -1 ghost_brew
Error: Cauldron -1 does not exist.
Enter command: b 1 real_brew
Potion: 'real_brew' bottled by merlin!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    real_brew [Potency: 30]
      Ingredients: CRYSTAL SLOWING


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: [CTRL+D]
Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • Potions are added to the tail of a wizard's list of potions, in the order they were bottled.
  • You may assume that there will be no two potions with the same name.

Stage 2.4 - Reorder a Cauldron

In this stage, we will allow a wizard to optimise a cauldron so our brew can be as strong as possible!

Command

The Reorder Cauldron command is called as follows:

o [cauldron_number]

The Reorder Cauldron command consists of o and then the number of the cauldron to reorder.

For example, the command o 1 will reorder the ingredients in cauldron 1.

Description

When a Reorder Cauldron command is entered, your program should rearrange the cauldron's list of ingredients so that every ingredient which prefers the TOP region (CRYSTAL and FLOWER) appears before every ingredient which prefers the BOTTOM region (MUSHROOM and ROOT), while keeping the relative order of ingredients within each of these two groups unchanged.

Print a message to confirm that the command was successful:
Cauldron [cauldron_number] reordered!\n.

Before reordering, the cauldron's ingredients are out of order:

Cauldron with ingredients out of order before reordering

After o 1, ingredients that prefer the TOP are moved in front of ingredients that prefer the BOTTOM, keeping their relative order:

Cauldron after reordering, with top-preferring ingredients first

Errors

  • If there is no cauldron at the given [cauldron_number], the following error message should be printed:
    Error: Cauldron [cauldron_number] does not exist.\n.

Examples

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 MUSHROOM INERT
a i 1 CRYSTAL SLOWING
c 1
o 1
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 60

  ------------------ TOP ------------------
   1. MUSHROOM ::::: INERT (30)   < misplaced
  ----------------- BOTTOM ----------------
   2. CRYSTAL ::::: SLOWING (30)   < misplaced
  -----------------------------------------

  2 of 2 ingredients are misplaced.

Enter command: o 1
Cauldron 1 reordered!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 60

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (30)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (30)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 MUSHROOM INERT
a i 1 ROOT CHILLING
a i 1 FLOWER ENERGETIC
a i 1 CRYSTAL SLOWING
c 1
o 1
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: a i 1 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 1!
Enter command: a i 1 FLOWER ENERGETIC
Ingredient: FLOWER ENERGETIC added to cauldron 1!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 90

  ------------------ TOP ------------------
   1. MUSHROOM ::::: INERT (30)   < misplaced
   2. ROOT ::::: CHILLING (15)   < misplaced
  ----------------- BOTTOM ----------------
   3. FLOWER ::::: ENERGETIC (15)   < misplaced
   4. CRYSTAL ::::: SLOWING (30)   < misplaced
  -----------------------------------------

  4 of 4 ingredients are misplaced.

Enter command: o 1
Cauldron 1 reordered!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 90

  ------------------ TOP ------------------
   1. FLOWER ::::: ENERGETIC (15)
   2. CRYSTAL ::::: SLOWING (30)
  ----------------- BOTTOM ----------------
   3. MUSHROOM ::::: INERT (30)
   4. ROOT ::::: CHILLING (15)
  -----------------------------------------

  0 of 4 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
o 1
c 1
a i 1 ROOT CHILLING
o 1
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: o 1
Cauldron 1 reordered!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 0

  ------------------ TOP ------------------
    No ingredients yet
  ----------------- BOTTOM ----------------
    No ingredients yet
  -----------------------------------------

  0 of 0 ingredients are misplaced.

Enter command: a i 1 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 1!
Enter command: o 1
Cauldron 1 reordered!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 15

  ------------------ TOP ------------------
  ----------------- BOTTOM ----------------
   1. ROOT ::::: CHILLING (15)
  -----------------------------------------

  0 of 1 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
o 1
a c merlin MASTER
a i 1 MUSHROOM INERT
a i 1 CRYSTAL SLOWING
o 0
o 2
o -1
o 1
c 1
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: o 1
Error: Cauldron 1 does not exist.
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: o 0
Error: Cauldron 0 does not exist.
Enter command: o 2
Error: Cauldron 2 does not exist.
Enter command: o -1
Error: Cauldron -1 does not exist.
Enter command: o 1
Cauldron 1 reordered!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 60

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (30)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (30)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: [CTRL+D]
Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • Reordering an empty or single-ingredient cauldron should succeed and print the usual confirmation message; there is simply nothing (or nothing more) to rearrange.
  • Reordering a cauldron does not change its brew_potency, since the same ingredients (with the same potencies) remain in the cauldron, just in a different order.
  • You should not malloc() any new ingredient structs to do this. You also do not need to copy any ingredient's fields into a new struct.

Testing and Submission

Remember to do your own testing! Are you finished with this stage? If so, you should make sure to do the following:
  • Run 1511 style and clean up any issues a human may have reading your code. Don't forget -- 20% of your mark in the assignment is based on style and readability!
  • Autotest for this stage of the assignment by running the autotest-stage command as shown below.
  • Remember -- give early and give often. Only your last submission counts, but why not be safe and submit right now?
1511 style cs_alchemy.c
1511 style cs_alchemy.h
1511 style main.c
1511 autotest-stage 02 cs_alchemy
give cs1511 ass2_cs_alchemy cs_alchemy.c cs_alchemy.h main.c

Stage 3

Stage 3 will focus on removing wizards and cauldrons, freeing memory, and finally brewing some potions! This milestone has been divided into four substages:

  • Stage 3.1 - Quit the Apothecary.
  • Stage 3.2 - Remove Potions and Cauldrons.
  • Stage 3.3 - Remove a Wizard.
  • Stage 3.4 - Light and Simmer a Cauldron.

Stage 3.1 - Quit the Apothecary

Every wizard eventually needs to close up shop for the day! In this stage, you will implement the logic for quitting the apothecary and freeing all of its memory.

Command

The Quit command is called as follows:

q

Description

When the q command is entered, or when [CTRL + D] is pressed, all malloc'd memory should be freed and the command loop should end.

Once complete, it should print out the final message at the end of the provided main() function before terminating:
Thank you for brewing potions!. This is already handled for you in the provided main.c.

Examples

Input:

CS_Alchemy
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  No wizards yet!

Cauldrons:
  No cauldrons yet!

Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a w morgana APPRENTICE
a c merlin MASTER
a c morgana APPRENTICE
a c merlin NOVICE
a i 1 CRYSTAL SLOWING
a i 1 MUSHROOM INERT
a i 2 ROOT CHILLING
a i 3 FLOWER ENERGETIC
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a w morgana APPRENTICE
Wizard: 'morgana' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a c morgana APPRENTICE
Cauldron: assigned to 'morgana'!
Enter command: a c merlin NOVICE
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: a i 2 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 2!
Enter command: a i 3 FLOWER ENERGETIC
Ingredient: FLOWER ENERGETIC added to cauldron 3!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - APPRENTICE
    No potions at the moment!

  merlin - MASTER
    No potions at the moment!


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 60

  ==================================================
     CRYSTAL ::::: SLOWING (30)
    MUSHROOM ::::: INERT (30)
  ==================================================

  2. |morgana| [READY]
  Required rank: APPRENTICE
  Brew potency: 15

  ==================================================
        ROOT ::::: CHILLING (15)
  ==================================================

  3. |merlin| [READY]
  Required rank: NOVICE
  Brew potency: 15

  ==================================================
      FLOWER ::::: ENERGETIC (15)
  ==================================================


Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL SLOWING
a i 1 MUSHROOM INERT
b 1 elixir_of_haste
a i 1 ROOT CHILLING
b 1 tonic_of_calm
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: b 1 elixir_of_haste
Potion: 'elixir_of_haste' bottled by merlin!
Enter command: a i 1 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 1!
Enter command: b 1 tonic_of_calm
Potion: 'tonic_of_calm' bottled by merlin!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    elixir_of_haste [Potency: 60]
      Ingredients: CRYSTAL SLOWING, MUSHROOM INERT

    tonic_of_calm [Potency: 15]
      Ingredients: ROOT CHILLING


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL SLOWING
*
[CTRL+D]

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    No potions at the moment!


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 30

  ==================================================
     CRYSTAL ::::: SLOWING (30)
  ==================================================


Enter command: [CTRL+D]
Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • The q command does not take any arguments.
  • From Stage 3.1 onwards, you should check for memory leaks by compiling with --leak-check, as seen in the examples below.
  • Autotests and marking tests from this stage onwards will check for memory leaks.

Stage 3.2 - Remove Potions and Cauldrons

Even the most powerful wizards occassionally create a brew undeserving of being bottled into a potion. In this stage, wizards will be able to remove potions they no longer want, and remove cauldrons entirely.

Command 1: Remove Potion

The Remove Potion command is called as follows:

r p [potion_name]

For example, the command r p elixir_of_haste will remove the potion called elixir_of_haste.

Description

When the Remove Potion command is entered, your program should find the potion with the given [potion_name] in any wizard's list of potions, remove it from that list, and free all memory associated with it (including its list of ingredients).

Print a message to confirm that the command was successful:
Potion: '[potion_name]' discarded!\n.

Errors

  • If there is no potion with the given [potion_name] in any wizard's list of potions, the following error message should be printed:
    Error: No potion with name [potion_name].\n.

Command 2: Remove Cauldron

The Remove Cauldron command is called as follows:

r c [cauldron_number]

For example, the command r c 2 will remove cauldron 2 from the apothecary.

Description

When the Remove Cauldron command is entered, your program should find the cauldron at the given [cauldron_number], remove it from the apothecary's list of cauldrons, and free all memory associated with it (including its list of ingredients).

Print a message to confirm that the command was successful:
Cauldron [cauldron_number] removed!\n.

Errors

  • If there is no cauldron at the given [cauldron_number], the following error message should be printed:
    Error: Cauldron [cauldron_number] does not exist.\n.

Examples

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL SLOWING
b 1 first_elixir
a i 1 ROOT CHILLING
b 1 second_elixir
*
r p first_elixir
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: b 1 first_elixir
Potion: 'first_elixir' bottled by merlin!
Enter command: a i 1 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 1!
Enter command: b 1 second_elixir
Potion: 'second_elixir' bottled by merlin!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    first_elixir [Potency: 30]
      Ingredients: CRYSTAL SLOWING

    second_elixir [Potency: 15]
      Ingredients: ROOT CHILLING


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: r p first_elixir
Potion: 'first_elixir' discarded!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    second_elixir [Potency: 15]
      Ingredients: ROOT CHILLING


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a c merlin NOVICE
a c merlin APPRENTICE
a i 1 CRYSTAL SLOWING
a i 2 ROOT CHILLING
a i 3 MUSHROOM INERT
*
r c 2
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a c merlin NOVICE
Cauldron: assigned to 'merlin'!
Enter command: a c merlin APPRENTICE
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: a i 2 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 2!
Enter command: a i 3 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 3!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    No potions at the moment!


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 30

  ==================================================
     CRYSTAL ::::: SLOWING (30)
  ==================================================

  2. |merlin| [READY]
  Required rank: NOVICE
  Brew potency: 15

  ==================================================
        ROOT ::::: CHILLING (15)
  ==================================================

  3. |merlin| [READY]
  Required rank: APPRENTICE
  Brew potency: 30

  ==================================================
    MUSHROOM ::::: INERT (30)
  ==================================================


Enter command: r c 2
Cauldron 2 removed!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    No potions at the moment!


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 30

  ==================================================
     CRYSTAL ::::: SLOWING (30)
  ==================================================

  2. |merlin| [READY]
  Required rank: APPRENTICE
  Brew potency: 30

  ==================================================
    MUSHROOM ::::: INERT (30)
  ==================================================


Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
r p ghost_elixir
r c 1
a c merlin MASTER
a i 1 CRYSTAL SLOWING
b 1 real_elixir
r p ghost_elixir
r p real_elixir
r p real_elixir
r c 0
r c 2
r c -1
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: r p ghost_elixir
Error: No potion with name ghost_elixir.
Enter command: r c 1
Error: Cauldron 1 does not exist.
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: b 1 real_elixir
Potion: 'real_elixir' bottled by merlin!
Enter command: r p ghost_elixir
Error: No potion with name ghost_elixir.
Enter command: r p real_elixir
Potion: 'real_elixir' discarded!
Enter command: r p real_elixir
Error: No potion with name real_elixir.
Enter command: r c 0
Error: Cauldron 0 does not exist.
Enter command: r c 2
Error: Cauldron 2 does not exist.
Enter command: r c -1
Error: Cauldron -1 does not exist.
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    No potions at the moment!


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a w morgana APPRENTICE
a c merlin MASTER
a c morgana APPRENTICE
a i 1 CRYSTAL SLOWING
a i 2 ROOT CHILLING
b 1 merlin_elixir
a i 1 MUSHROOM INERT
*
r p merlin_elixir
r c 1
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a w morgana APPRENTICE
Wizard: 'morgana' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a c morgana APPRENTICE
Cauldron: assigned to 'morgana'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: a i 2 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 2!
Enter command: b 1 merlin_elixir
Potion: 'merlin_elixir' bottled by merlin!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - APPRENTICE
    No potions at the moment!

  merlin - MASTER
    merlin_elixir [Potency: 30]
      Ingredients: CRYSTAL SLOWING


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 30

  ==================================================
    MUSHROOM ::::: INERT (30)
  ==================================================

  2. |morgana| [READY]
  Required rank: APPRENTICE
  Brew potency: 15

  ==================================================
        ROOT ::::: CHILLING (15)
  ==================================================


Enter command: r p merlin_elixir
Potion: 'merlin_elixir' discarded!
Enter command: r c 1
Cauldron 1 removed!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - APPRENTICE
    No potions at the moment!

  merlin - MASTER
    No potions at the moment!


Cauldrons:
  1. |morgana| [READY]
  Required rank: APPRENTICE
  Brew potency: 15

  ==================================================
        ROOT ::::: CHILLING (15)
  ==================================================


Enter command: q

Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • Removing a potion with the same name as another potion will not be tested, since potion names are assumed to be unique (as established in Stage 2.3).
  • The character following r will only ever be p, c, or w (from Stage 3.3). Any other character will not be tested.

Stage 3.3 - Remove a Wizard

Some wizards decide alchemy just isn't for them and move onto enchanting instead! In this stage, you will implement a command to remove a wizard, redistributing their potions to the remaining wizards.

Command

The Remove Wizard command is called as follows:

r w [wizard_name]

For example, the command r w Gandalf will remove the wizard called Gandalf from the apothecary.

Description

When the Remove Wizard command is entered, your program should:

  1. Redistribute the wizard's potions, one at a time, to the remaining wizards (every wizard other than the one being removed), using the following process:
    • Find the new owner for a potion: the wizard, other than the one being removed, with the fewest potions in their list of potions.
      • If multiple wizards are tied for the fewest potions, the new owner is whichever of them is closer to the head of the apothecary's list of wizards.
    • Move the potion that is at the head of the departing wizard's list of potions to the tail of the new owner's list of potions.
    • Repeat until all of the departing wizard's potions have been redistributed.
  2. Free every cauldron assigned to the given wizard (along with their ingredients), removing them from the apothecary's list of cauldrons.
  3. Remove the wizard from the apothecary's list of wizards, and free their memory.
  4. Print a message to confirm that the command was successful:
    Wizard: '[wizard_name]' has left the apothecary!\n.

Before removing, the departing wizard has two potions and one cauldron:

Apothecary with three wizards, where the middle wizard has two potions and a cauldron

After r w Gandalf, each potion is moved to the remaining wizard with the fewest potions (ties go to the wizard closest to the head), and the departing wizard's cauldron is freed:

Apothecary after removing the middle wizard, with their potions redistributed

Errors

The following errors should be checked in order:

  • If there is no wizard with the given [wizard_name], the following error message should be printed:
    Error: No wizard with name [wizard_name].\n.
  • If the wizard has potions to redistribute, but is the only wizard remaining in the apothecary, the following error message should be printed:
    Error: Potions could not be redistributed to other wizards.\n, and the wizard, their cauldrons, and their potions should not be removed or modified.

Examples

Input:

CS_Alchemy
a w merlin MASTER
a w morgana APPRENTICE
*
r w morgana
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a w morgana APPRENTICE
Wizard: 'morgana' added!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - APPRENTICE
    No potions at the moment!

  merlin - MASTER
    No potions at the moment!


Cauldrons:
  No cauldrons yet!

Enter command: r w morgana
Wizard: 'morgana' has left the apothecary!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    No potions at the moment!


Cauldrons:
  No cauldrons yet!

Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a w morgana APPRENTICE
a w gandalf MASTER
a c gandalf MASTER
a i 1 CRYSTAL SLOWING
b 1 first_elixir
a i 1 ROOT CHILLING
b 1 second_elixir
a i 1 MUSHROOM INERT
b 1 third_elixir
a i 1 FLOWER ENERGETIC
b 1 fourth_elixir
*
r w gandalf
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a w morgana APPRENTICE
Wizard: 'morgana' added!
Enter command: a w gandalf MASTER
Wizard: 'gandalf' added!
Enter command: a c gandalf MASTER
Cauldron: assigned to 'gandalf'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: b 1 first_elixir
Potion: 'first_elixir' bottled by gandalf!
Enter command: a i 1 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 1!
Enter command: b 1 second_elixir
Potion: 'second_elixir' bottled by gandalf!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: b 1 third_elixir
Potion: 'third_elixir' bottled by gandalf!
Enter command: a i 1 FLOWER ENERGETIC
Ingredient: FLOWER ENERGETIC added to cauldron 1!
Enter command: b 1 fourth_elixir
Potion: 'fourth_elixir' bottled by gandalf!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  gandalf - MASTER
    first_elixir [Potency: 30]
      Ingredients: CRYSTAL SLOWING

    second_elixir [Potency: 15]
      Ingredients: ROOT CHILLING

    third_elixir [Potency: 30]
      Ingredients: MUSHROOM INERT

    fourth_elixir [Potency: 15]
      Ingredients: FLOWER ENERGETIC

  morgana - APPRENTICE
    No potions at the moment!

  merlin - MASTER
    No potions at the moment!


Cauldrons:
  1. |gandalf| [READY]
  Required rank: MASTER
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: r w gandalf
Wizard: 'gandalf' has left the apothecary!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - APPRENTICE
    first_elixir [Potency: 30]
      Ingredients: CRYSTAL SLOWING

    third_elixir [Potency: 30]
      Ingredients: MUSHROOM INERT

  merlin - MASTER
    second_elixir [Potency: 15]
      Ingredients: ROOT CHILLING

    fourth_elixir [Potency: 15]
      Ingredients: FLOWER ENERGETIC


Cauldrons:
  No cauldrons yet!

Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
r w gandalf
a c merlin MASTER
a i 1 CRYSTAL SLOWING
b 1 lonely_elixir
r w merlin
r p lonely_elixir
r w merlin
r w merlin
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: r w gandalf
Error: No wizard with name gandalf.
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: b 1 lonely_elixir
Potion: 'lonely_elixir' bottled by merlin!
Enter command: r w merlin
Error: Potions could not be redistributed to other wizards.
Enter command: r p lonely_elixir
Potion: 'lonely_elixir' discarded!
Enter command: r w merlin
Wizard: 'merlin' has left the apothecary!
Enter command: r w merlin
Error: No wizard with name merlin.
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  No wizards yet!

Cauldrons:
  No cauldrons yet!

Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a w morgana APPRENTICE
a w gandalf MASTER
a c morgana APPRENTICE
a i 1 CRYSTAL SLOWING
b 1 morgana_elixir
*
r w morgana
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a w morgana APPRENTICE
Wizard: 'morgana' added!
Enter command: a w gandalf MASTER
Wizard: 'gandalf' added!
Enter command: a c morgana APPRENTICE
Cauldron: assigned to 'morgana'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: b 1 morgana_elixir
Potion: 'morgana_elixir' bottled by morgana!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  gandalf - MASTER
    No potions at the moment!

  morgana - APPRENTICE
    morgana_elixir [Potency: 30]
      Ingredients: CRYSTAL SLOWING

  merlin - MASTER
    No potions at the moment!


Cauldrons:
  1. |morgana| [READY]
  Required rank: APPRENTICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: r w morgana
Wizard: 'morgana' has left the apothecary!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  gandalf - MASTER
    morgana_elixir [Potency: 30]
      Ingredients: CRYSTAL SLOWING

  merlin - MASTER
    No potions at the moment!


Cauldrons:
  No cauldrons yet!

Enter command: q

Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • If the wizard being removed has no potions, none need to be redistributed, so they can be removed immediately.

Stage 3.4 - Light and Simmer a Cauldron

Now its time to finally do some alchemy and brew some potions! In this stage, wizards will be able to light a cauldron and let it simmer, gradually turning its ingredients into a more potent brew.

Command 1: Light Cauldron

The Light Cauldron command is called as follows:

l [cauldron_number] [turns]

For example, the command l 1 5 will light cauldron 1 to simmer for 5 turns.

Description

When the Light Cauldron command is entered, your program should set the given cauldron's status to SIMMERING, and set the number of turns it has left to simmer to the given [turns].

Print a message to confirm that the command was successful:
Cauldron [cauldron_number] lit for [turns] turns!\n.

Before lighting, the cauldron is READY and holds three ingredients:

Ready cauldron with three ingredients before lighting

After l 1 5, the cauldron's status becomes SIMMERING, with 5 turns left to simmer:

Simmering cauldron with three ingredients after lighting

Errors

The following errors should be checked in order:

  • If there is no cauldron at the given [cauldron_number], the following error message should be printed:
    Error: Cauldron [cauldron_number] does not exist.\n.
  • If the cauldron's status is not READY, the following error message should be printed:
    Error: Cauldron [cauldron_number] is not ready to be lit.\n.
  • If the cauldron has no ingredients, the following error message should be printed:
    Error: Cauldron [cauldron_number] is empty.\n.
  • If [turns] is less than 1, or greater than 10, the following error message should be printed:
    Error: Brew turns must be between 1 and 10.\n.

Command 2: Simmer Cauldron

The Simmer Cauldron command is called as follows:

s [cauldron_number]

For example, the command s 1 will simmer cauldron 1 for one turn.

Description

When the Simmer Cauldron command is entered, the given cauldron should progress by a single turn:

  1. Every ingredient currently in the cauldron loses 3 potency (an ingredient's potency cannot drop below 0).
  2. For every ingredient that is not misplaced (as defined in Stage 2.1, determined from their positions at the start of the turn), the cauldron's brew_potency increases by 6. Misplaced ingredients contribute nothing.
  3. Any ingredient whose potency has dropped to 0 is removed from the cauldron entirely.
  4. The number of turns the cauldron has left to simmer decreases by 1. If it reaches 0, the cauldron's status becomes BREWED, and it can no longer be simmered.

A cauldron with no ingredients left can still be SIMMERING. Simmering it further has no effect beyond decreasing its turns-remaining count, until that count reaches 0 and the cauldron becomes BREWED.

Print a message to confirm that the command was successful:

  • If the cauldron has just finished brewing, print:
    Cauldron [cauldron_number] has finished brewing!\n.
  • Otherwise, print:
    Cauldron [cauldron_number] simmered, [turns_remaining] turns remaining!\n.

Continuing from the lit cauldron above, after one s 1 every ingredient has lost 3 potency. The FLOWER (in the TOP) and the MUSHROOM (in the BOTTOM) are correctly placed, so each adds 6 to the brew_potency, while the misplaced CRYSTAL adds nothing. The cauldron now has 4 turns remaining:

Simmering cauldron after one simmer turn

After three more s 1 commands, each working the same way, the cauldron has 1 turn remaining, and the FLOWER has only 3 potency left:

Simmering cauldron before its final simmer turn

The final s 1 follows the same steps in order:

  1. Every ingredient loses 3 potency, so the FLOWER drops to 0.
  2. Placement is still based on the positions at the start of the turn, so the FLOWER and the MUSHROOM each add 6 to the brew_potency, and the misplaced CRYSTAL adds nothing.
  3. Only now is the FLOWER removed. This moves the CRYSTAL into the TOP, but that would only matter on a later turn, since this turn's brew_potency has already been calculated.
  4. The cauldron has 0 turns remaining, so its status becomes BREWED:
Brewed cauldron after its final simmer turn, with one ingredient removed

Errors

The following errors should be checked in order:

  • If there is no cauldron at the given [cauldron_number], the following error message should be printed:
    Error: Cauldron [cauldron_number] does not exist.\n.
  • If the cauldron's status is not SIMMERING, the following error message should be printed:
    Error: Cauldron [cauldron_number] is not simmering.\n.

Examples

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL SLOWING
a i 1 MUSHROOM INERT
c 1
l 1 2
c 1
s 1
c 1
s 1
c 1
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 60

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (30)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (30)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: l 1 2
Cauldron 1 lit for 2 turns!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 60

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (30)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (30)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: s 1
Cauldron 1 simmered, 1 turns remaining!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 72

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (27)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (27)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: s 1
Cauldron 1 has finished brewing!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [BREWED]
  Wizard: merlin | Required rank: MASTER | Brew potency: 84

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (24)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (24)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL FLYING
a i 1 ROOT CHILLING
a i 1 FLOWER ENERGETIC
a i 1 MUSHROOM INERT
c 1
l 1 2
s 1
c 1
s 1
c 1
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL FLYING
Ingredient: CRYSTAL FLYING added to cauldron 1!
Enter command: a i 1 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 1!
Enter command: a i 1 FLOWER ENERGETIC
Ingredient: FLOWER ENERGETIC added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 90

  ------------------ TOP ------------------
   1. CRYSTAL ::::: FLYING (30)
   2. ROOT ::::: CHILLING (15)   < misplaced
  ----------------- BOTTOM ----------------
   3. FLOWER ::::: ENERGETIC (15)   < misplaced
   4. MUSHROOM ::::: INERT (30)
  -----------------------------------------

  2 of 4 ingredients are misplaced.

Enter command: l 1 2
Cauldron 1 lit for 2 turns!
Enter command: s 1
Cauldron 1 simmered, 1 turns remaining!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 102

  ------------------ TOP ------------------
   1. CRYSTAL ::::: FLYING (27)
   2. ROOT ::::: CHILLING (12)   < misplaced
  ----------------- BOTTOM ----------------
   3. FLOWER ::::: ENERGETIC (12)   < misplaced
   4. MUSHROOM ::::: INERT (27)
  -----------------------------------------

  2 of 4 ingredients are misplaced.

Enter command: s 1
Cauldron 1 has finished brewing!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [BREWED]
  Wizard: merlin | Required rank: MASTER | Brew potency: 114

  ------------------ TOP ------------------
   1. CRYSTAL ::::: FLYING (24)
   2. ROOT ::::: CHILLING (9)   < misplaced
  ----------------- BOTTOM ----------------
   3. FLOWER ::::: ENERGETIC (9)   < misplaced
   4. MUSHROOM ::::: INERT (24)
  -----------------------------------------

  2 of 4 ingredients are misplaced.

Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL SLOWING
a i 1 ROOT CHILLING
a i 1 MUSHROOM INERT
c 1
l 1 6
s 1
s 1
s 1
s 1
c 1
s 1
c 1
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: a i 1 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 75

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (30)
  ----------------- BOTTOM ----------------
   2. ROOT ::::: CHILLING (15)
   3. MUSHROOM ::::: INERT (30)
  -----------------------------------------

  0 of 3 ingredients are misplaced.

Enter command: l 1 6
Cauldron 1 lit for 6 turns!
Enter command: s 1
Cauldron 1 simmered, 5 turns remaining!
Enter command: s 1
Cauldron 1 simmered, 4 turns remaining!
Enter command: s 1
Cauldron 1 simmered, 3 turns remaining!
Enter command: s 1
Cauldron 1 simmered, 2 turns remaining!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 147

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (18)
  ----------------- BOTTOM ----------------
   2. ROOT ::::: CHILLING (3)
   3. MUSHROOM ::::: INERT (18)
  -----------------------------------------

  0 of 3 ingredients are misplaced.

Enter command: s 1
Cauldron 1 simmered, 1 turns remaining!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 165

  ------------------ TOP ------------------
   1. CRYSTAL ::::: SLOWING (15)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (15)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
l 1 3
a c merlin MASTER
l 1 3
a i 1 CRYSTAL SLOWING
l 1 0
l 1 11
l 1 -1
l 9 3
l 1 2
l 1 2
s 1
s 1
l 1 2
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: l 1 3
Error: Cauldron 1 does not exist.
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: l 1 3
Error: Cauldron 1 is empty.
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: l 1 0
Error: Brew turns must be between 1 and 10.
Enter command: l 1 11
Error: Brew turns must be between 1 and 10.
Enter command: l 1 -1
Error: Brew turns must be between 1 and 10.
Enter command: l 9 3
Error: Cauldron 9 does not exist.
Enter command: l 1 2
Cauldron 1 lit for 2 turns!
Enter command: l 1 2
Error: Cauldron 1 is not ready to be lit.
Enter command: s 1
Cauldron 1 simmered, 1 turns remaining!
Enter command: s 1
Cauldron 1 has finished brewing!
Enter command: l 1 2
Error: Cauldron 1 is not ready to be lit.
Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL SLOWING
l 1 3
a i 1 MUSHROOM INERT
i 1 1 ROOT CHILLING
o 1
b 1 too_soon
r c 1
r w merlin
c 1
s 1
s 1
s 1
o 1
b 1 finally
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: l 1 3
Cauldron 1 lit for 3 turns!
Enter command: a i 1 MUSHROOM INERT
Error: Ingredients can only be added to a cauldron before brewing.
Enter command: i 1 1 ROOT CHILLING
Error: Ingredients can only be added to a cauldron before brewing.
Enter command: o 1
Error: Cauldron 1 is still simmering.
Enter command: b 1 too_soon
Error: Cauldron 1 is still simmering.
Enter command: r c 1
Error: Cauldron 1 is still simmering.
Enter command: r w merlin
Error: merlin has a cauldron currently simmering.
Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 30

  ------------------ TOP ------------------
  ----------------- BOTTOM ----------------
   1. CRYSTAL ::::: SLOWING (30)   < misplaced
  -----------------------------------------

  1 of 1 ingredients are misplaced.

Enter command: s 1
Cauldron 1 simmered, 2 turns remaining!
Enter command: s 1
Cauldron 1 simmered, 1 turns remaining!
Enter command: s 1
Cauldron 1 has finished brewing!
Enter command: o 1
Cauldron 1 reordered!
Enter command: b 1 finally
Potion: 'finally' bottled by merlin!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  merlin - MASTER
    finally [Potency: 30]
      Ingredients: CRYSTAL SLOWING


Cauldrons:
  1. |merlin| [READY]
  Required rank: MASTER
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: q

Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • A cauldron can be lit for a maximum of 10 turns at a time.
  • If every ingredient in a cauldron decays away to nothing, the cauldron can continue simmering (and finishing brewing) with an empty list of ingredients.

Testing and Submission

Remember to do your own testing! Are you finished with this stage? If so, you should make sure to do the following:
  • Run 1511 style and clean up any issues a human may have reading your code. Don't forget -- 20% of your mark in the assignment is based on style and readability!
  • Autotest for this stage of the assignment by running the autotest-stage command as shown below.
  • Remember -- give early and give often. Only your last submission counts, but why not be safe and submit right now?
1511 style cs_alchemy.c
1511 style cs_alchemy.h
1511 style main.c
1511 autotest-stage 03 cs_alchemy
give cs1511 ass2_cs_alchemy cs_alchemy.c cs_alchemy.h main.c

Stage 4

This stage is for students who want to challenge themselves and solve more complicated programming problems. This milestone has been divided into three substages:

  • Stage 4.1 - Peek at a Brew.
  • Stage 4.2 - Annihilating Ingredients.
  • Stage 4.3 - Duelling Wizards.

Stage 4.1 - Peek at a Brew

Brewing potions can be very complicated. Ingredients can shift around, disappear, or do even more mysterious things (spooky). This is why, in this stage, you will implement a command that lets a wizard peek ahead at how their brew will progress.

Command

The Peek Cauldron command is called as follows:

p [cauldron_number] [turns]

For example, the command p 1 3 will peek at what cauldron 1 would look like after 3 more turns of simmering.

Description

When the Peek Cauldron command is entered, your program should simulate [turns] more turns of simmering (using the same rules as the Simmer Cauldron command from Stage 3.4) without actually changing the cauldron in any way.

Print out:

  1. A header naming the cauldron and the number of turns to simulate.
  2. The cauldron's current brew_potency, and what its brew_potency would become after the simulated turns.
  3. The cauldron's current list of ingredients, under a Now: heading.
  4. What the cauldron's list of ingredients would look like after the simulated turns, under an After [turns] turns: heading. Ingredients that would decay away entirely should not appear in this list.

To see the exact format expected, see the examples below.

// The format strings used by the Peek Cauldron command, in the order they print.

printf("=-=-= Peek: Cauldron %d in %d turns =-=-=\n", cauldron_number, turns);
printf("Brew potency: %d -> %d\n\n", brew_potency, peeked_brew_potency);

printf("Now:\n");
printf("\nAfter %d turns:\n", turns);

printf("  %2d. %s ::::: %s (%d)\n", depth, type, effect, potency);
printf("  No ingredients\n");

printf("=-=-=\n\n");

Errors

The following errors should be checked in order:

  • If there is no cauldron at the given [cauldron_number], the following error message should be printed:
    Error: Cauldron [cauldron_number] does not exist.\n.
  • If the cauldron's status is not SIMMERING, the following error message should be printed:
    Error: Cauldron [cauldron_number] is not simmering.\n.
  • If [turns] is less than 1, or greater than the number of turns the cauldron has left to simmer, the following error message should be printed:
    Error: Peek turns must be between 1 and [turns_remaining].\n.

Examples

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL FLYING
a i 1 MUSHROOM INERT
l 1 3
p 1 1
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL FLYING
Ingredient: CRYSTAL FLYING added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: l 1 3
Cauldron 1 lit for 3 turns!
Enter command: p 1 1
=-=-= Peek: Cauldron 1 in 1 turns =-=-=
Brew potency: 60 -> 72

Now:
   1. CRYSTAL ::::: FLYING (30)
   2. MUSHROOM ::::: INERT (30)

After 1 turns:
   1. CRYSTAL ::::: FLYING (27)
   2. MUSHROOM ::::: INERT (27)
=-=-=

Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL FLYING
a i 1 FLOWER ENERGETIC
a i 1 ROOT CHILLING
a i 1 MUSHROOM INERT
l 1 4
p 1 3
s 1
s 1
s 1
c 1
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL FLYING
Ingredient: CRYSTAL FLYING added to cauldron 1!
Enter command: a i 1 FLOWER ENERGETIC
Ingredient: FLOWER ENERGETIC added to cauldron 1!
Enter command: a i 1 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: l 1 4
Cauldron 1 lit for 4 turns!
Enter command: p 1 3
=-=-= Peek: Cauldron 1 in 3 turns =-=-=
Brew potency: 90 -> 162

Now:
   1. CRYSTAL ::::: FLYING (30)
   2. FLOWER ::::: ENERGETIC (15)
   3. ROOT ::::: CHILLING (15)
   4. MUSHROOM ::::: INERT (30)

After 3 turns:
   1. CRYSTAL ::::: FLYING (21)
   2. FLOWER ::::: ENERGETIC (6)
   3. ROOT ::::: CHILLING (6)
   4. MUSHROOM ::::: INERT (21)
=-=-=

Enter command: s 1
Cauldron 1 simmered, 3 turns remaining!
Enter command: s 1
Cauldron 1 simmered, 2 turns remaining!
Enter command: s 1
Cauldron 1 simmered, 1 turns remaining!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 162

  ------------------ TOP ------------------
   1. CRYSTAL ::::: FLYING (21)
   2. FLOWER ::::: ENERGETIC (6)
  ----------------- BOTTOM ----------------
   3. ROOT ::::: CHILLING (6)
   4. MUSHROOM ::::: INERT (21)
  -----------------------------------------

  0 of 4 ingredients are misplaced.

Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL FLYING
a i 1 MUSHROOM INERT
l 1 5
c 1
p 1 5
p 1 5
p 1 2
c 1
s 1
c 1
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL FLYING
Ingredient: CRYSTAL FLYING added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: l 1 5
Cauldron 1 lit for 5 turns!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 60

  ------------------ TOP ------------------
   1. CRYSTAL ::::: FLYING (30)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (30)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: p 1 5
=-=-= Peek: Cauldron 1 in 5 turns =-=-=
Brew potency: 60 -> 120

Now:
   1. CRYSTAL ::::: FLYING (30)
   2. MUSHROOM ::::: INERT (30)

After 5 turns:
   1. CRYSTAL ::::: FLYING (15)
   2. MUSHROOM ::::: INERT (15)
=-=-=

Enter command: p 1 5
=-=-= Peek: Cauldron 1 in 5 turns =-=-=
Brew potency: 60 -> 120

Now:
   1. CRYSTAL ::::: FLYING (30)
   2. MUSHROOM ::::: INERT (30)

After 5 turns:
   1. CRYSTAL ::::: FLYING (15)
   2. MUSHROOM ::::: INERT (15)
=-=-=

Enter command: p 1 2
=-=-= Peek: Cauldron 1 in 2 turns =-=-=
Brew potency: 60 -> 84

Now:
   1. CRYSTAL ::::: FLYING (30)
   2. MUSHROOM ::::: INERT (30)

After 2 turns:
   1. CRYSTAL ::::: FLYING (24)
   2. MUSHROOM ::::: INERT (24)
=-=-=

Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 60

  ------------------ TOP ------------------
   1. CRYSTAL ::::: FLYING (30)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (30)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: s 1
Cauldron 1 simmered, 4 turns remaining!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 72

  ------------------ TOP ------------------
   1. CRYSTAL ::::: FLYING (27)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (27)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL FLYING
a i 1 ROOT CHILLING
a i 1 MUSHROOM INERT
l 1 6
p 1 4
p 1 5
p 1 6
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL FLYING
Ingredient: CRYSTAL FLYING added to cauldron 1!
Enter command: a i 1 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: l 1 6
Cauldron 1 lit for 6 turns!
Enter command: p 1 4
=-=-= Peek: Cauldron 1 in 4 turns =-=-=
Brew potency: 75 -> 147

Now:
   1. CRYSTAL ::::: FLYING (30)
   2. ROOT ::::: CHILLING (15)
   3. MUSHROOM ::::: INERT (30)

After 4 turns:
   1. CRYSTAL ::::: FLYING (18)
   2. ROOT ::::: CHILLING (3)
   3. MUSHROOM ::::: INERT (18)
=-=-=

Enter command: p 1 5
=-=-= Peek: Cauldron 1 in 5 turns =-=-=
Brew potency: 75 -> 165

Now:
   1. CRYSTAL ::::: FLYING (30)
   2. ROOT ::::: CHILLING (15)
   3. MUSHROOM ::::: INERT (30)

After 5 turns:
   1. CRYSTAL ::::: FLYING (15)
   2. MUSHROOM ::::: INERT (15)
=-=-=

Enter command: p 1 6
=-=-= Peek: Cauldron 1 in 6 turns =-=-=
Brew potency: 75 -> 177

Now:
   1. CRYSTAL ::::: FLYING (30)
   2. ROOT ::::: CHILLING (15)
   3. MUSHROOM ::::: INERT (30)

After 6 turns:
   1. CRYSTAL ::::: FLYING (12)
   2. MUSHROOM ::::: INERT (12)
=-=-=

Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
p 1 1
a c merlin MASTER
a i 1 CRYSTAL FLYING
p 1 1
l 1 3
p 1 0
p 1 4
p 1 -1
p 9 1
p 1 3
s 1
s 1
s 1
p 1 1
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: p 1 1
Error: Cauldron 1 does not exist.
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL FLYING
Ingredient: CRYSTAL FLYING added to cauldron 1!
Enter command: p 1 1
Error: Cauldron 1 is not simmering.
Enter command: l 1 3
Cauldron 1 lit for 3 turns!
Enter command: p 1 0
Error: Peek turns must be between 1 and 3.
Enter command: p 1 4
Error: Peek turns must be between 1 and 3.
Enter command: p 1 -1
Error: Peek turns must be between 1 and 3.
Enter command: p 9 1
Error: Cauldron 9 does not exist.
Enter command: p 1 3
=-=-= Peek: Cauldron 1 in 3 turns =-=-=
Brew potency: 30 -> 30

Now:
   1. CRYSTAL ::::: FLYING (30)

After 3 turns:
   1. CRYSTAL ::::: FLYING (21)
=-=-=

Enter command: s 1
Cauldron 1 simmered, 2 turns remaining!
Enter command: s 1
Cauldron 1 simmered, 1 turns remaining!
Enter command: s 1
Cauldron 1 has finished brewing!
Enter command: p 1 1
Error: Cauldron 1 is not simmering.
Enter command: q

Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • Peeking at a cauldron never changes its status, its brew_potency, its list of ingredients, or the number of turns it has left to simmer. The exact same cauldron can be peeked at multiple times in a row with identical results.
  • Peeking still applies the Simmer Cauldron rules from Stage 3.4 exactly, including ingredients decaying away and the TOP/BOTTOM boundary shifting as ingredients are lost.

Stage 4.2 - Annihilating Ingredients

Potion ingredients have many different effects, and as a result, they cancel each other out when they get too close! In this stage, you will implement logic so that ingredients with opposing effects destroy each other while a cauldron simmers.

Two ingredient effects oppose each other if they are one of the following pairs (in either order):

  • ENERGETIC and SLOWING
  • CHILLING and SCORCHING
  • FLYING and SINKING

INERT does not oppose any effect.

Command

This stage does not introduce a new command. Instead, it extends the Simmer Cauldron command from Stage 3.4:

s [cauldron_number]

Since Peek Cauldron (from Stage 4.1) simulates the Simmer Cauldron command, its simulated turns should also account for annihilation.

Description

After a cauldron has lost potency, gained brew potency, and had any fully-decayed ingredients removed for the turn (as described in Stage 3.4), your program should then repeatedly search the cauldron's list of ingredients from head to tail, looking for two adjacent ingredients whose effects oppose each other.

When such a pair is found:

  • If the two ingredients have equal potency, both are destroyed completely and removed from the cauldron.
  • Otherwise:
    1. The ingredient with the higher potency survives; the other is destroyed.
    2. The surviving ingredient's potency is reduced by the destroyed ingredient's potency.
    3. The surviving ingredient's effect changes to INERT (its type is unchanged).

Annihilating ingredients may make two other opposing ingredients adjacent to each other, so after any single annihilation, searching should restart from the head of the list. This process should keep repeating until a full search finds no adjacent opposing pairs.

Annihilation only ever happens between adjacent ingredients. Two ingredients with opposing effects will not annihilate if there is another ingredient sitting between them in the cauldron's list.

Since an ingredient's effect becomes INERT after surviving an annihilation, it can never annihilate again in a later turn, even if another ingredient with an opposing effect becomes adjacent to it.

The full order of a single Simmer Cauldron turn, including the new annihilation step, is shown below. Each s command runs through this order exactly once:

Flowchart of the steps in one simmer turn

For example, consider a cauldron that has been given four ingredients and then lit with l 1 3. The first and last ingredients have opposing effects (FLYING and SINKING), but since they are not adjacent, nothing happens yet:

Simmering cauldron with four ingredients before simmering

When s 1 is entered, every ingredient first decays by 3 (to 27, 12, 12 and 12), and the two correctly placed middle ingredients each add 6 to the brew_potency, bringing it to 87. Then the search for annihilations begins. The FLOWER ENERGETIC and ROOT SLOWING are adjacent and opposing, and both have 12 potency, so both are destroyed. This makes the MUSHROOM FLYING and FLOWER SINKING adjacent, so the search restarts from the head:

Cauldron after the first annihilation, with two ingredients left

The MUSHROOM FLYING (27) and FLOWER SINKING (12) now annihilate. Their potencies are not equal, so the FLOWER is destroyed, and the MUSHROOM survives with 27 - 12 = 15 potency and becomes INERT. A full search now finds no more opposing pairs, so annihilation is finished for this turn. Note that annihilation never changes the brew_potency, which is still 87:

Cauldron after the second annihilation, with one inert ingredient left

Examples

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL ENERGETIC
a i 1 CRYSTAL SLOWING
a i 1 MUSHROOM FLYING
c 1
l 1 3
s 1
c 1
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL ENERGETIC
Ingredient: CRYSTAL ENERGETIC added to cauldron 1!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: a i 1 MUSHROOM FLYING
Ingredient: MUSHROOM FLYING added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 90

  ------------------ TOP ------------------
   1. CRYSTAL ::::: ENERGETIC (30)
  ----------------- BOTTOM ----------------
   2. CRYSTAL ::::: SLOWING (30)   < misplaced
   3. MUSHROOM ::::: FLYING (30)
  -----------------------------------------

  1 of 3 ingredients are misplaced.

Enter command: l 1 3
Cauldron 1 lit for 3 turns!
Enter command: s 1
Cauldron 1 simmered, 2 turns remaining!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 102

  ------------------ TOP ------------------
  ----------------- BOTTOM ----------------
   1. MUSHROOM ::::: FLYING (27)
  -----------------------------------------

  0 of 1 ingredients are misplaced.

Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL ENERGETIC
a i 1 ROOT SLOWING
c 1
l 1 4
s 1
c 1
s 1
c 1
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL ENERGETIC
Ingredient: CRYSTAL ENERGETIC added to cauldron 1!
Enter command: a i 1 ROOT SLOWING
Ingredient: ROOT SLOWING added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 45

  ------------------ TOP ------------------
   1. CRYSTAL ::::: ENERGETIC (30)
  ----------------- BOTTOM ----------------
   2. ROOT ::::: SLOWING (15)
  -----------------------------------------

  0 of 2 ingredients are misplaced.

Enter command: l 1 4
Cauldron 1 lit for 4 turns!
Enter command: s 1
Cauldron 1 simmered, 3 turns remaining!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 57

  ------------------ TOP ------------------
  ----------------- BOTTOM ----------------
   1. CRYSTAL ::::: INERT (15)   < misplaced
  -----------------------------------------

  1 of 1 ingredients are misplaced.

Enter command: s 1
Cauldron 1 simmered, 2 turns remaining!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 57

  ------------------ TOP ------------------
  ----------------- BOTTOM ----------------
   1. CRYSTAL ::::: INERT (12)   < misplaced
  -----------------------------------------

  1 of 1 ingredients are misplaced.

Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin MASTER
a c merlin MASTER
a i 1 CRYSTAL ENERGETIC
a i 1 MUSHROOM INERT
a i 1 CRYSTAL SLOWING
c 1
l 1 3
s 1
c 1
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin MASTER
Wizard: 'merlin' added!
Enter command: a c merlin MASTER
Cauldron: assigned to 'merlin'!
Enter command: a i 1 CRYSTAL ENERGETIC
Ingredient: CRYSTAL ENERGETIC added to cauldron 1!
Enter command: a i 1 MUSHROOM INERT
Ingredient: MUSHROOM INERT added to cauldron 1!
Enter command: a i 1 CRYSTAL SLOWING
Ingredient: CRYSTAL SLOWING added to cauldron 1!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [READY]
  Wizard: merlin | Required rank: MASTER | Brew potency: 90

  ------------------ TOP ------------------
   1. CRYSTAL ::::: ENERGETIC (30)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (30)
   3. CRYSTAL ::::: SLOWING (30)   < misplaced
  -----------------------------------------

  1 of 3 ingredients are misplaced.

Enter command: l 1 3
Cauldron 1 lit for 3 turns!
Enter command: s 1
Cauldron 1 simmered, 2 turns remaining!
Enter command: c 1
=-=-= Cauldron 1 =-=-= [SIMMERING]
  Wizard: merlin | Required rank: MASTER | Brew potency: 102

  ------------------ TOP ------------------
   1. CRYSTAL ::::: ENERGETIC (27)
  ----------------- BOTTOM ----------------
   2. MUSHROOM ::::: INERT (27)
   3. CRYSTAL ::::: SLOWING (27)   < misplaced
  -----------------------------------------

  1 of 3 ingredients are misplaced.

Enter command: q

Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • Annihilation happens after decayed ingredients are removed for the turn, and before the cauldron's turns-remaining count is decreased.

Stage 4.3 - Duelling Wizards

There can only be one ultimate wizard. What determines this? A duel of course! In this stage, you will implement a command that allows two wizards to duel using their potions.

Command

The Duel Wizards command is called as follows:

d [wizard_a] [wizard_b]

For example, the command d Merlin Morgana will start a duel between the wizards Merlin and Morgana.

Description

When the Duel Wizards command is entered, the two given wizards duel using their potions, one pair at a time, starting from the head of each of their lists of potions. The number of individual potion duels that occur is equal to the number of potions belonging to whichever wizard has fewer potions. This means that any of the other wizard's remaining potions are not used and are unaffected by the duel.

For each pair of potions, they fight as follows:

  1. While both potions still have a positive brew_potency, and at least one of them still has ingredients remaining:
    • If both potions still have ingredients, compare the ingredient at the head of each potion's list:
      • If their effects oppose each other (see Stage 4.2), or they have equal potency, both ingredients are destroyed.
      • Otherwise, the ingredient with the higher potency has its potency reduced by the weaker ingredient's potency and survives, with the weaker ingredient is destroyed.
    • If one potion has run out of ingredients, the other potion deals broth damage: its head ingredient is destroyed, and that ingredient's potency is subtracted directly from the brew_potency of the potion with no ingredients.
  2. Whichever potion has the higher brew_potency once the fight ends wins this pairing. If their brew_potency is equal, this pairing is a draw.

For each pair, print Potion [i]: [potion_a] vs [potion_b]\n, where [i] is the number of this pairing, counting from 1, and [potion_a] and [potion_b] are the names of the two potions dueling in it. Then print one of:

  •   [name] [Potency: [potency]] wins!\n\n, if one potion won, where [name] and [potency] are the winning potion's name and brew_potency. For example:
      elixir_of_strength [Potency: 30] wins!
  •   Draw! Both potions were destroyed.\n\n, if the pairing was a draw.

If a potion wins its pairing, the losing potion is destroyed, and the winning potion (along with any ingredients it has left) survives. If a pairing is a draw, both potions are destroyed.

Once every pairing has been fought, print [wizard_a] [score_a] - [score_b] [wizard_b]\n, where [wizard_a] and [wizard_b] are the names of the two wizards, and [score_a] and [score_b] are the number of pairings each wizard won (draws are not counted towards either wizard's score). Then:

  • If one wizard won more pairings than the other, print [wizard_name] wins the duel!\n, and promote the winning wizard to the next rank up (NOVICE to APPRENTICE, or APPRENTICE to MASTER), printing [wizard_name] was promoted to [new_rank]!\n, where [new_rank] is the rank they were promoted to. If the winning wizard is already MASTER, no further promotion occurs, and no message should be printed for it.
  • Otherwise (including if there were no pairings at all), print The duel was a draw!\n.

To see the exact format expected, see the examples below.

// The format strings used by the Duel Wizards command, in the order they print.

printf("=-=-= Duel: %s vs %s =-=-=\n\n", wizard_a_name, wizard_b_name);

printf("Potion %d: %s vs %s\n", pairing, potion_a_name, potion_b_name);
printf("  %s [Potency: %d] wins!\n\n", winning_potion_name, brew_potency);
printf("  Draw! Both potions were destroyed.\n\n");

printf("%s %d - %d %s\n", wizard_a_name, score_a, score_b, wizard_b_name);

printf("%s wins the duel!\n", winning_wizard_name);
printf("The duel was a draw!\n");
printf("%s was promoted to %s!\n", winning_wizard_name, new_rank);

printf("=-=-=\n\n");

For example, consider two wizards who each have one potion. Since each wizard has exactly one potion, d Merlin Morgana fights a single pairing: Ice_Draught vs Poison_Elixir:

Two wizards, each with one potion, before a duel

In the first clash, the head ingredients are CRYSTAL SCORCHING and CRYSTAL CHILLING. Their effects oppose each other, so both are destroyed. Neither potion's brew_potency changes:

Both potions after their opposing head ingredients destroy each other

In the second clash, the head ingredients are MUSHROOM INERT (30) and FLOWER INERT (15). They do not oppose each other and their potencies are not equal, so the weaker FLOWER is destroyed, and the MUSHROOM survives with 30 - 15 = 15 potency. Again, neither potion's brew_potency changes:

Both potions after an unequal clash, with one potion out of ingredients

Poison_Elixir has now run out of ingredients, so Ice_Draught deals broth damage: its head ingredient, MUSHROOM INERT (15), is destroyed, and its potency is subtracted from the brew_potency of Poison_Elixir, which drops from 45 to 30:

Both potions after the first round of broth damage

Ice_Draught deals broth damage again: its last ingredient, FLOWER INERT (15), is destroyed, and Poison_Elixir drops from 30 to 15. Both potions have now run out of ingredients, so the fight ends. Ice_Draught has the higher brew_potency (75 > 15), so it wins this pairing:

Both potions out of ingredients at the end of the fight

Finally, the losing potion Poison_Elixir is destroyed, while the winning potion Ice_Draught survives, even though it has no ingredients left. Merlin won more pairings (1 - 0), so Merlin wins the duel and is promoted from NOVICE to APPRENTICE:

Two wizards after the duel, with the winner promoted and the losing potion destroyed

Errors

The following errors should be checked in order:

  • If there is no wizard with the given name [wizard_a], the following error message should be printed:
    Error: No wizard with name [wizard_a].\n.
  • If there is no wizard with the given name [wizard_b], the following error message should be printed:
    Error: No wizard with name [wizard_b].\n.
  • If [wizard_a] and [wizard_b] are the same wizard, the following error message should be printed:
    Error: A wizard cannot duel themselves.\n.
  • If either wizard has no potions, the following error message should be printed:
    Error: Both wizards need a potion to duel with.\n.

Examples

Input:

CS_Alchemy
a w merlin NOVICE
a w morgana NOVICE
a c merlin NOVICE
a c morgana NOVICE
a i 1 MUSHROOM ENERGETIC
b 1 strength_elixir
a i 2 ROOT CHILLING
b 2 frost_phial
*
d merlin morgana
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin NOVICE
Wizard: 'merlin' added!
Enter command: a w morgana NOVICE
Wizard: 'morgana' added!
Enter command: a c merlin NOVICE
Cauldron: assigned to 'merlin'!
Enter command: a c morgana NOVICE
Cauldron: assigned to 'morgana'!
Enter command: a i 1 MUSHROOM ENERGETIC
Ingredient: MUSHROOM ENERGETIC added to cauldron 1!
Enter command: b 1 strength_elixir
Potion: 'strength_elixir' bottled by merlin!
Enter command: a i 2 ROOT CHILLING
Ingredient: ROOT CHILLING added to cauldron 2!
Enter command: b 2 frost_phial
Potion: 'frost_phial' bottled by morgana!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - NOVICE
    frost_phial [Potency: 15]
      Ingredients: ROOT CHILLING

  merlin - NOVICE
    strength_elixir [Potency: 30]
      Ingredients: MUSHROOM ENERGETIC


Cauldrons:
  1. |merlin| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================

  2. |morgana| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: d merlin morgana
=-=-= Duel: merlin vs morgana =-=-=

Potion 1: strength_elixir vs frost_phial
  strength_elixir [Potency: 30] wins!

merlin 1 - 0 morgana
merlin wins the duel!
merlin was promoted to APPRENTICE!
=-=-=

Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - NOVICE
    No potions at the moment!

  merlin - APPRENTICE
    strength_elixir [Potency: 30]
      Ingredients: 


Cauldrons:
  1. |merlin| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================

  2. |morgana| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin NOVICE
a w morgana NOVICE
a c merlin NOVICE
a c morgana NOVICE
a i 1 MUSHROOM ENERGETIC
b 1 storm_elixir
a i 1 CRYSTAL CHILLING
a i 1 ROOT FLYING
b 1 tempest_draught
a i 2 ROOT SLOWING
b 2 sludge_tonic
a i 2 FLOWER SCORCHING
a i 2 MUSHROOM SINKING
b 2 ember_phial
*
d merlin morgana
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin NOVICE
Wizard: 'merlin' added!
Enter command: a w morgana NOVICE
Wizard: 'morgana' added!
Enter command: a c merlin NOVICE
Cauldron: assigned to 'merlin'!
Enter command: a c morgana NOVICE
Cauldron: assigned to 'morgana'!
Enter command: a i 1 MUSHROOM ENERGETIC
Ingredient: MUSHROOM ENERGETIC added to cauldron 1!
Enter command: b 1 storm_elixir
Potion: 'storm_elixir' bottled by merlin!
Enter command: a i 1 CRYSTAL CHILLING
Ingredient: CRYSTAL CHILLING added to cauldron 1!
Enter command: a i 1 ROOT FLYING
Ingredient: ROOT FLYING added to cauldron 1!
Enter command: b 1 tempest_draught
Potion: 'tempest_draught' bottled by merlin!
Enter command: a i 2 ROOT SLOWING
Ingredient: ROOT SLOWING added to cauldron 2!
Enter command: b 2 sludge_tonic
Potion: 'sludge_tonic' bottled by morgana!
Enter command: a i 2 FLOWER SCORCHING
Ingredient: FLOWER SCORCHING added to cauldron 2!
Enter command: a i 2 MUSHROOM SINKING
Ingredient: MUSHROOM SINKING added to cauldron 2!
Enter command: b 2 ember_phial
Potion: 'ember_phial' bottled by morgana!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - NOVICE
    sludge_tonic [Potency: 15]
      Ingredients: ROOT SLOWING

    ember_phial [Potency: 45]
      Ingredients: FLOWER SCORCHING, MUSHROOM SINKING

  merlin - NOVICE
    storm_elixir [Potency: 30]
      Ingredients: MUSHROOM ENERGETIC

    tempest_draught [Potency: 45]
      Ingredients: CRYSTAL CHILLING, ROOT FLYING


Cauldrons:
  1. |merlin| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================

  2. |morgana| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: d merlin morgana
=-=-= Duel: merlin vs morgana =-=-=

Potion 1: storm_elixir vs sludge_tonic
  storm_elixir [Potency: 30] wins!

Potion 2: tempest_draught vs ember_phial
  Draw! Both potions were destroyed.

merlin 1 - 0 morgana
merlin wins the duel!
merlin was promoted to APPRENTICE!
=-=-=

Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - NOVICE
    No potions at the moment!

  merlin - APPRENTICE
    storm_elixir [Potency: 30]
      Ingredients: 


Cauldrons:
  1. |merlin| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================

  2. |morgana| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin NOVICE
a w morgana NOVICE
a c merlin NOVICE
a c morgana NOVICE
a i 1 MUSHROOM ENERGETIC
b 1 vigour_elixir
a i 2 CRYSTAL FLYING
b 2 levitation_phial
*
d merlin morgana
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin NOVICE
Wizard: 'merlin' added!
Enter command: a w morgana NOVICE
Wizard: 'morgana' added!
Enter command: a c merlin NOVICE
Cauldron: assigned to 'merlin'!
Enter command: a c morgana NOVICE
Cauldron: assigned to 'morgana'!
Enter command: a i 1 MUSHROOM ENERGETIC
Ingredient: MUSHROOM ENERGETIC added to cauldron 1!
Enter command: b 1 vigour_elixir
Potion: 'vigour_elixir' bottled by merlin!
Enter command: a i 2 CRYSTAL FLYING
Ingredient: CRYSTAL FLYING added to cauldron 2!
Enter command: b 2 levitation_phial
Potion: 'levitation_phial' bottled by morgana!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - NOVICE
    levitation_phial [Potency: 30]
      Ingredients: CRYSTAL FLYING

  merlin - NOVICE
    vigour_elixir [Potency: 30]
      Ingredients: MUSHROOM ENERGETIC


Cauldrons:
  1. |merlin| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================

  2. |morgana| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: d merlin morgana
=-=-= Duel: merlin vs morgana =-=-=

Potion 1: vigour_elixir vs levitation_phial
  Draw! Both potions were destroyed.

merlin 0 - 0 morgana
The duel was a draw!
=-=-=

Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - NOVICE
    No potions at the moment!

  merlin - NOVICE
    No potions at the moment!


Cauldrons:
  1. |merlin| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================

  2. |morgana| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: q

Thank you for brewing potions!

Input:

CS_Alchemy
a w merlin NOVICE
a w morgana NOVICE
a c merlin NOVICE
a c morgana NOVICE
a i 1 MUSHROOM ENERGETIC
a i 1 MUSHROOM ENERGETIC
a i 1 MUSHROOM ENERGETIC
a i 1 MUSHROOM ENERGETIC
b 1 titan_brew
a i 2 ROOT INERT
a i 2 ROOT INERT
a i 2 ROOT INERT
a i 2 ROOT INERT
b 2 sludge_phial
*
d merlin morgana
*
q

Input and Output:

dcc main.c cs_alchemy.c -o cs_alchemy --leak-check
./cs_alchemy
                  Welcome to....
                .       o      .       o
      o    .        O       .       O       .    o
       T H E   P O T I O N   A P O T H E C A R Y
     .   o  .   O   .   o   .   O   .   o   .   O
 (o) (O)  (o) (O)  (o)  (O) (o)  (O) (o)  (O) (o) (O)
oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oOoOo(_)oOo(_)oOo(_)oO
~o~^~O~o~^~o~O~^~o~^~O~o~^~o~^~O~o~^~o~O~^~o~^~O~o~^~o

Enter the name of the apothecary: CS_Alchemy
Enter command: a w merlin NOVICE
Wizard: 'merlin' added!
Enter command: a w morgana NOVICE
Wizard: 'morgana' added!
Enter command: a c merlin NOVICE
Cauldron: assigned to 'merlin'!
Enter command: a c morgana NOVICE
Cauldron: assigned to 'morgana'!
Enter command: a i 1 MUSHROOM ENERGETIC
Ingredient: MUSHROOM ENERGETIC added to cauldron 1!
Enter command: a i 1 MUSHROOM ENERGETIC
Ingredient: MUSHROOM ENERGETIC added to cauldron 1!
Enter command: a i 1 MUSHROOM ENERGETIC
Ingredient: MUSHROOM ENERGETIC added to cauldron 1!
Enter command: a i 1 MUSHROOM ENERGETIC
Ingredient: MUSHROOM ENERGETIC added to cauldron 1!
Enter command: b 1 titan_brew
Potion: 'titan_brew' bottled by merlin!
Enter command: a i 2 ROOT INERT
Ingredient: ROOT INERT added to cauldron 2!
Enter command: a i 2 ROOT INERT
Ingredient: ROOT INERT added to cauldron 2!
Enter command: a i 2 ROOT INERT
Ingredient: ROOT INERT added to cauldron 2!
Enter command: a i 2 ROOT INERT
Ingredient: ROOT INERT added to cauldron 2!
Enter command: b 2 sludge_phial
Potion: 'sludge_phial' bottled by morgana!
Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - NOVICE
    sludge_phial [Potency: 60]
      Ingredients: ROOT INERT, ROOT INERT, ROOT INERT, ROOT INERT

  merlin - NOVICE
    titan_brew [Potency: 120]
      Ingredients: MUSHROOM ENERGETIC, MUSHROOM ENERGETIC, MUSHROOM ENERGETIC, MUSHROOM ENERGETIC


Cauldrons:
  1. |merlin| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================

  2. |morgana| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: d merlin morgana
=-=-= Duel: merlin vs morgana =-=-=

Potion 1: titan_brew vs sludge_phial
  titan_brew [Potency: 120] wins!

merlin 1 - 0 morgana
merlin wins the duel!
merlin was promoted to APPRENTICE!
=-=-=

Enter command: *
=-=-=-=-=-=-=-=[Apothecary: CS_Alchemy]=-=-=-=-=-=-=-=
Wizards:
  morgana - NOVICE
    No potions at the moment!

  merlin - APPRENTICE
    titan_brew [Potency: 120]
      Ingredients: 


Cauldrons:
  1. |merlin| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================

  2. |morgana| [READY]
  Required rank: NOVICE
  Brew potency: 0

  ==================================================
    No ingredients yet
  ==================================================


Enter command: q

Thank you for brewing potions!

Assumptions / Restrictions / Clarifications

  • A potion's brew_potency is only ever reduced by taking broth damage (i.e. damage taken once it has run out of ingredients). Ingredient-versus-ingredient clashes never directly change either potion's brew_potency.

Testing and Submission

Remember to do your own testing! Are you finished with this stage? If so, you should make sure to do the following:
  • Run 1511 style and clean up any issues a human may have reading your code. Don't forget -- 20% of your mark in the assignment is based on style and readability!
  • Autotest for this stage of the assignment by running the autotest-stage command as shown below.
  • Remember -- give early and give often. Only your last submission counts, but why not be safe and submit right now?
1511 style cs_alchemy.c
1511 style cs_alchemy.h
1511 style main.c
1511 autotest-stage 04 cs_alchemy
give cs1511 ass2_cs_alchemy cs_alchemy.c cs_alchemy.h main.c

Extension

As an extension, we have set up a starting point to add a texture pack to your program via SplashKit.

Extension activities are NOT worth any marks, nor are there any autotests. They are just for fun!

Getting Started

To get started with SplashKit, complete the SplashKit activities.

Sample Code

First, navigate to your SplashKit directory.

cd splashkit

Create a new directory for your project and cd into it.

mkdir cs_alchemy
cd cs_alchemy

Set up your directory for SplashKit with:

1511 setup-splashkit-directory

Run this cp command to retrieve the sample code.

cp -n /web/cs1511/26T3/activities/cs_alchemy/splashkit_example.c .

This should add the splashkit_example.c sample code to your current directory.

Check that SplashKit Works

Let's check that SplashKit works by running a test file. It should display a white square with a grid inside.

skm clang++ splashkit_example.c -o splashkit_example
./splashkit_example

Have a look inside of splashkit_example.c and note that:

  • At the very top, the the SplashKit library "splashkit.h" is included. If you see an error here, check SplashKit #1 - Getting Started for a solution to set up your VS Code project.
  • In the main() function:
    • open_window("SplashKit Example", 600, 400) creates a 600×400 window for displaying graphics.
    • The while (!window_close_requested(w)) loop keeps running until the user closes the window. Within this loop:
      • process_events() handles input or window-related actions (like closing the window).
      • refresh_screen() updates the window so any graphical changes (like drawing a rectangle) are displayed to the user.

Running Your SplashKit Code

When creating your SplashKit program, give it a distinctive name like splashkit_cs_alchemy.c.

To compile and run your program, use:

skm clang++ splashkit_cs_alchemy.c -o splashkit_cs_alchemy
./splashkit_cs_alchemy

Writing Your SplashKit Program

Now that you've seen how the sample code works, it’s time to create your own SplashKit program.

If you're not sure where to begin, start by researching the SplashKit Library. The goal at first is not to understand and memorise the entire library. Rather, it's better to skim through the pages to build a broad understanding of the capabilities that SplashKit can bring to your creations.

The Graphics page is a good place to start, and the following sections will be useful:

  • Windows for opening, closing, and controlling the size of windows.
  • Color for using different colours.
  • Graphics for drawing shapes, images, and text.
  • Geometry for handling shapes such as rectangles, circles, lines, and points.
  • Input for capturing and handling user input such as keyboard and mouse events.

SplashKit Gallery

Have you built something fun or interesting using SplashKit? Show it off and inspire your classmates!

Share any screenshots or short videos of your running program in the SplashKit Gallery on the Course Forum. Feel free to add a brief description or reflect on how you made it, so we can all learn from your mistakes journey 😅.

Tools

Creating Apothecaries in Separate Files

If you are getting sick of typing your inputs every time you run CS Alchemy, you might want to store your input in a separate file.

1. Create a file for your input.

First, let's create a file to store in the input for an apothecary that you have created. This isn't a .c file, it's just a regular plain text file, the file extension .in works nicely for this!

Let's put it in the same directory as your assignment code.

cd ass2
ls
cs_alchemy.c 
cs_alchemy.h
main.c
cs_alchemy
my_apothecary.in

2. Add your input to the file

Inside of this file, add the input for the apothecary.

Your file could look a bit like this (including the newline at the end):

CS_Alchemy
a w merlin NOVICE
a c merlin NOVICE
*

3. Run the code with your file

Next, instead of just running ./cs_alchemy, lets tell the computer to first read from the file we created.

cat my_apothecary.in - | ./cs_alchemy

This will also work on the reference implementation too!

cat my_apothecary.in - | 1511 cs_alchemy




Assessment

Assignment Conditions

  • Joint work is not permitted on this assignment.

    This is an individual assignment.

    The work you submit must be entirely your own work. Submission of any work even partly written by any other person is not permitted.

    The only exception being if you use small amounts (< 10 lines) of general purpose code (not specific to the assignment) obtained from a site such as Stack Overflow or other publicly available resources. You should attribute the source of this code clearly in an accompanying comment.

    Assignment submissions will be examined, both automatically and manually for work written by others.

    Do not request help from anyone other than the teaching staff of COMP1511.

    Do not post your assignment code to the course forum - the teaching staff can view assignment code you have recently autotested or submitted with give.

    Rationale: this assignment is an individual piece of work. It is designed to develop the skills needed to produce an entire working program. Using code written by or taken from other people will stop you learning these skills.

  • The use of code-synthesis tools, such as GitHub Copilot, is not permitted on this assignment.

    The use of Generative AI to generate code solutions is not permitted on this assignment.

    Rationale: this assignment is intended to develop your understanding of basic concepts. Using synthesis tools will stop you learning these fundamental concepts.

  • Sharing, publishing, distributing your assignment work is not permitted.

    Do not provide or show your assignment work to any other person, other than the teaching staff of COMP1511. For example, do not share your work with friends.

    Do not publish your assignment code via the internet. For example, do not place your assignment in a public GitHub repository.

    Rationale: by publishing or sharing your work you are facilitating other students to use your work, which is not permitted. If they submit your work, you may become involved in an academic integrity investigation.

  • Sharing, publishing, distributing your assignment work after the completion of COMP1511 is not permitted.

    For example, do not place your assignment in a public GitHub repository after COMP1511 is over.

    Rationale: COMP1511 sometimes reuses assignment themes, using similar concepts and content. If students in future terms can find your code and use it, which is not permitted, you may become involved in an academic integrity investigation.

Violation of the above conditions may result in an academic integrity investigation with possible penalties, up to and including a mark of 0 in COMP1511 and exclusion from UNSW.

Relevant scholarship authorities will be informed if students holding scholarships are involved in an incident of plagiarism or other misconduct. If you knowingly provide or show your assignment work to another person for any reason, and work derived from it is submitted - you may be penalised, even if the work was submitted without your knowledge or consent. This may apply even if your work is submitted by a third party unknown to you.

If you have not shared your assignment, you will not be penalised if your work is taken without your consent or knowledge.

For more information, read the UNSW Student Code , or contact the course account. The following penalties apply to your total mark for plagiarism:

0 for the assignment Knowingly providing your work to anyone and it is subsequently submitted (by anyone).
0 for the assignment Submitting any other person's work. This includes joint work.
0 FL for COMP1511 Paying another person to complete work. Submitting another person's work without their consent.

Submission of Work

You should submit intermediate versions of your assignment. Every time you autotest or submit, a copy will be saved as a backup. You can find those backups  here , by logging in, and choosing the yellow button next to ass2_cs_alchemy.

Every time you work on the assignment and make some progress, you should copy your work to your CSE account and submit it using the give  command below.

It is fine if intermediate versions do not compile or otherwise fail submission tests.

Only the final submitted version of your assignment will be marked.

You submit your work like this:

  give cs1511 ass2_cs_alchemy cs_alchemy.c cs_alchemy.h main.c

Assessment Scheme

This assignment will contribute 25% to your final mark.

80% of the marks for this assignment will be based on the performance of the code you write in cs_alchemy.c cs_alchemy.h main.c.

20% of the marks for this assignment will come from manual marking of the readability of the C you have written. The manual marking will involve checking your code for clarity, and readability, which includes the use of functions and efficient use of loops and if statements.

Marks for your performance will be allocated roughly according to the below scheme.

COMP1511

100% for Performance Completely working implementation, which exactly follows the specification (Stage 1, 2, 3 and 4).
85% for Performance Completely working implementation of Stage 1, 2 and 3.
65% for Performance Completely working implementation of Stage 1 and 2.
35% for Performance Completely working implementation of Stage 1.

COMP1911

100% for Performance Completely working implementation, which exactly follows the specification (Stage 1, 2, 3.1, 3.2 and 3.3).
85% for Performance Completely working implementation of Stage 1 and 2.
40% for Performance Completely working implementation of Stage 1.

Marks for your style will be allocated roughly according to the scheme below.

Style Marking Rubric

0 1 2 3 4
Formatting (/5)
Indentation (/2) - Should use a consistent indentation scheme. Multiple instances throughout code of inconsistent/bad indentation Code is mostly correctly indented Code is consistently indented throughout the program
Whitespace (/1) - Should use consistent whitespace (for example, 3 + 3 not 3+ 3) Many whitespace errors No whitespace errors
Vertical Whitespace (/1) - Should use consistent whitespace (for example, vertical whitespace between sections of code) Code has no consideration for use of vertical whitespace Code consistently uses reasonable vertical whitespace
Line Length (/1) - Lines should be max. 80 characters long Many lines over 80 characters No lines over 80 characters
Documentation (/5)
Comments (incl. header comment) (/3) - Comments have been used throughout the code above code sections and functions to explain their purpose. A header comment (with name, zID and a program description) has been included No comments provided throughout code Few comments provided throughout code Comments are provided as needed, but some details or explanations may be missing causing the code to be difficult to follow Comments have been used throughout the code above code sections and functions to explain their purpose. A header comment (with name, zID and a program description) has been included
Function/variable/constant naming (/2) - Functions/variables/constants names all follow naming conventions in style guide and help in understanding the code Functions/variables/constants names do not follow naming conventions in style guide and help in understanding the code Functions/variables/constants names somewhat follow naming conventions in style guide and help in understanding the code Functions/variables/constants names all follow naming conventions in style guide and help in understanding the code
Organisation (/5)
Function Usage (/4) - Code has been decomposed into appropriate functions separating functionalities No functions are present, code is one main function Some code has been moved to functions Some code has been moved to sensible/thought out functions, and/or many functions exceed 50 lines (incl. main function) Most code has been moved to sensible/thought out functions, and/or some functions exceed 50 lines (incl. main function) All code has been meaningfully decomposed into functions of a maximum of 50 lines (incl. The main function)
Function Prototypes (/1) - Function Prototypes have been used to declare functions above main Functions are used but have not been prototyped All functions have a prototype above the main function or no functions are used
Elegance (/5)
Overdeep nesting (/2) - You should not have too many levels of nesting in your code (nesting which is 5 or more levels deep) Many instances of overdeep nesting <= 3 instances of overdeep nesting No instances of overdeep nesting
Code Repetition (/2) - Potential repetition of code has been dealt with via the use of functions or loops Many instances of repeated code sections <= 3 instances of repeated code sections Potential repetition of code has been dealt with via the use of functions or loops
Constant Usage (/1) - Any magic numbers are #defined None of the constants used throughout program are #defined All constants used are #defined and are used consistently in the code
Illegal elements
Illegal elements - Presence of any illegal elements indicated in the style guide CAP MARK AT 16/20

Allowed C Features

This assignment must be implemented exclusively using linked lists for all core data structures and logic. Other than arrays, there are no restrictions on C features in this assignment, except for those outlined in the Style Guide. If you choose to use features beyond what has been taught in COMP1511/1911, be aware that course staff may not be able to assist you.

Due Date

This assignment is due 20 November 2026 18:00:00. For each day after that time, the maximum mark it can achieve will be reduced by 5% (off the ceiling).
  • For instance, at 1 day past the due date, the maximum mark you can get is 95%.
  • For instance, at 3 days past the due date, the maximum mark you can get is 85%.
  • For instance, at 5 days past the due date, the maximum mark you can get is 75%.
No submissions will be accepted after 5 days late, unless you have special provisions in place.

Change Log

Version 1.0
(2026-10-29 09:00)
  • Assignment Released