Due date: 8:00 A.M. Saturday, November 1st

1 Overview

In this project you will write a program that uses arrays to store and process data. Your program will simulate an automobile race with just one car. (Not very exciting to watch is it?) The car will move around the track in a predictable way, always turning just before it hits a wall. The car starts off with a certain amount of fuel, which is used up as it travels. The track will contain oil slicks (drawn as '*' symbols) and some fuel supplements (drawn as 'F' symbols). When the car encounters an oil slick, the oil slick will disappear from the track, and the car's direction will change abruptly. When the car encounters a fuel supplement, the fuel supplement will disappear from the track, and the car's fuel supply will be increased. (Each fuel supplement will increase the fuel supply by a different amount - explained later). The car will leave behind its own oil slicks from time to time. The race is over when the car either runs out of fuel, or completes a pre-determined number of laps.

If all goes well, the output from your program will appear to be a real-time animation of the race. Below is a snapshot of a typical race at one point in time:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@   F   X     |            @@@@@@
@@@@@              |  *          @@@@@
@@@                |               @@@
@@                 |        *       @@
@     F   @@@@@@@@@@@@@@@@@@         @
@         @@@@@@@@@@@@@@@@@@         @
@@    *                             @@
@@@                           F    @@@
@@@@@          *                  @@@@
@@@@@@                           @@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

