CSE 142 Homework #3

Pumpkin Design Assistant

This assignment consists of two parts. First, a pair of exercises involving writing short functions which use loops. The main assignment is to write a longer program to design and display faces.


Loop Exercises

Files

Stairs: stairstarter.c   sample executable

Factorial: facstarter.c   sample executable

Instructions

Most of the instructions are contained with the starter .c files.

There are two programs (two .c files) to complete.  Both involve completing functions and main.  The two programs are independent, so you could do them in either order, or work on them simultaneously.

Every function and both mains involve loops.   We would like you to get experience with both while and for loops.  You should have examples of each kind of loop in the program you complete.

The first program is called Stair Case.  Please read through the entire starter .c file before beginning work.

The starter version  calls a test function which we supply, and your final version should also call testcases.  However, as you are developing the program, you may find it better to write your own test function as you go along, or make test calls directly from main.  (For example, as soon as you get the printChar function written and compiling without error, test it by placing calls to it from main.   When you are sure printChar works perfectly, write the next function, and test it by making calls to it from main.  Keep doing this until everything works completely.)  Before turning in the program, remove (or better yet, comment out) your test cases, and restore the call to our testcases function at the beginning of main (and be sure to test it again before turning in!)

For the second program, Factorial, follow the specifications given as comments in the program.  As you will see, it involves a certain amount of experimentation after most of the programming is done.  Your result (the LASTGOODVALUE) might be different from the one given by the sample executable.  And that answer itself might seem wrong, since you will be running the program on a machine different from the one used to develop the program.


Programming Assignment

Pumpkin Design Assistant (PDA)


Introduction

The wizards continue to be impressed with your application of muggle technology to help automate the magical world. Your next task takes you to Hogwarts School of Wizardry. One of the big events is the annual Halloween party. The great hall is to be decorated with pumpkins, and your job is to help design the faces to be carved in the pumpkins.

You are to write a program that allows the user to interactively design a carving of a pumpkin. The program will display a menu for the user giving a set of options for choice of nose, eyes, and mouth, as well as resizing the pumpkin. Since computers are new to the wizarding world, you can use a simple command line menu, instead of implementing a fancy GUI.

Key Concepts

In this homework, keep an eye out for...

Specifications

            Before perusing the specifications, please check out the sample executable.  Get a feel for how the program operates.  Then read the program specifications (all the way through!).  Scan through the starter code to see what is given.  Finally, check out our suggestions concerning managing the complexity of the application.

            The goal of the Pumpkin Design Assistant (PDA) is to allow you to customize a pumpkin, using a menu-driven interface.  The program continues running until the user chooses to exit the application (using one of the menu options).  You will find that the code needed to display the menu and process a selection has already been written for you.  You will need to write the code that reads a menu option (integer) from the user, and verifies that the input is valid.

The various menu options are:
  1. Display This Menu This one is written for you, it displays the menu
  2. Print.  This menu option displays the pumpkin as it is currently formatted.  For more information, see    Drawing the Pumpkin, below.
  3. Increase Height.  Increases the current height of the pumpkin by one line unless this would enlarge the  pumpkin’s size above its maximum height.  The height of the pumpkin begins at its minimum height (defined below).
  4. Decrease Height.  Decreases the current height of the pumpkin by one line unless this would reduce the pumpkin’s size below its minimum height (defined below). 
  5. Increase Width.  Increases the current width of the pumpkin by two characters unless this would enlarge the pumpkin’s size above its maximum width.  The width of the pumpkin begins at its minimum width (defined below).
  6. Decrease Width.  Decreases the current width of the pumpkin by two characters unless this would reduce the pumpkin’s size below its minimum width (defined below).  Thus, this option has no effect until the width has been increased, using Increase Width.
  7. Choose Eyes.  Displays a sub-menu (see Selecting Facial Features below) for selecting a style of eyes.  Once the user has selected a style using the sub-menu, the currently selected eye is updated.
  8. Choose Nose.  Displays a sub-menu (see Selecting Facial Features below) for selecting the style of nose.  Once the user has selected a style using the sub-menu, the currently selected nose is updated.
  9. Choose Mouth.  Displays a sub-menu (see Selecting Facial Features below) for selecting the style of mouth.  Once the user has selected a style using the sub-menu, the currently selected mouth is updated.
  10. Exit Program.  Ends the application.

