CMSC 106 Project #7 - Magic Fall 2002


Due date: Tuesday 12/10 before 11:00 p.m.

1 Purpose

In this project you will write a program using structures and structures which contain other structures as members, arrays of structures, and functions with structure parameters, using both call-by-value and call-by-reference.

For this project we are imagining that you are a powerful magician, who casts various ``spells''. Your program will keep track of an inventory of magical ingredients, which will be used up as spells are cast.

Your program begins by reading in an inventory of magical ingredients for spells. Next it will read in your Spell Book, which lists the spells you know and the ingredients that are required for casting each kind of spell. Finally, it will read in a list of spells and attempt to cast them. These spells will only be cast if you have enough of the required ingredients in inventory. Of course the amounts of ingredients in inventory must be reduced as spells are cast.

2 Project description

2.1 Program input

The input file will be divided into three portions: Initial ingredient inventory, Spell Book, and Spells to cast. A description of each of these sections of the input file appears below.

2.1.1 Initial ingredient inventory

The first portion of the input file contains a listing of ingredients that you have on hand. At the bottom you will see ``11111'', which designates the end of the list. Below is the list which appears as the first section of the primary_input file:
42 beads
11 pinches of ashes
6 ounces of camel spit
6 beads
4 cloves of garlic
6 candles
10 grams of incense
17 sheets of parchment
2 frog toes
7 dwarf lips
15 ounces of tree bark
32 grams of pixie dust
4 pinches of red pepper
7 pinches of ashes
2 frog toes
20 pounds of charcoal
5 candles
12 spider's legs
999 hours of cackling
999 hours of chanting
999 hours of babbling
11111

Please notice that many items appear more than once on the list. Also notice that this list is not sorted in any way.


Assumptions:

2.1.2 Spell Book

The middle section in the input file contains a list of spells that you know how to cast. Each spell has a name, followed by a list of the ingredients that must be used in order to cast the spell. At the end of each spell, you will see a line containing ``11111'' to designate the end of the list of ingredients. After the last spell, you will see two lines that look like ``11111'' to designate that we have reached the end of the entire list of spells. Below is the list of spells that is listed in the middle section of the primary_input file:
Love Potion
4 candles
3 hours of chanting
5 ounces of camel spit
2 candles
11111
Convert to Toad
3 ounces of bat's blood
4 sheets of parchment
2 hours of cackling
2 pounds of charcoal
3 hours of cackling
11111
Create Rain
3 spider's legs
2 grams of incense
3 grams of pixie dust
4 spider's legs
11111
Finish Project 7
12 beads
3 frog toes
4 hours of chanting
3 sheets of parchment
3 dwarf lips
11111
Levitate
6 grams of incense
3 ounces of bat's blood
2 cloves of garlic
13 candles
4 hours of babbling
11111
Reveal Truth
6 spider's legs
2 candles
13 beads
15 grams of incense
11111
Bring Luck
6 pinches of ashes
2 pinches of red pepper
12 hours of chanting
11111
11111

Notice that some of the ingredients listed may not be mentioned in the initial inventory list. Also there may be ingredients on the initial inventory list that are not mentioned in any of the spells. The spells are not sorted in any way, and the list of ingredients for each spell is also not sorted. Note that the same ingredient may appear more than once in the list for a particular spell.


Assumptions:

2.1.3 Spells to cast

The third and final section in the input file contains a list of spell names. These are the spells that we will try to cast. Below is the list of spell names that you will find in the final section of the primary_input file:
Convert to Toad
Bring Luck
Remove Wart
Love Potion
Levitate

Notice that there may be spells listed that were not listed in the Spell Book. There may also be spells listed in the Spell Book that are not mentioned in this section. By the way, the same spell may be listed in this section repeatedly. Also, please notice that there is no limit to the number of spells that may be listed in this section, so you must process them one at a time rather than trying to read them all into an array and then process them. This section does not terminate with ``11111''.


