CMSC 106 | Project #5 | Spring 2002 |
In this project you will write a program which uses functions and which reads input until no more data is seen, and develop the program by testing the functions as each one is written.
The program in Project 4 could process more complex game boards by using arrays, but in order to add more features, you will need to implement a number of functions and modify your solution for Project 4 to use them. (It may, however, be easier to program this project from scratch, rather than trying to modify your program from Project 4.)
As you read this section, you may also want to refer to the ``Sample output'' section below.
Your program will now have two different players moving around on the same game board. Each player will continue to move until the end of the input is read.
The differences in your program's input compared to the previous project are described in this section. Other than the details mentioned here, you can assume the input files for project 5 will be the same as the corresponding input files from project 4.
Otherwise, the input will consist of a set of dimensions, game board data, and a list of moves as described in the requirements for Project 4. The program will read and process moves for the players until it reaches the end of the input file.
The differences in your program's processing and output from before are described in this section.
Player X blocked by player Y moving M at r c!
where X is either 'O' or 'P' for the player trying to move, Y is the symbol for the other player, and r and c are the current row and column of the player trying to move.
Also, a box can be blocked from moving by the other player. If this occurs, the program must print the message:
X: Box blocked by player moving M at r c!
where X is the player trying to move, and M, r, and c are as above.
O: Wall moving L at 3 2!
Any other requirements and tasks your program had to perform in Project 4 still apply to this project, even if they are not mentioned above, unless specifically contradicted or modified here.
You are to implement and call at least six functions (other than main). If your program doesn't contain, and call, at least six functions, it will be graded as if it does not work on the primary input - even if that output is correct. You are only required to write six functions to have a ``working'' project. If you write at least six of them (and your output matches the output identified as the primary output), you can receive over 50 of the 100 points. To earn full credit (up to 100 points) on the project, your program must produce the complete output shown and you must implement at least ten functions. Keep in mind that the more of these functions you write, the easier your program will be to test and implement correctly. Each function may be no longer than 30 lines of executable code (not counting declarations, punctuation, or comments).
Some suggestions of possible functions are listed below. Your functions and parameters may be named anything you like and may be in any order you choose. Functions should call the others described where appropriate. You should write and test each function separately, starting with the simpler ones, before implementing those which could depend upon them. As each is completed, you can modify your previous project by replacing code which performs the same task as the new function with a call to it instead.
In many cases it is apparent where each function should be used. For
instance, the print_board
function described performs
processing similar to a fragment of your previous project's code. In this
case, you should turn that code into the body of the
print_board
function, and replace those statements with a call
to the function itself. In a few other cases it may not be immediately
obvious how a function should be used. However, as you write other
functions, you will come across a situation where you need to perform the
processing described by that function, so you can just write and call it at
that point.
You may find other functions which could be written as well.
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, and at most one return
statement may be used
and it must be at the end of any function.
Even if you already know what they are, you may not use any C
language features other than those introduced in Chapters 1 through 9 of
your textbook, plus those presented in lecture while these chapters were
covered. In addition neither the goto
nor the continue
statement may be used, and the break
statement may not be used in any
loop. Your program must contain only one single return
statement at
the end of main
, and may not use the exit()
library function
at all. You must use character constants (i.e., 'A'
), rather than
numeric ASCII values anywhere character values are needed. Lastly, no
global variables may be used. Using C features not in these chapters, or
using global variables, the goto
statement, the exit()
library
function, multiple return
s in any function, 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. Do not put your alias in this comment! In addition, you must have a short 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:
return
statements in any function
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.
Because this project is larger than the previous projects, being able to determine what part of your code is causing an error is much more important. If you need to come to office hours, you will be expected to be able to tell us where the error is, or what you have done to try to locate it. This means having tested your functions, as explained below, so that you know which ones already work for sure. It also means it is absolutely necessary to develop your program in stages so that you are not trying to write and test all of the code at one time.
As discussed in the earlier project assignments, it is very important to
type in only a part of your program at a time and compile and test it, and
verify that it is correct, before going on. For a program with functions,
this means writing only one function at a time. It also means making sure
that function is correct before calling it from your main
function or
another function. The way to determine if it is correct or not is to add
test calls, or temporary statements just for the purpose of testing this
function, to your program. You can add these calls at the beginning of your
main
function. The idea is that, having written a function, you know
what it is supposed to do. Call it, passing some sample values as arguments
and print its return value if it has one, to make sure that it does
whatever it was supposed to do correctly. If it's supposed to change some
values in an array, print the array after the test call to insure the
function did what it should have. You should be able to figure out by hand
what results the function was supposed to produce for the call you wrote.
If it doesn't do what you think it ought, you need to find out why before
going on!
It may be best for you to implement the shorter functions first. After you write and test these you will have more practice with functions, and can go on to write those which are a little more complex.
Another good strategy would be to first implement the functions which duplicate behavior which your Project #4 had, since you should already have a working version for that project. Identify which statements in your Project #4 perform the same task as one of the functions described above and turn those statements into a function, replacing the statements by calls to that function. If your function is correct, you should get the same results as your Project #4 produced before. Only after you have written all such functions should you begin to adjust your program to take into account the ways in which your program is supposed to behave differently than Project #4.
Due to the complexities of reading character input, and the possibility of error which may occur, it's extremely important to carefully print the input values which your program reads to insure it's reading its input data correctly! Often one of the first steps of writing a program can be to simply write the code which reads the input and test it by printing the input values as they are read, because if the input isn't read properly clearly no code after that will be able to work right, even if written correctly.
Here are several common compilation errors having to do with functions produced by the cc compiler on our class machines and what they mean:
(where X is the name of one of your functions, and this error occurs where the function is declared)
This means you called a function before it was defined, or before the compiler saw a prototype for it. The solution is to add a prototype for every function at the top of the program file as soon as it is written, which tells the compiler everything it needs to know about the function so it won't become confused in this way.
The function as written has a different number of parameters than the prototype which you wrote for it.
You wrote a function which you specified should have a return
value, but you didn't include a return
statement anywhere
inside it. If you want the function to return a value, you have
to add a return
statement. Or, if you don't need it to
return anything after all, change its declaration to indicate that
it doesn't return anything.
(where X is the name of a two-dimensional array parameter in one of your function definitions)
You can omit the first subscript of a two-dimensional array
parameter when defining a function, but not the second one. This
error is usually caused by trying to write a two-dimensional
array parameter with two empty sets of brackets, such as
arr[][]
. The number of columns must appear inside the
second set of brackets.
(where X is the name of an array parameter in some function)
This is typically caused by the same problem as the previous error.
Just because a function works correctly for one or two sets of inputs doesn't mean it always works right. You will need to think of a variety of different possibilities for the function's input values (arguments) and make sure it produces the right results in every case. A few minutes spent adding statements which test each function with varying values will be well worth it, if it saves you hours of trying to track down a bug later! Once you are convinced your function works correctly, just delete the test calls, and integrate the new function into the rest of your program by calling it where it is needed.
To illustrate the fact that correct results in one or two cases don't mean a function always works correctly, imagine that for some program you have to write a function which counts how many times a given number is located inside an array containing 10 integers, and returns the result. Its parameters are an array of integers and the value which should be searched for inside the array. Here is the function you wrote:
int count_quantity(int arr[], int num) { /* This function returns the count of how many occurrences of its * second parameter are found in its first array parameter. The * array is assumed to have ten elements. */ int count= 0, index= 1; while (index < 10) { if (arr[index - 1] == num) count++; index++; } return count; }
To test this function you could write a small main
function
containing an array, call the function with that array and a value to search
for inside it, and print the answer which was returned. You can tell what
results it should produce from examining the array. For example:
int main() { int array[10] = {3, 1, 5, 1, 4, 7, 9, 4, 2, 1}; printf("number %d was found %d times\n", 3, count_quantity(array, 3)); printf("number %d was found %d times\n", 4, count_quantity(array, 4)); printf("%d\n", count_quantity(array, 4)); return 0; }
You would see that the first test call returns and prints 1, and there is in fact only one 3 inside the array. The second one prints 2, and there are two 4s in the array. You might conclude that your function was correct, however, this is not the case! Altering the call to search for different values, or adding separate test calls, reveals that the call:
printf("number %d was found %d times\n", 1, count_quantity(array, 1));
would also print 2, however, there are three 1s in the array, therefore 3
should be the correct result printed! The problem is that the last array
element is never examined, since the loop stops immediately when index
reaches 10, and arr[8]
was the last element tested. You could verify
this by adding a debug printf
statement in the loop printing each
array element as it is examined. In this case, changing the loop condition
to ``while (index < 11)
'' would be one way of fixing the problem.
The crucial point is that testing the function by calling it in only a few cases is not sufficient to conclude that it is correct.
If random or unexpected values are printed some of the most common reasons are:
printf
statements to see the values of the array
subscripts which you are using, to see where the error might be
happening.
return
statement at the end of each function (as required above) to pass
back a value which was computed or determined, rather than several
return
statements in different places in the same function.
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:
|
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.
Your project must be electronically submitted by the date above, to aviod 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 ``5'' 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 ``game2.c'', submit would be run as
submit 5 game2.c
.
Assuming the name of the executable version of the program is ``game2.x'', here is a sample execution for one input data set.
Be sure to test your program against a variety of inputs, so you are sure it works in all circumstances!
|
For this project, the primary input consists of the contents of the
file shown above. This file will be posted in your instructor's
class posting account- do not try to type it in yourself!