CMSC 106 Project #4 - SymPond Fall 2002


Due date: November 4th, before 11:00 p.m.

1 Purpose

In this project you will write a program that uses arrays to store and process data. Your program will simulate a pond, which contains a fish who will swim around, eat some plants, and eventually die. If all goes well, the output from your program will appear to be a real-time animation of the fish's life. Below is a snapshot of a typical pond at one instant in time:

@@@@@@@@@@@@@@@@
@@        @@@@@@
@   ::: <  @@@@@
@    ::       @@
@@@      ::   @@
@@       :     @
@    @@        @
@ ::  @@   ::  @
@@@@          @@
@@@@@@@@@@@@@@@@

The ``@'' symbols are land surrounding the pond. The ``:'' symbols are the plants that the fish loves to eat, and the ``<'' is the fish. (Blank spaces are water.)

Note that the shape of the fish will change depending on which way he has just moved:

    <  fish just moved left
    >  fish just moved right
    A  fish just moved up   (this is a capital A)
    V  fish just moved down (this is a capital V)

2 Files Provided

For this project, we are giving you the usual primary input and output files, but we are also going to give you a working copy of the program to see how it runs when it's finished! (Of course we aren't giving you the ``.c'' file, just the executable, ``SymPond.x''.)

The following files are provided in your instructor's posting account:

SymPond.x
animation_input
primary_input
primary_output