Assumptions:

2.2 Data structures

You must follow the instructions in this section very carefully or you will lose a lot of credit for this project. You will define the following three structure types for use with this project. (You may also define others if you find them useful.)

  1. Ingredient structures have 2 members:
  2. IngredientList structures have 2 members:
  3. Spell structures have 2 members:

Important: Your inventory must be stored using an IngredientList structure. Your Spell Book must be stored using an array of Spell structures.

2.3 A useful function

As you will read below, this project demands that you use functions effectively. As a big hint, we will mention one important function that you should write, and we will give an outline of how to implement it.

You should write a function that accepts two parameters: An IngredientList; and an Ingredient that we will call newIngred. (You must decide whether to pass these parameters by value, or to pass them with a pointer.)

The role of the function is to add the ingredient newIngred to the list. We will do this in such a way that the elements in the list are always ordered alphabetically by name, and no name will appear more than once on the list.

As an example, imagine that newIngred has the name ``ounces of goop'', and the amount 15. Here is how the function should try to add this ingredient to the list:

  1. If the list is empty, then you should initialize the first element in the list to be a copy of newIngred - i.e. set the name of the first element to ``ounces of goop'' and set the amount to 15. (The function should then terminate.)
  2. If an ingredient already appears on the list with the same name as newIngred (in this case ``ounces of goop''), then you must add the amount specified by newIngred (15) to the amount of the ingredient of the same type that is already on the list. In other words, if you already have an ingredient on the list with the name ``ounces of goop'' and the amount 4, then you should just increase the amount of this ingredient to 19. (The function should then terminate.)
  3. If the list already contains one or more ingredients, but none of them have the same name as newIngred, then you must insert a copy of newIngred into the list so that the names of the ingredients in the list are always ordered alphabetically. Since you will fill your IngredientList structures with data by repeatedly calling this function, you may assume that the ingredients that are already on the list are sorted alphabetically. Therefore, to find the proper location for newIngred, you should start at the beginning of the list and cycle through the ingredients until you find one that is alphabetically greater than newIngred. This will be the spot where newIngred must be inserted. All of the items on the list from this point to the end of the list must be moved over to make room for newIngred. To move these elements over, first move the last one, then the next to the last one, and so on. After you have made room, copy newIngred into the proper location. (In the event that newIngred is the ``largest'' alphabetically, you do not have to move any of the existing members of the list - just add a copy of newIngred to the end of the list.)

You may need to write some ``helper'' functions that will be called by this function. Don't forget that we still have that rule about having a maximum of 30 statements per function!

2.4 Processing and output

  1. Begin by reading in the initial inventory, and storing the data. Use the function described in the section above to add each ingredient to the list. The ingredients should be stored alphabetically by name, and no name should appear more than once on the list.
  2. Display the initial inventory list in the order it is stored. See the primary_output file, below, for the precise formatting.
  3. Read in the Spell Book and store the data. The spells should be added to the array of Spells in the order that they appear in the input file. (The spell names do not have to be alphabetical.) As you are reading the ingredient list for each spell, use the function described in the section above to add each ingredient to the list. For any particular spell, the ingredients in the ingredient list should be stored alphabetically by name, and no name should appear more than once on the list.
  4. Display the Spell Book in the order the Spells are stored. See the primary_output file, below, for the precise formatting.
  5. Print the line that says ``Time for spell casting!'' (See the primary_output file, below, for the precise formatting.)
  6. Read in the list of Spells to Cast, one at a time. After reading each spell, perform the following actions:
    1. Check to see if you have a spell by that name in your Spell Book. If you don't, print the exact message: ``I do not know this spell.'' Then move on to the next spell in the list.
    2. Cycle through the ingredients needed to cast the spell. If you find an ingredient that is not listed in your inventory, print the exact message ``I do not carry %s'', where %s is the name of the ingredient. If you find an ingredient that is listed in your inventory, but the amount in inventory is not sufficient, then print the exact message: ``I do not have enough %s'', where %s is the name of the ingredient. You will print one message for each type of ingredient that is lacking. If you do not have enough of one or more ingredients required for the spell, then the spell will not be cast, so you should not decrease the amounts of any of the ingredients in your inventory.
    3. If you have enough of every ingredient required for the spell, print the exact message: ``Spell Successful!''. You must then subtract from the inventory the quantities of each ingredient that was required to cast the spell. For example, if the spell lists ``8 eyeballs'' as an ingredient, and you have 17 eyeballs in your inventory, then you must reduce the inventory to 9 eyeballs. After you have reduced the inventory amounts for all of the ingredients used, print the message: ``New inventory:'', and then display the entire inventory list. See the section regarding primary_output for the exact formatting requirements. In the event that the amount of an item is reduced to exactly zero, you should no longer display that item when listing the inventory.

