CMSC 106 Project #4 - Gem Drop Spring 2003

Due date: April 10th, 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 play a game called ``Gem Drop''. Various kinds of gems are dropped into a rectangular game board. If 3 or more gems match, either horizontally or vertically, they are removed from the board, and the player gets points based on the value of each gem. The game continues until a column of the game board fills with gems or there is no more input.

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, ``gemdrop.x''.) There is also a graphics version of Gem Drop at:

http://games.real.com/webgames.php?src=010303realhome_1&mode=spnav

Our version doesn't work exactly like this example, but it should give a good idea of what the game is like. (The web version may not work on Netscape, but it should work on Internet Explorer version 5.5 and above.)

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

gemdrop.x
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 ``gemdrop.x'' (except for the animation described later).

To see the program work, type:

   gemdrop.x < primary_input

You should see an animated version of the Gem Drop game!

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:

11 6
Ruby     2
Emerald  1
Topaz    3
Diamond  4
Sapphire 3
Amethyst 7
Gold     5
Jade     8
end
G 3
R 0
T 0
S 0
A 0
D 0
R 5
G 5
* 5
T 3
E 5
S 5
E 5
G 0
J 1
R 2
G 4
G 4
T 3
E 1
D 2
T 3
G 3
R 3

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 describe the dimensions of the game board. (In this case: 11 rows and 6 columns). Important: See the section below for the error checking which the program must do for the game board dimensions.

After the dimensions, the input file includes the list of gem names and point values. Each gem name will be on a separate line, followed by 1 or more blanks and the point value for that gem. The end of the gem list will be shown by the word ``end'' appearing in all lower-case letters on a line by itself. There is no maximum length for the name of a gem, but every gem and its point value will be on a separate line. Since the game moves are given by the first letter of the gem name, you have to store only the first letter of the name in the program, not the entire name. This also means that there may be up to 26 different gem types, one for each upper-case letter.

Following the gem list is the list of game moves. Each game move consists of the letter representing the name of a gem and the number of the column where it is to be placed. Each move will be on a separate line, and the column number will be separated from the gem letter by 1 or more blanks.

Important: Columns are numbered left-to-right, beginning with column 0. Gems are inserted at the top of a column, and they fall until they reach the lowest square in the column which does not already have a gem stored there.

3.1 Error Checking

You must do some error checking to make sure the input is correct.

There is no minimum or maximum number of moves.

If the program finds any error, it must print the appropriate message for the first error found and stop processing the input.

3.2 Playing the Game

The game is played by processing each move until there is no more input, or until a move cannot be made because the column for that move is full. Each move is given by the letter of a gem and a column number (starting with column 0 on the left). If the move is valid, then the gem is placed on the board in the specified column. The gem ``falls'' down the column until it reaches the lowest square in the column which does not already contain a gem. After the gem is placed in the correct location, the program must check to see if there are any matches. A match is defined as any sequence of 3 or more adjacent identical gems, either horizontally or vertically. If there is a match, the matching gems are removed, and their total point value is added to the player's score. If any other gem is located in a column above a gem which is removed, then the remaining gems drop down to fill the empty locations. All matches (both horizontal and vertical) must be removed before any remaining gems are dropped. For example, suppose the game board looks like this:

....
.GG.
GTT. 
EXXT
RXXT

Another topaz (T) drops into the empty spot in column 3 (the fourth column), creating this pattern:

....
.GG.
GTTT
EXXT
RXXT

ALL of the topazes shown in the example would be removed to give this pattern:

....
....
GGG.
EXX.
RXX.

Since 5 topazes are removed, 15 points are added to the score, assuming topaz has a value of 3. Note that the 2 golds (G) have now dropped down to form a match with the existing gold in the lower row. Any matches like this must also be removed BEFORE the next move takes place.

There is a special gem called the blue diamond, shown by the asterisk symbol ('*'). The blue diamond is the ``annihilator''. It removes all gems which match the gem it lands on, and then it disappears. In other words, if the blue diamond lands in a column which contains a topaz immediately below it, then all topaz gems are removed, regardless of where they are located on the board. If the blue diamond lands in an empty column, then it simply annihilates itself. The point values for any gems which are removed by the blue diamond are added to the score. (Because the blue diamond has no point value itself, it does not appear in the list of gem names and point values in the input.)

If a move would try to insert a gem into a full column, then the game is over. Otherwise, each move is processed until there is no more input. When the game is over, the program must print out the final appearance of the board, followed by the message:

Final score p

where p is the total number of points.

3.3 Drawing the Game Board

Each square on the game board is represented by a single character. An empty square contains a period ('.'). Any square containing a gem is represented by the first letter of the gem name ('G' for gold, 'T' for topaz, etc.). The blue diamond is not displayed on the game board, because it disappears as soon as it lands on the board. Your program will draw the game board only at the end of the game. Our program uses ``animation'' to show how the board looks after every move. If you do something like this to help debug your program, make sure you remove the extra statements before you submit your project for grading.

Important: To see the animation from your program on the screen, you will need to print the game board after every move. You will also need to slow the computer down. To accomplish this, insert the following line so that it will run once after each time the board 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. YOU ALSO NEED TO REMOVE ANY EXTRA PRINTING OF THE GAME BOARD BEFORE THE END OF THE GAME.

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

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 game board, you should declare a two dimensional character array that is big enough to hold the biggest possible board (30 by 30). The first line of the input file will tell you how much of that array will be used.

  2. Initialize the game board to be empty.

  3. Create a big loop to handle each move in the game.

  4. Program the insertion of a gem into the game board.

  5. Program the removal of gem matches.

  6. Have the blue diamond annihilate gems matching the one it lands on.

  7. Program the error checking for the input.

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

  9. 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. Of course we will test your program with a wide variety of different input files. We will use boards of different sizes and different combinations of gems.

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 2003-03-21