UMBC CMSC 202
UMBC CMSC 202 CSEE | 202 | current 202

CMSC 202 - Project 4

BattleShip Power Players

Assigned Sunday November 12, 2006
Design Due Sunday November 19, 2006 at 11:59 pm
Program Due Tuesday November 28, 2006 at 11:59pm
Updates
  • Nov 14 - Linking the KLSocket.o library
  • Nov 14 - Error Checking of Server/Client Messages
  • Nov 14 - Project modifications - clarification on system design

Objectives


General Project Description

You have just recently started an internship with GamesCo - a local interactive game company and your supervisor wants you to create an electronic version of the old BattleShip game. You will be responsible for creating the interface that users will see, all of the game logic, a networking component that will allow users to play each other head-to-head, and an artificial-intelligence component that will allow users to play the computer.

Each phase of this project will add on a different component so that by the end of the five phases, you will have a completely operational BattleShips game.

Project Description

Project Modifications

These last two requirements will necessitate using the provided KLSocket class to support running your application as a Server or as a Client. A Server accepts a connection from a Client application and then they exchange messages until one of the chooses to disconnect (for our application the message "WIN" will indicate that both the client and server should end). The Server/Client architecture is a basic component of all of today's internet applications. In order to use this functionality, you will run your application twice, first as a server (leave it running), and then as a client, using a separate terminal window. Once both are running, the two will be able to communicate and play BattleShip against each other.

Above is a graphical depiction of what your system may look like and may give you an idea of what needs to happen. The main system will interact with a single Player "object" (either a Human or a Computer) which has access to one or more boards. Your main system may also have access to one or more boards (this is the dashed line). The key component here is the socket-based communication between two main systems - both of which can begin as the same main, but will have an if/else statement somewhere that will modify the actions slightly.

Functional Description

Your application will function similarly to previous projects, but in addition to having the ability to play two players head-to-head using any mixture of human and computer players, it will also have the ability to play these using your own application or by pitting your application against another student's.

Command Line

The application will have an altered command line to accept the following: Any extra or incorrect command-line parameters must result in an error message accompanied by a "Usage" message, detailing the correct use of the application.

The second command-line argument is no longer optional and must be either HUMAN or COMP, indicating which player should be used for the current execution of your application. This no longer indicates who will go first.

The third argument which will be either SERVER or CLIENT indicates whether the current execution will be the Server or the Client.

The fourth argument is the port number that the server is running on (or will run on if this is the server).

The final argument is only required for the client and is the machine name or IP number that the server is running on.

An example of properly running the applications might be:

Server (always start this first):

Proj3 b1.txt HUMAN SERVER 61038 Client: Proj3 b2.txt COMP CLIENT 61038 linux2.gl.umbc.edu You can pit your application against any other student application by simply running one as a server on some port and the other as a client on the same port. Be careful when choosing a port-number, if you recieve garbage from the port (or unexpected values) - another student in the class might be using the same port number - simply change to another port number. This is a highly unlikely occurance, but as the project deadline nears, you might find it occuring more frequently. There is no need to exchange code, you can both simply run your application from your own account.

Design and Implementation Requirements

Classes

Player Class

You must introduce a Player class that is the base class of an inheritance hierarchy where the Computer and Human classes inherit data and operations from the Player class. You must demonstrate an appropriate use of a virtual method (other than the destructors) and a pure virtual method.

In designing your inheritance hierarchy, ensure that you adhere to the following guidelines:

In order to support Polymorphism and the ability to run your application as either a human or a computer, you will need to ensure that you dynamically allocate all Human and Computer objects using base-type (Player) pointers.

Communication Protocol

The KLSocket class has been provided to you in the form of a pre-compiled .o (object file) and a .h. Another employee in the company wrote this code many years ago, but has since left the company, leaving the code for you to use. Unfortunately, this employee did not document the code well, nor did he/she leave the .cpp files - all you have is the .o. Thankfully he/she left an example (socketApp.cpp) of how to use the class. You must refer to the .h file and the socketApp.cpp file to get an idea of how to use the class.

Server

The server must print a message that says something like:

"Server running on port: 51234"

If the server fails to open the socket, the server must print an error message.

If the server detects a win condition during the game, it must print a message indicating the winner.

If the connection to a client is successful, the server should then go into a loop sending and receiving messages from the client.

