The fourth (and final!) project this summer “pulls out all the stops” and just gives you a problem to solve in C. No starter code, no design advice, nothing but you and what you learned this summer. I hope you’ll produce a bunch of nice programs. Good luck!
You’re free to work with a partner for this project, but you are not required to partner up. If you choose to work with a partner, don’t try to “split” the work, it won’t be successful. The best approach is to get together in person and to actually write code together. Do that! You’ll get more out of it, maybe even a winning program.
Of course we’re going into a completely different domain yet again! Your job is to implement a variation of the classic Battleships game. The exact game rules as well as the various technical constraints are detailed below. The “special twist” is that your program will play against everybody else’s programs in a tournament. The ranking your program achieves in that contest is part of your score. However, the ranking is not the biggest grade component, so winning “at all costs” is not encouraged. Try to write a correct, reliable, and beautiful program that wins through superior strategy. Don’t get too desperate about being “number 1” as that desire has a tendency to backfire.
It is very important that you stick exactly to the data formats defined below! If your program cannot “play” correctly, it will be disqualified. Completely disqualified, not just disqualified from the tournament. Make sure you process all input and output exactly as specified!!
As always, you’re expected to develop (and submit!) a useful testing
infrastructure for your project.
What exactly that involves depends on how you structure your program,
but however you do your testing, we expect to see coverage analysis
Your goal is to get 100% line coverage for each source file, but it may
not be realistic to achieve that; try to get as close as possible and
defend any missing coverage in your
The game is played on a 10x10 square grid on which each player places his or her ships. The ships are one aircraft carrier of size 5, two battleships of size 4, three cruisers of size 3, and four destroyers of size 2. The ships can be placed anywhere, either vertically or horizontally, as long as each ship fits in its entirety. Ships are allowed to touch, but they are not allowed to intersect.
The game proceeds in turns. Player A announces a square on Player B’s grid to attack; player B checks their (secret) setup and replies whether the attack hit a ship or missed all ships; if it is a hit, and if the hit eliminates the last remaining square of a ship, player B has to announce that a ship was sunk; if the last ship of a player was sunk, the attacking player wins; otherwise the roles are switched and player B attacks a square on player A’s grid; and so on.
Your program will communicate through standard input and standard output. The output of your program will be the input to your opponent’s program and vice versa. It is imperative that you follow the format of messages detailed below exactly as given, any match during which your program fails to adhere to the specified format will be counted as a loss for you.
If your program is started as
./battle that means you’re going second;
if your program is started as
./battle -f or
./battle --first that
means you’re going first.
The program who goes first starts by sending a command to the opponent;
the program who goes second starts by reading a command from the opponent;
after each “message exchange” roles switch unless the game is over.
On Piazza we provide you with a simple tool hacked in Python that can be used to start two Battleship programs and have them talk to each other. The tool is used as follows:
python piper.py programone programtwo
programtwo are the two Battleship programs that
are playing against each other.
You can provide the same name twice, in which case the program will play
As part of starting the programs,
piper will will provide the
programone telling it to go first.
The protocol consists of the following messages (in the form of strings):
FIRE column row MISS HIT SUNK size CONCEDE CHEAT
The game starts with the program going first sending a
FIRE message to
attack the given position.
Positions are encoded as the letters A to J for the column and the numbers
1 to 10 for the row.
For example, the message
FIRE C 10 would attack the square in the third
column and last row.
The response for most attacks will be either
HIT if a ship was hit or
MISS if no ship was hit; note that the program not attacking right
now sends that message, so after sending out
FIRE C 10 you need to wait
for a reply from the other side.
After sending the reply, sides change, and the other side sends, for
FIRE A 7 message; and so on.
If an attack sinks a ship, instead of replying
HIT you must reply
SUNK and give the size of the ship just sunk as an integer; so sinking
the aircraft carrier would lead to
Eventually an attack will sink the last ship, in which case you must reply
CONCEDE instead of
SUNK and the game ends.
The only other way for the game to end “properly” is with a
The program sending that message is accusing the other program of cheating.
CHEAT message has been sent or received, both programs stop.
If the accusation is correct as determined by the judges, the accusing
program wins the round; if the accusation is incorrect, the accused program
wins the round.
All messages have to end with a single linefeed character. All letters are upper-case. There’s exactly one space between the parts of a message.
If you cannot parse the command the other program sends, you should print an error message to standard error and exit with a failing status code. If the other program was at fault, your program wins; if your program was at fault, the other program wins.
If at any time a program “gets stuck” and doesn’t send any of the expected commands within a reasonable amount of time (less than a second for sure), it is disqualified.
Your programs are not allowed to store data persistently (on disk, across the network, etc.) between executions.
If your program implements either cheating or cheat detection
you must talk about this in your
README file to give the judges
fair warning without having to read every single line of your code.
If your program cheats without disclosing that fact in the
file it will be disqualified.
The exact structure of your project (how many
their names, etc.) is up to you. All we expect is a
can be used to build your program when we run
make without a target.
We also expect your executable to be called
Please follow the submission instructions as detailed on
Make sure that your tarball
contains no derived files whatsoever (i.e. no executable files), but
allows building all required derived files.
Also, be sure to include a
Makefile that sets the appropriate
compiler flags and builds all programs by default.
Makefile should also have
test targets as per usual;
test target should run both system and unit tests; ideally it also
runs coverage analysis for you.
Finally, make sure to include your name and email address (for both
partners if this is a paired project) in every file you turn in (well,
in every file for which it makes sense to do so anyway)!
For reference, here is a short explanation of the grading criteria; some of the criteria don’t apply to all problems, and not all of the criteria are used on all assignments.
Packaging refers to the proper organization of the stuff you hand in, following both the guidelines for Deliverables above as well as the general submission instructions for assignments on Piazza.
Style refers to C programming style, including things like consistent indentation, appropriate identifier names, useful comments, suitable documentation, etc. Simple, clean, readable code is what you should be aiming for. Make sure you follow the style guide posted on Piazza!
Design refers to proper modularization (functions, modules, etc.) and an appropriate choice of algorithms and data structures.
Performance refers to how fast/with how little memory your programs can produce the required results compared to other submissions.
Functionality refers to your programs being able to do what they should according to the specification given above; if the specification is ambiguous, ask for clarification! (It also refers to you simply doing the required work, which may not be programming alone.)
If your programs cannot be built you will get no points whatsoever.
If your programs cannot be built without warnings using the required
compiler options given on Piazza we will take off 10%
(except if you document a very good reason).
If your programs cannot be built using
make we will take off 10%.
If your programs fail miserably even once, i.e. terminate with an
exception of any kind or dump core, we will take off 10% (for each such