2.5 Primary Output

Below are the contents of the file primary_output. This will give you an idea about how your output must be formatted. As usual, it is important for you to check your output against ours using the diff command.

Starting Inventory:
===================
   48 beads
   11 candles
   4 cloves of garlic
   7 dwarf lips
   4 frog toes
   10 grams of incense
   32 grams of pixie dust
   999 hours of babbling
   999 hours of cackling
   999 hours of chanting
   6 ounces of camel spit
   15 ounces of tree bark
   18 pinches of ashes
   4 pinches of red pepper
   20 pounds of charcoal
   17 sheets of parchment
   12 spider's legs

Spell Book
==========

Love Potion
   6 candles
   3 hours of chanting
   5 ounces of camel spit

Convert to Toad
   5 hours of cackling
   3 ounces of bat's blood
   2 pounds of charcoal
   4 sheets of parchment

Create Rain
   2 grams of incense
   3 grams of pixie dust
   7 spider's legs

Finish Project 7
   12 beads
   3 dwarf lips
   3 frog toes
   4 hours of chanting
   3 sheets of parchment

Levitate
   13 candles
   2 cloves of garlic
   6 grams of incense
   4 hours of babbling
   3 ounces of bat's blood

Reveal Truth
   13 beads
   2 candles
   15 grams of incense
   6 spider's legs

Bring Luck
   12 hours of chanting
   6 pinches of ashes
   2 pinches of red pepper

Time for spell casting!
=======================

Attempting to cast Convert to Toad
I do not carry ounces of bat's blood

Attempting to cast Bring Luck
Spell Successful!
New inventory:
   48 beads
   11 candles
   4 cloves of garlic
   7 dwarf lips
   4 frog toes
   10 grams of incense
   32 grams of pixie dust
   999 hours of babbling
   999 hours of cackling
   987 hours of chanting
   6 ounces of camel spit
   15 ounces of tree bark
   12 pinches of ashes
   2 pinches of red pepper
   20 pounds of charcoal
   17 sheets of parchment
   12 spider's legs

Attempting to cast Remove Wart
I do not know this spell.

Attempting to cast Love Potion
Spell Successful!
New inventory:
   48 beads
   5 candles
   4 cloves of garlic
   7 dwarf lips
   4 frog toes
   10 grams of incense
   32 grams of pixie dust
   999 hours of babbling
   999 hours of cackling
   984 hours of chanting
   1 ounces of camel spit
   15 ounces of tree bark
   12 pinches of ashes
   2 pinches of red pepper
   20 pounds of charcoal
   17 sheets of parchment
   12 spider's legs

Attempting to cast Levitate
I do not have enough candles
I do not carry ounces of bat's blood

3 Project requirements

All your C programs in this course should be written in ANSI C, which means they must compile and run correctly with cc -std1 -trapuv on the OIT UNIX Class Cluster. You will lose credit if your program generates any warning messages when it is compiled. Prototypes must appear for all functions used, listed at the top of the program file.