Client

The client must print a message that says something like:

"Connecting to host: linux1.gl.umbc.edu" "Connecting on port: 51234"

If the client fails to connect to the server, the client must print an error message.

If the client detects a win condition during the game, it must print a message indicating the winner.

If the connection to a client is successful, the server should then go into a loop sending and receiving messages from the client.

Linking to KLSocket.o Updated!

You should link the KLSocket.o class from the project directory in your makefile instead of submitting the file with your project. You can do this by adding the complete path to the file in the OBJECTS line of your makefile. You can also introduce several macros to simplify this, such as: SOCKET=/afs/umbc.edu/users/d/a/dana3/pub/CMSC202/p4/KLSocket.o OBJECTS= /* some stuff here */ $(SOCKET) That should enable your code to use the KLSocket.o library from the project directory. While you are developing your code, feel free to make a copy and use that as it will enable your application to run slightly faster and probably compile/link a little faster. But, when you turn in your code, do not submit the KLSocket.o file (do submit the KLSocket.h file). Simply add the above lines, that way when you submitrun, it should work and there won't be 150 copies of KLSocket.o in the submission directories.

Warning: Do not add the $(SOCKET) to the 'make clean' or 'make cleanest' targets - this will cause your makefile to attemp to delete something that you don't have write access to and will cause a makefile error/warning.

Messages

Once a connection has been established, the client's first message will be the initial square the client wishes to attack (Ex: A 0). So, the client will always go first in this version of the application. The server will then respond with the message "HIT" or "MISS", appropriately. The server will then send the square it wishes to attack (Ex: A 0). The client will reply with a "HIT" or "MISS". When either the client or the server detects that the final ship has been sunk, instead of sending the "HIT" message, it will send a "WIN" message indicating that the other player has won the game. At that point both the client and server must print a message to the user indicating who has won the game. After recieving a HIT/MISS message, the server and client should reply with "ACK" which acknowledges the receipt of the last message.

An example of a sequence of messages might be:

client: A 0 server: MISS client: ACK server: C 1 client: HIT server: ACK client: B 7 server: HIT client: ACK server: B 1 client: MISS ... server: F 2 client: WIN

Error Checking Messages Updated!

You will want to error-check the messages that you receive from other servers or clients. This is relatively simple as you know what type of message to accept. If your application gets an incorrect message or a square that doesn't exist, it should exit with an error message. We will NOT be testing this, but for your own sanity and your own debugging process, you should implement at least a basic "sanity" check on all messages read from the opponent.

Extra Credit

Stack-based AI: 10 points

We mentioned that using the Queue class is a basic AI technique, but what is it about the Queue that makes it a good strategy? If we use a different data structure can we get a better result?

Using the same strategy as the original Queue class, implement a Stack class (last-in, first-out). You must use the same node-based dynamic data structure that you used for the Queue class. In fact, if you just make some basic modifications to your Queue class, you shouldn't need to generate the whole thing from scratch.

In order to determine which is the best strategy, you should devise a "testing suite" that you can use to examine which strategy is best and in which situations. For example, if the ships are randomly distributed, which is better? If the ships are clustered, which is better? If the ships are in a line, which is better? You should plan on running your tests LOTS of times and you must collect the data and analyze the results. The above questions are NOT a sufficent set of questions to ask/answer in your test suite - you need to think of some other comparisons to make between the two. I would recommend running each test at least 100 times to get a good sample-set of results. Some of the metrics you will want to collect are: how many turns were taken? How many squares were missed? How many squares were hit before a loss? You should also think about what the opponent's strategy should be - should you write an opponent that guesses all the ships correctly? One who never wins? Or should you run the AI against itself? Or should you use a combination of these and test all of them (hint, hint)?

Add a command-line argument to your application that indicates "QUEUE" or "STACK" - which should be used.

To get credit, you must submit a README file along with your code for the Stack class and the automated test suite (add this to your makefile). Your README file must include a description of your testing suite, directions for running and building your testing suite, and a discussion on which performed better and under what conditions. Finally, it must include a discussion about why you believe these are the results - given the data, what conclusions can you make about why one class performs better (or the same) as the other? Why do you think this is happening? What about the BattleShip game makes one class a better choice than the other?

3 Levels of AI difficulty: 10 points