Drawing the Pumpkin

            The pumpkin will be drawn using the normal characters on the keyboard.  Of particular use are vertical bars (|), underscores (_), hyphens (-), forward-slashes (/) and back-slashes (\).  Use other characters as you find them useful.

            The forehead is drawn in the first four lines of the pumpkin (regardless of the size of the pumpkin).  The chin is drawn in the last two lines.  The remaining space is allocated (as evenly as possible) to the eyes, nose and mouth regions.    Since the pumpkin’s height is variable, you will need to add blank space above (or below) the facial features so that the entire height is used.

            Each facial feature (eyes, nose and mouth) needs to be drawn inside a border.  You are free to design a suitable border (e.g., a rectangle).  At its widest part, the border needs to use the entire width of the pumpkin.

            The appearance of the facial features depends on the currently selected eyes, nose and mouth.  Using the selection sub-menus (see Selecting Facial Features below), the user can select various facial features.  Whichever facial feature is currently selected should be drawn in the space allocated to that feature.

            As the width of the pumpkin grows, space will need to be added around the facial features.  The nose and mouth should always be centered on the pumpkin.  The eyes can either be centered, or they can move apart as the pumpkin grows.

Selecting Facial Features

            Your program will need three sub-menus, one for each style of facial feature.  Each sub-menu must have the following options:

0. No Eyes/Nose/Mouth.  This option selects a completely blank facial feature.  When the program starts, the eyes, nose and mouth should all be blank.

1, 2, … Additional Features.  You are free to design whatever facial features you choose.  You must design at least 2 of each (i.e., 2 eyes, 2 noses and 2 mouths).  Your designs do not have to mimic those of the sample executable, but they should be as interesting -- or more so!

            The sub-menu will not look like the main menu.  Instead, it should consist of a simple instruction (like “Choose a nose:”) followed by each of the options.  The options should be numbered (so the user knows what value to enter to choose that option), and the currently selected option should be marked in some manner (e.g., using an asterisk, which is what the sample executable uses).  After the option number, you should draw the feature as it would appear on the pumpkin (using at most 3 lines).  You may draw the feature using the pumpkin’s current width or the using the minimum width.  Check out the sample executables for examples.

Retrieving User Input

            Since the program is menu driven, the user needs to have some way to select menu options.  Each menu option will correspond to a number, which can be entered by the user.

            You should display a simple prompt whenever you expect the user to enter a value.  This can be as simple as a single hyphen (-) or more complex (e.g., the valid input range, followed by a > symbol).

            You may assume that the user will only enter valid integers (if the user types a character or a double, it is OK for your program not to work properly).  You do need to validate the user’s choice.  The user should only be allowed to enter values that correspond to menu options.  If the entry is too low or too high, you should display an error message.  This message should tell the user either the valid input range or what value to enter to see the current menu.  (The latter is slightly more work, but it looks cool.)

Minimum/Maximum Size

            The width and height of the pumpkin begin at pre-specified minimum values.  Neither value should ever be less than its corresponding minimum.  The minimum height is defined as the sum of the minimum heights of the 5 components of the pumpkin: The forehead is always drawn using exactly 4 lines.  The eyes, nose and mouth are drawn using at least 3 lines each.  The chin is always drawn using exactly 2 lines.

            You will need to choose a minimum width.  A good rule of thumb is to set the minimum width equal to the maximum width of the mouth, plus 4.  (This leaves room for one blank space on either side, plus a border.  Check out the sample executable.)

            The starter code also includes a maximum height and a maximum width.  These values should also never be exceeded.

Getting Started

            The first step is to decide which variables you will need to complete the assignment.  You will need to determine what information needs to be preserved for the duration of the program.  These variables need to be declared in main (remember, no global variables).  Of course, there may be variables that are needed only for a specific operation; these will probably be local variables for some function.

            We have provided you with code that outlines the main menu.  A good first step is to determine how you will retrieve information from the user.  Recall that the user should only be allowed to enter a value that corresponds to a menu option.  Once the user enters a valid menu option, that value will be used by the switch statement to control program execution.  