Copy all of these files into your own account. (By now you should know how to do this. If you don't know, drop by TA office hours.) When you are done with the project, your executable should work just like ``SymPond.x''.

To see the program work, type:

   SymPond.x < animation_input

You should see an animation of the life and death of a fish!

3 Project description

As with previous projects, the input for your program will be read from a file using Unix redirection. Below are the contents of the primary input file which we have given you:

10
16
@@@@@@@@@@@@@@@@
@@        @@@@@@
@          @@@@@
@             @@
@@@           @@
@@             @
@    @@        @
@     @@       @
@@@@          @@
@@@@@@@@@@@@@@@@
15
2 8
12
2 4 3
2 5 7
2 6 4
3 5 5
3 6 11
4 9 1
4 10 7
5 9 4
7 2 3
7 3 8
7 11 3
7 12 6
N

You may assume (without checking) that all of the numbers that appear in the input stream will be integers. (There are no floats at all in this project.)

The first two numbers (in this case 10 and 16) describe the dimensions of the pond. (In this case: 10 rows and 16 columns). Important: The dimensions of the pond will never exceed 57 units in either direction. You may also assume that each dimension will be at least 4 units.

After the dimenions, the input file includes the grid of characters that represent the shape of the pond. '@' symbols represent land, spaces are water.

Directly beneath the picture of the pond are numbers that describe the fish. First the fish's weight: in this case, 15. Next you see the starting coordinates for the fish, in this case 2 8. This indicates that the fish is in row 2, column 8. (Note that the row and column coordinates are 0-based; e.g. the first row is row 0.)

After the fish data you are given data about the plants in the pond. The first value (in this case 12) specifies the number of plants that are in the pond in the beginning of the simulation. This value is followed by one line of data for each plant. For each plant you are given the location coordinates and the caloric content. So in the example above, the first plant is located in row 2, column 4, and contains 3 calories of nutritional value.

The last data element in the file represents a flag (either 'Y' or 'N') that will indicate whether or not the program should show every frame in the animation, or just show the pond once at the end. (We'll say more about this flag later.)

Important: The coordinates of the pond should be envisioned as below. The asterisk indicates the position row 2, column 8, where the fish in this example will start.

  0 1 2 3 4 5 6 7 8 9...
0
1
2                 *
3
4
.
.
.

3.1 Error Checking - the Lack Thereof

You may assume that all of the input values are reasonable. You do not have to do any checking. You may also assume that the pond provided will be entirely surrounded by land, so that there is no possibility of the fish swimming off the edge of the grid. You may also assume that the position where the fish starts will not be over land or over a plant. You may also assume that all of the plants will be positioned in the water (not on land.) Further, you may assume that the weight of the fish and the caloric values of the plants are always bigger than zero.

3.2 Fish Movement

The fish is not that smart. He will move one square every ``day''. The fish will always move either Left, Right, Up or Down. (No diagonals.) Once the fish starts moving in a particular direction, he will continue to move in that direction until he encounters land. The fish will always begin his life moving to the Left.

The fish may never move onto the land (he is not a snakehead fish). If the fish is about to move onto land, he will change his direction so that when he moves he will still be on the water. Below are the specific rules that you must use to determine which way the fish will go when he runs into the land.

If the fish wants to move to the Left, but there is land there, he will change his direction to ``Up''.

If the fish wants to move Up, but there is land there, he will change his direction to ``Right''.

If the fish wants to move Right, but there is land there, he will change his direction to ``Down''.

If the fish wants to move Down, but there is land there, he will change his direction to ``Left''.


As an example, consider the diagram below. Imagine that this poor fish wants to move left.

@@@@@@@@
@@@@
@@<
@
@

Since he cannot move left, he changes his mind and decides to move up. Unfortunately, he cannot move up either, so he changes his mind again and begins to move to the right:

@@@@@@@@
@@@@
@@ >
@
@

You may assume that the fish will never be trapped on all sides like this:

@@@
@<@
@@@

3.3 Drawing the Pond

There are two drawing modes: ``animation'' and ``just show the end''. The mode will be determined by the last entry in the input file. If this last entry is ``Y'', then you will use ``animation mode''. If this last entry is ``N'', then you will use ``just show the end'' mode.

3.3.1 Just-Show-The-End Mode

In this mode there is no output at all until after the fish dies. At this point, you draw the pond just once, the way it appears after the fish's death.

3.3.2 Animation Mode

In animation mode, the pond will be drawn after each ``day.'' (I.e. each time the fish moves.) Important: The pond is not drawn the first time until after the fish has moved once. The last time the pond is drawn will be just after the fish dies. Below is an example of output for a typical sequence of three ``days'' during the life of a fish. Notice that there are no blank lines between the pictures of the pond. (Note: This is a sample of three consecutive days taken out of the middle of the fish's life. Presumably there is a lot of data before and after this section.)

@@@@@@@@@@@@@@@@
@@        @@@@@@
@          @@@@@
@    ::       @@
@@@      :    @@
@@       :     @
@    @@        @
@ ::  @@   ::  @
@@@@     <    @@
@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@
@@        @@@@@@
@          @@@@@
@    ::       @@
@@@      :    @@
@@       :     @
@    @@        @
@ ::  @@   ::  @
@@@@    <     @@
@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@
@@        @@@@@@
@          @@@@@
@    ::       @@
@@@      :    @@
@@       :     @
@    @@        @
@ ::  @@   ::  @
@@@@   <      @@
@@@@@@@@@@@@@@@@

Important: To get this to look like an animation on your screen, you will need to slow the computer down. To accomplish this, insert the following line so that it will run once after each time the pond is drawn during animation mode:

usleep(300000);

This instruction tells the computer to ``sleep'' (i.e. do nothing) for 300000 microseconds. (A microsecond is one millionth of a second.) You may want to change this number to either speed up or slow down the animation. If it doesn't look smooth on your screen, try slowing it down by using a larger value.

IMPORTANT: BEFORE YOU SUBMIT YOUR PROGRAM, TAKE OUT ALL CALLS TO THE USLEEP FUNCTION. OTHERWISE WE CANNOT GRADE YOUR PROJECT.

To see your output as an animation, you should use Unix redirection for your input, but send your output to the screen. For example:

% a.out < animation_input

3.4 Death of the fish

This is the sad part. As you'll read below, the fish's weight decreases as he ages. When his weight finally reaches zero, he will die. When the fish dies, he decomposes and plants will grow in the 3 by 3 square surrounding his place of death:

:::
:::
:::

Note that plants cannot grow where there is land. As an example, suppose the fish is in the position indicated by the asterisk below when he dies:

@@@@
@@ @@@@ 
@@*
@
@

After his death, plants will grow like this:

@@@@
@@:@@@@
@@::
@:::
@

3.5 A day in the life of a fish

Your pond simluation should be written as a big loop, where each pass through the loop corresponds to a day in the life of the fish. The loop will only terminate when the fish dies.

Here is what must transpire in each ``day'' of the fish's life. (It is important that things happen in the exact order listed below.)

  1. Fish checks to see if he is about to hit land. If he is, he must find a different direction to move that will not result in hitting land. (See the section above about fish movement to see how to select a new direction.)
  2. Fish moves one unit.
  3. If the fish is now above a plant, he will eat it. This means that the plant is no longer there (just water), and the fish's weight must be increased by the caloric content of the plant. (Yummy.)
  4. The fish ages. His weight must be decreased by 1 unit. If his weight after this decrease is now 0, he dies. (Don't forget that plants will grow near his place of death.)
  5. The pond may now be drawn. (See the section about drawing the pond to see how to decide whether or not the pond must be drawn every day, or just on the last day.) Don't forget to draw the fish with the correct shape, depending on which direction he just moved, if he is still alive. (Once he is dead, do not draw the fish - there is no ghost-fish.)

4 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. Even if you already know what they are, you may not use any C language features other than those introduced in Chapters 1 through 8 of your textbook, plus those presented in lecture while these chapters were covered. Note that as a result user-defined functions may not be used. In addition, although they are covered in the allowable chapters, neither the goto nor the continue statement may be used, and the break statement may not be used in any loop. Lastly, your program must contain only one single return statement at its end, and may not use the exit() library function at all. Using C features not in these chapters, or using the goto statement, the exit() library function, multiple returns, or break or continue in loops, 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. 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:



5 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.

Even if you didn't need to refer much to the methods presented in the corresponding sections in the earlier project assignments, you will need to begin reading these carefully now because as the assignments get larger and more complex these techniques for debugging and program development will become indispensable. Remember, one of the important topics you must learn in this course is how to track down and fix both syntax and semantic errors in your code. You will need to follow the procedures described, as well as be able to describe an error and what you have already done to find it, and bring a printout of your source code if you need to come for assistance with it during office hours.

5.1 Possible development steps

These steps are a suggestion only; you can follow others if you prefer, since there are many ways to develop any program. However, whatever steps you do choose, you should be certain to write small parts of your program at a time and test each one to verify that it works before going on!


  1. You could begin by declaring one or more arrays to hold your data. For the symbols in the pond, you should declare a two dimensional character array that is big enough to hold the biggest possible pond (57 by 57). The first line of the input file will tell you how much of that array will be used.

  2. Do all of the reading of the input file to fill the array, and initialize the fish and plants. Put some temporary printf statements in to verify that all of the data has been read correctly.

  3. Create a big loop to handle each day in the life of the fish.

  4. Program the fish's movements.

  5. Program the fish's weight loss and subsequent death.

  6. Have the fish eat plants when they are beneath him.

  7. Lastly, thoroughly check your entire program after finishing it before submitting it. Create several input files testing them all by hand.

  8. Before submitting your program, TAKE OUT ANY USES OF THE ``USLEEP'' FUNCTION.


5.2 Primary Input and Output

As usual, we are giving you one test case to experiment with. (Notice that the file ``animation_input'' is identical to ``primary_input'', except that it specifies ``animation mode'' instead of ``just-show-the-end'' mode.) Of course we will test your program with a wide variety of different input files. We will use ponds of different sizes and shapes. Important: Make sure that your program works in both ``animation'' mode and ``just-show-the-end'' mode, because we will test both modes heavily.

5.3 Finding compilation errors


Invalid #define

If every line (or most lines) which use a symbolic constant is flagged as an invalid statement, the error is most likely in the definition of the constant itself.


5.4 Program debugging

The most common error in C programs with arrays is using invalid subscripts to refer to array elements (falling off one edge or other of an array).


Segmentation fault (core dumped)

Getting this error when a program runs usually means it has referred to an invalid area of memory, which is often caused by incorrect array subscripts. To find the problem, add debug printfs to narrow down where in your program the problem occurs. Before every reference to an array element appearing in that section of code you can add debug printfs which display the values which will be used as subscripts. For instance, if your code contains a statement like

printf("%d", array[i][j]);
            


then add test statements above it to print the values of i and j. Verify by running the program that i is not larger than the maximum row subscript for the array, and j is not larger than the maximum column subscript. Falling off an edge of the array won't necessarily lead to a core dump, it may just cause incorrect results.

\n for debug printfs

For technical reasons, all debug printfs used must end in \n. Otherwise, if your program has a core dump, some (or all) of the debug print results may not be displayed before the program halts, defeating the purpose of adding the debug printfs.

core file

A core dump creates a file named "core" which contains the contents of your memory space at the time of the program crash. This file can get large and is not useful at all for our purposes, so it should be removed before going on to prevent exceeding your quota of disk space.


6 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.

7 Submitting your project

IMPORTANT: BEFORE YOU SUBMIT YOUR PROJECT, TAKE OUT ANY LINES WHERE YOU HAVE USED ``USLEEP''. OTHERWISE YOUR PROJECT CANNOT BE GRADED.

Your project must be electronically submitted by the date above to avoid losing credit. 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 ``4'' 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 ``p4.c'', submit would be run as

submit 4 p4.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-10-21