The `@' symbols are walls surrounding the track. The '|' symbols represent the finish line. The 'F' symbols are fuel supplements. The '*' symbols are oil slicks. Finally, the 'X' is the car!

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, ``race.x''.)

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

race.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 ``race.x''.

To see the program work, type:

   race.x < animation_input

You should see an animation of a one lap race.

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:

12
38
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@             |            @@@@@@
@@@@@          *   |  X          @@@@@
@@@                |               @@@
@@                 |        *       @@
@         @@@@@@@@@@@@@@@@@@         @
@         @@@@@@@@@@@@@@@@@@         @
@@    *                             @@
@@@                                @@@
@@@@@          *                  @@@@
@@@@@@                           @@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
3
1 9 20
5 6 25
8 30 35
1
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 12 and 38) describe the dimensions of the track area. (In this case: 12 rows and 38 columns). Important: The dimensions of the track 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 track. '@' symbols represent the walls, '*' symbols represent oil slicks, '|' symbols represent the finish line. The 'X' represents the starting position of the car. Hint: Don't forget that every line in the input file ends with a newline character. If you are reading in one character at a time, you will need to carefully remove the newline character after each line.

After the picture of the track, you are given data about the fuel supplements that will be provided at the start of the race. They will be scattered around at various locations on the track.

The first value (in this case 3) specifies the number of fuel supplements that this particular race will start with. Important: The race will never start with more than 40 fuel supplements on the track.

Next you will find one line of data for each fuel supplement. For each fuel supplement you are given the location coordinates and the amount of fuel that is available at that location. In the example above, the first fuel supplement is located in row 1, column 9, and contains 20 units of fuel. When you draw the track you will represent the location of these fuel supplements by drawing an 'F' symbol.

Just after the fuel supplement data, you will see a number. (In this case it is a 1.) This number represents the number of laps that the car must complete around the track. (More about that later.)

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 track once at the end of the race. (We'll say more about this flag later.) Hint: Don't forget that the previous line ended with a newline character. You may have to remove this character before reading in the animation flag.

Important: The coordinates of the track should be envisioned as below. (Note that we are using 0-based indexing). The 'F' indicates the position row 1, column 9, where the first fuel supplement is located in the primary input case.

  0 1 2 3 4 5 6 7 8 9...
0
1                   F
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 track provided will be entirely surrounded by walls, so that there is no possibility of the car driving off the edge of the grid. You may also assume that the position where the car starts will not be over a fuel supplement. You may also assume that all of the fuel supplements will be positioned on an empty part of the track itself (not on a wall and not on the finish line.) You may assume that each fuel supplement will contain an amount of fuel that is greater than 0. You may also assume that the finish line will be drawn in a way that makes sense.

3.2 Start Your Engine

The car always starts off with 100 units of fuel. The car's direction always starts off moving to the LEFT.

3.3 Car Movement

The car will move one position at a time. It will always move either Left, Right, Up or Down. (No diagonals.) Once the car starts moving in a particular direction, it will continue to move in that direction until it encounters a wall or an oil slick.

3.3.1 The word ``Frame''

We will refer to each moment in time just after the car has moved as a ``frame''. This will help us to discuss the flow of your program. We will think of the race as a sequence of ``frames''.

3.3.2 Walls

The car may never move onto a wall. If the car is about to move onto a wall, it will change its direction so that when it moves it will still be on the track. Below are the specific rules that you must use to determine which way the car will go when it runs into the wall.

If the car wants to move to the Left, but there is a wall there, it will change its direction to ``Down''.

If the driver wants to move Up, but there is a wall there, it will change its direction to ``Left''.

If the car wants to move Right, but there is a wall there, it will change its direction to ``Up''.

If the car wants to move Down, but there is a wall there, it will change its direction to ``Right''.


Note that you may need to apply more than one rule for a particular movement. As an example, consider the diagram below. Imagine that the car is indicated by the 'X' and wants to move LEFT.

@
@
@@X
@@@@
@@@@@@@@

Since it cannot move left, it changes its mind and decides to move down. Unfortunately, it cannot move down either, so it changes its mind again and decides to move to the right. The subsequent frame would look like this:

@
@
@@ X
@@@@
@@@@@@@@

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

@@@
@X@
@@@

3.3.3 Encountering Oil Slicks

The car CAN drive onto an oil slick. If this happens, the oil slick is removed from the track, and the direction of the car will change, as described below:

If the car has just moved LEFT onto an oil slick, its direction on the subsequent movement will be UP.

If the car has just moved UP onto an oil slick, its direction on the subsequent movement will be RIGHT.

If the car has just moved RIGHT onto an oil slick, its direction on the subsequent movement will be DOWN.

If the car has just moved DOWN onto an oil slick, its direction on the subsequent movement will be LEFT.

3.4 Drawing the Race

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.4.1 Just-Show-The-End Mode

In this mode there is no output at all until the end of the race. (The race will end when the car either runs out of fuel, or completes the correct number of laps.) In ``Just-Show-The-End Mode'', you draw the race just once, the way it appears at the end. This is the mode used in the primary input case.

3.4.2 Animation Mode

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

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@       *     |            @@@@@@
@@@@@              |  *          @@@@@
@@@                |               @@@
@@    *            |        *       @@
@         @@@@@@@@@@@@@@@@@@         @
@         @@@@@@@@@@@@@@@@@@         @
@@                                  @@
@@@      *       X            F    @@@
@@@@@          *                  @@@@
@@@@@@                           @@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@       *     |            @@@@@@
@@@@@              |  *          @@@@@
@@@                |               @@@
@@    *            |        *       @@
@         @@@@@@@@@@@@@@@@@@         @
@         @@@@@@@@@@@@@@@@@@         @
@@                                  @@
@@@      *        X           F    @@@
@@@@@          *                  @@@@
@@@@@@                           @@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@       *     |            @@@@@@
@@@@@              |  *          @@@@@
@@@                |               @@@
@@    *            |        *       @@
@         @@@@@@@@@@@@@@@@@@         @
@         @@@@@@@@@@@@@@@@@@         @
@@                                  @@
@@@      *         X          F    @@@
@@@@@          *                  @@@@
@@@@@@                           @@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

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 be executed once after each time the track 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.5 End of the Race

There are two ways the race could end. Either the car runs out of fuel, or the car completes the expected number of laps.

3.5.1 Running out of Fuel

As you'll read below, the car's fuel supply is decreased by 1 unit every time it moves. When the fuel supply reaches 0, the race is over.

3.5.2 Finishing the Race

If the car doesn't run out of fuel, it might actually be able to finish the race. Remember that the number of laps is provided in the input file.

You will need to keep track of the number of times the car actually crosses over the finish line. Note that the car will cross the finish line once just as the race begins. That means that if the race is supposed to go on for four laps, then the race will end just after the car has reached the finish line for the fifth time.

3.6 One ``Frame'' in the Race

Your race simluation should be written as a big loop, where each pass through the loop corresponds to a ``frame'' in the race. (The car moves exactly one position each frame.) The loop will only terminate when the race is over.

Here is what must transpire each time through this big loop. (It is important that things happen in the exact order listed below.)

  1. Check to see if the car is about to hit a wall. If it is, it must find a different direction to move that will not result in hitting a wall. (See the section above about car movement to see how to select a new direction.)
  2. Decide whether or not the car will generate an oil slick. If the amount of fuel in the tank is divisible by 10, then when the car moves it will leave behind an oil slick in its current location. (Note: There is one exception - if the car's current location is over the finish line, then it will NOT emit an oil slick.)
  3. The car's position is moved one unit either up, down, left or right, depending on it's current direction. Don't forget that the car may leave an oil slick behind.
  4. If the car has moved onto the finish line, increment the number of laps completed.
  5. If the car has moved onto a fuel supplement, remove the fuel supplement from the track, and add the amount of fuel contained in the supplement to the car's fuel tank.
  6. If the car has moved onto an oil slick, change the direction of the car (for movement the next time through the loop) and remove the oil slick from the track.
  7. Decrease the amount of fuel in the tank by one unit.
  8. If the amount of fuel has reached 0 or if the number of laps completed indicates that the race should end then the race will end AFTER you draw the race in step 9.
  9. If you are in animation mode or if the race is about to end, draw the race.

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

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

6.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 track, you should declare a two dimensional character array that is big enough to hold the biggest possible track (57 by 57). The first two numbers in the input file will tell you what portion of this huge array will actually be used for the current track. For the fuel supplements you might choose to use ``parallel arrays'' to keep track of their information. Remember that there will never be more than 40 fuel supplements. You might use one array to store the Row Number of each fuel supplement, another array for the Column Number, and a third array to store the Amount of Fuel in each supplement.

  2. Do all of the reading of the input file to fill the array(s), and initialize the car (location, direction, starting amount of fuel), the track, and the fuel supplement information. Put some temporary printf statements in to verify that all of the data has been read correctly.

  3. Create a big empty loop to handle each frame. (You'll fill in the body of the loop a little at a time in the subsequent steps.)

  4. Program the car's movements and have it turn when it finds a wall.

  5. Program the car to turn when it moves onto an oil slick.

  6. Program the car to emit its own oil slicks.

  7. Program the car's fuel consumption, fuel increases when encountering fuel supplements, and termination of the program when out of fuel.

  8. Start keeping track of laps, and make the race end if the car has completed the total number of laps.

  9. Thoroughly check your entire program after finishing it before submitting it. Create several input files testing them all carefully. Make sure that your program works correctly in both ``animation'' mode and ``just-show-the-end'' mode.

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


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


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


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

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

About this document ...

This document was generated using the LaTeX2HTML translator Version 2K.1beta (1.61)

Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999, Ross Moore, Mathematics Department, Macquarie University, Sydney.

The command line arguments were:
latex2html -show_section_numbers -split 0 -no_navigation -no_footnode project4

The translation was initiated by Fawzi Emad on 2003-10-18


Fawzi Emad 2003-10-18

Web Accessibility