An important design decision: should you create a function that retrieves a value entered by the user, or place that code inside main?  If you choose to use a function, you will need to decide what parameters are needed by the function (if any).  Whatever your decision, you need to be able to justify that decision.

            At this point, your program should be able to display the menu, and retrieve a value from the user.  The user’s input will be ignored for the time being, but it’s a good idea to test each new feature as you add it.  Compile your program and verify that the user can only enter integers that correspond to menu options.  (As always, you can assume that the user will not enter a double, when an integer is requested.)

            Another relatively easy step is to change the program logic so that the menu can be displayed multiple times.  You need to decide how to modify the code so that the program will run until the user enters EXIT_PROGRAM.  Don’t forget to fill in the case EXIT_PROGRAM: so that the correct thing happens when the user chooses this option.

            The next step will be slightly more involved: drawing the pumpkin.  A good idea would be to draw a "call-graph" (see course packet) before starting to write any code.  Drawing a pumpkin consists of drawing the forehead, drawing the eyes, drawing the nose, drawing the mouth, and drawing the chin.  This might suggest writing some helper functions.  You should also determine what common functionality is needed for drawing.  A (not-so-subtle) hint is to write a function that draws the some character (c), n times.  At this stage, do not worry about the fact that the pumpkin’s height and width can change; just assume a constant size.  You might also want to assume that no eye, nose or mouth has been chosen yet (This is a safe assumption since the user cannot yet choose these features!)  Once you are done with this step, 3 of the menu options should be working properly.

            The next step is to change the pumpkin’s size.  Changing the width is easier.  Add the code needed to update the width of the pumpkin (this is the easy part).  Don’t forget about the minimum/maximum width.  The harder part is to modify the drawing routine(s) so that the width of the pumpkin is taken into account.  As always, you should update incrementally.  You could, perhaps, start with the chin and work up, or vice versa.

            You have reached a significant milestone.  Much of your program is now functional.  Adding the code needed to update the height is the next step.  You will need to decide how to allocate space between the eyes, nose and mouth regions.  If you are having trouble, you might want to look at old quiz section solutions.  The drawing routine(s) will need to be modified to allow for extra (blank) space.

            The final step is to allow the user to change the eyes, nose and mouth.  Choose one feature to start with (e.g., the mouth).  When the user selects CHOOSE_MOUTH, your program should display the options (don’t forget to indicate the current selection) and wait for the user to select one of the options.  (Is there any code you’ve already written that you can re-use here?)  Once you are sure that the mouth is working properly, you should be able to add the nose and eyes fairly easily.  (Given our current knowledge of C, there isn’t any good way to re-use code here.  You will probably end up cutting and pasting a fair amount.)

            Once you have a fully functional program (with little artistic merit), you can play with improving the appearance of the pumpkin.  It is important that this be the last step.  Artistic design is worth very little in this assignment.  You will be much better off submitting a program that works properly than one that looks nice, but works poorly.

FAQ

Q: I’m getting unrecognized character escape sequence (C4129) warnings when I compile.  What does this mean?

A: It might mean you used a backslash (\) in a string.  Since the backslash is used to indicate special characters (e.g., \n), you need to use a double-backslash (\\) whenever you want a backslash to appear.

Q: How do I make the console window bigger?

A: Right-click on the title-bar, and select Properties.  Select the Layout tab.  Increase the Window Size Height to a suitably large value (e.g., 50).  Click OK, select the Save properties … option, and then click OK.  This only works on Windows NT and Windows 2000; I do not think there is a way to change the console size in Windows98/95.

Q: How do I divide the excess height into three roughly equal size groups, so that all space is accounted for?

A: The following code assigns values to x1, x2, and x3, such that x1+x2+x3 == n and x1, x2, and x3 differ by at most 1.

x1 = n/3;
x2 = (n+1)/3;
x3 = (n+2)/3;

Programming Requirements

One of the key concepts you should exercise in this assignment is appropriate use of functions.  Some operations need to be performed several times (verifying that input is successful and that the input has a sensible value is one fairly obvious example).  Other operations are sufficiently complex or subtle that it makes sense to define them as a function.  That isolates the details of the operation in a separate part of the code instead of embedding it in in the main program.

You should define appropriate functions in your program and use them as needed.  You need to rely on your own best judgment.  You shouldn't define a tiny function for every separate calculation in the program, but you should use functions to break up the program into understandable chunks of code, each one of which does a single, self-contained operation.  A function that is too long is often a sign of poor design.  This applies to main, too!

Beside the specific requirement of using functions appropriately, your code should be clean and understandable as always.  Remember to:

Files

Two sample executable files are provided to indicate the range of solutions that are possible for this assignment.

A few bits of advice