You may use any ANSI C language features we have discussed in the course so far, plus anything we will discuss between now and the end of the semester, with the following exceptions:


Using any of these disallowed C features will result in losing credit.

Your program must have a comment near the top which contains your name, login ID, student ID, your section number, your TA's name, and an original description of the action and operation of the program. In addition, you must have a comment before each function, explaining its action and operation. Your program should be written using good programming style and formatting, as discussed in class and throughout your textbook. For this project, style is considered to consist of:


4 Developing your program

You may want to skip this section at first, read the rest of the project, and come back to study it carefully when you are about to begin writing your program.

The more you write functions to perform various manipulations on structures, the easier your code becomes to test. It is really recommended you use functions for each separate, discrete operation to be performed on any structure.

Here are some suggestions for possible functions. You do not have to use these, and you may use as many other functions as you want:


Do not use a global structure variable or array, like your book does in its example in Chapter 16! You will lose substantial credit if you use global variables in your project.

4.1 Finding compilation errors

If you get an error from the first line of your first function involving a particular structure type, which identifies a syntax error right after the name of the structure type, you probably have declared the structure type after this function which uses it. All structure type definitions must precede the first use of a variable or parameter of that structure type.

Here are several other common compilation errors having to do with structures produced by the cc compiler on our class machines and what they mean:


4.2 Program debugging


  1. Add lots of debug printf statements if your code isn't working, to find out where! You need to know this before you can find out why the problem is occurring.

  2. Draw lots of pictures of your structure types to trace exactly where things are in memory.

  3. If after you have tried these techniques, and tested each of your functions, you still can't figure out why your program doesn't work, bring a printout to our office hours, and we can help you learn how to track the problem down.

4.3 Helpful hints

Frequently save backup copies of your program under different names or in different subdirectories, so even if you inadvertently delete your file or change things which you realize you shouldn't have, it's easy to recover a recent version.

5 Academic integrity statement

Any evidence of unauthorized use of computer accounts or cooperation on projects will be submitted to the Student Honor Council, which could result in an XF for the course, suspension, or expulsion from the University. Projects are to be written INDIVIDUALLY. For academic honesty purposes, projects are to be considered comparable to a take-home exam. Any cooperation or exchange of ideas which would be prohibited on an exam is also prohibited on a project assignment, and WILL BE REPORTED to the Honor Council.


VIOLATIONS OF ACADEMIC HONESTY INCLUDE:


  1. failing to do all or any of the work on a project by yourself, other than assistance from the instructional staff.

  2. using any ideas or any part of another student's project, or copying any other individual's work in any way.

  3. giving any parts or ideas from your project, including test data, to another student.

  4. having programs on an open account or on a PC that other students can access.

  5. transferring any part of a project to or from another student or individual by any means, electronic or otherwise.


IT IS THE RESPONSIBILITY, UNDER THE UNIVERSITY HONOR POLICY, OF ANY STUDENT WHO LEARNS OF AN INCIDENT OF ACADEMIC DISHONESTY TO REPORT IT TO THEIR INSTRUCTOR.

6 Submitting your project

Your project must be electronically submitted by the date above, to avoid losing credit as described on the syllabus. No projects more than two days late will be accepted for credit without prior permission or a valid medical excuse, as described on your syllabus. Only the project which you electronically submit, according to the procedures provided, can be graded; it is your responsibility to test your program and verify that it works properly before submitting. Lost passwords or other system problems do not constitute valid justifications for late projects, so do not put off working on your program or wait to submit it at the last minute!

Turn in your assignment using the ``submit'' program as before, except using ``7'' for the project number. You are to submit only the .c file containing your source code, not the executable version of your program! If your program is in a file named ``p7.c'', submit would be run as submit 7 p7.c.

Before you submit your project, you must exactly follow the specific submission checklist in the ``Testing projects before submitting'' handout separately posted by your instructor!



Steve Scolnik 2002-11-25

Web Accessibility