The Queue-based strategy is a basic AI technique used to list a bunch of "good" guesses for the future. There are many other techniques that you can implement that may be more game-specific. You will add three levels of difficulty to allow a variety of users to be challenged by your application. In order to demonstrate the difficult of each of these strategies, like the Stack-based AI component, you must create a test suite that thoroughly tests the different strategies against a variety of board structures (and ship placement strategies) as well as a variety of opponents. Refer to the Stack description for more ideas on what to implement.

Add a command-line argument to your application that indicates "EASY" or "MEDIUM" or "HARD" - which should be used. This must be the same argument as the "STACK"/"QUEUE" argument for the other extra credit

To get credit, you must submit a README file along with your code for your strategies and the automated test suite (add this to your makefile). Your README file must include a description of your testing suite, directions for running and building your testing suite, and a justification of how each represents a "significant" improvement over the last. Use your data analysis to support your claims that each "harder" level is a significant improvement over the last (you should probably see the same improvement from the easy to the medium as you do from medium to hard, for example if the medium strategy takes 5% fewer attempts than the easy, then the hard should take 5% fewer attempts than the easy). Finally, include a discussion on what about your "hard" strategy takes advantage of the structure of the BattleShip game to produce a more intelligent AI component.

BONUS Extra Credit: 0-5 points

As a special treat, for students interesting in competing in an AI tournament, we will run all interested students' work through a series of battles with each other, using a single-elimination, tournament-style structure. Each "game" will consist of 3 rounds, of which the winner (winning 2 of 3) moves up to the next round. The ultimate winner will receive 5 points, second place will recieve 3, and third place will receive 1 point.

In order to participate, you must put a file named "BATTLE" in your submission directory (it can be an empty file, but it must be named as indicated. Your application must print "WINNER" if it won the game or "LOSER" if it lost, on a line all by itself - this must be printed to the 'cout' stream. Any applications that attempt to cheat by printing the wrong message will immediately be disqualified and will receive a zero for the entire project.

General Tips


Project Design Assignment

Your project design document for this project must be named p4design.txt. Be sure to read the
design specification carefully. Submit your design in the usual way: submit cs202 Proj4 p4design.txt Remember - the design is due ONE WEEK before the project. Late designs will not be accepted.

Project Makefile

The "make" utility is used to help control projects with large numbers of files. It consists of targets, rules, and dependencies. You will be learning about make files in lab. For this project, the makefile will be provided for you. You will be responsible for providing makefiles for all future projects. Copy the file makefile from Ms. Wortman's public directory to your directory.

When you want to compile and link your program, simply type the command make or make Proj4 at the Linux prompt. This will compile all necessary .cpp files and create the executable named Proj4.

The make utility can also be used for compiling a single file without linking. For example, to compile Proj4.cpp, type make Proj4.o.

In addition to compiling and linking your files, make can be used for maintaining your directory. Typing make clean will remove any extraneous files in your directory, such as .o files and core files. Typing make cleanest will remove all .o files, core files, Proj4 executable and backup files created by the editor. More information about these commands can be found at the bottom of the makefile.

If you are building your own makefile, you MUST use the /usr/local/bin/g++ compiler to compile and build each file. Do not depend on setting your default compiler to be this compiler, the grader may use a different compiler. There are two compilers on the GL systems, and you are required to use the one located at /usr/local/bin/g++.


Grading

The grade for this project will be broken down as follows. A more detailed breakdown will be provided in the grade form you receive with your project grade.

85% - Correctness

This list may not be comprehensive, but everything on this list will be verified by the graders.

15% - Coding Standards

Your code adheres to the
CMSC 202 coding standards as discussed and reviewed in class.

Project Submission

Steps for Submission

  1. submit all files
  2. submitls to verify they are in the remote directory
  3. submitmake to build your files remotely
  4. submitrun to run your files remotely

Details on Submit Tools.

Remember -- if you make any change to your program, no matter how insignificant it may seem, you should recompile and retest your program before submitting it. Even the smallest typo can cause compiler errors and a reduction in your grade.

Avoid unpleasant surprises!

Be sure to use the submitmake and submitrun utilities provided for you to compile, link and run your program after you've submitted it.


Last Modified: Tuesday, 14-Nov-2006 20:37:45 EST