Programming in Java
Supervision 3
Foreword If you comment your code, so will I!
Programs might not work the first time!
If any of the following is unclear, please let me know.
Battleships!
Make a two player game, which can be played on one machine or over a network, which is a version of the traditional game of Battleships. If you choose to implement an AI, we can have a competition!
Your task is to try to pull together your knowledge of the java language and the way it works, along with your understanding of how to program, come up with algorithms and solve problems in a logical and clear way, in order to try and make a slightly larger and more satisfying program then perhaps you have in the past.
As this is a first course in software engineering, I have provided the following guidelines (the hard bit of developing a system!) and you need to understand and fill in the gaps if you wish! However, you are encouraged to do the whole thing yourself, if you want to, and my solution is by no means the only one, although I can justify it…!
The only requirement of your implementation is that it conforms to the rules of the game and protocol specified below. This will allow a game to be played, with each player using their favourite and possibly different implementations.
Below are the rules and protocol, also provided in Protocol.java. There then follows a set of “clues” that outline and begin to solve the whole problem, which you can use as much of as you wish.
Files are provided to help you get started as well, including a demo (my implementation) (class files only!) (yes, could you backwards engineer, no you shouldn’t!). The demo implementation client is hard coded to try and connect to the localhost, so you run two instances of the game on one machine to play.
Rules of the Game
1. Each player will decide to become a
server or a client (the later role required the
IP address of a server to be known).
2. Each player connects to another
suitable player
3. Each
player positions their fleet. There can
be any combination of the ships from the static docking array (see below), but
there must be at least 1 Tug.
4. Each
player does not know anything about their opponents fleet, accept their must be
at least one Tug.
5. A starting player is chosen at random
by the server, who informs the client
6. Players take it in turns to try and
fire upon their opponents ships
7. Each
player is obliged to immediately inform the attacker of the damage their attack
has caused. This is the only other
source of information about an opponents fleet.
8. The
first player to fire upon all of their opponent’s ships, thereby destroying the
opposing fleet, is the winner.
9. If
a players fleet if destroyed, this must be included in
the information provided to the attacker.
10. The game ends and can be repeated from
step 1.
Extensions:
·
When
the game ends, the winner could communicate the actual layout of his board to
the other player.
·
The
players could be artificial (ly
"intelligent")
·
The
interface could be textual/graphical/...
Game protocol
A reliable
network communication channel should be used (e.g. TCP/IP)
The level 4
body of all messages should be a sequences of 8-bit
integers (bytes) and take this format:
START_MESSAGE,
message length, Application Body, END_MESSAGE (no commas in the actual message!)
Application
Body = sequence of integers, minimum length = 1, maximum length = 8
N.B. The
body of the ISO OSI layer 4 message != application
level 'Body' used above and below.
"XXXX/XXXX/XXXX" means there are 3 possible values for this
part of the message.
Server:
1.
Initialise server
2.
Listen
for client - get 2-way TCP socket communication channel
3.
LISTENING
4.
Decide
which player is to start
5.
Send
PLAYER message (Body = PLAYER CLIENT/SERVER)
6.
Process
situation if necessary
7.
Enter
ATTACKING/DEFENDING state as appropriate
8.
End
of game - commute and display winner.
Close connection and stop being server.
Client:
1.
Initialise client
2.
Attempt
to connect to server - get 2-way TCP socket communication channel
3.
WAITING
4.
Receive
starting player message (Body = PLAYER CLIENT/SERVER)
5.
Process
situation if necessary
6.
Enter
ATTACKING/DEFENDING state as appropriate
7.
End
of game - commute and display winner.
Close connection and stop being client.
ATTACKING state:
1.
Send
FIRE message (Body = FIRE X-coord Y-coord)
2.
Process
situation if wish
3.
Receive
Intelligence message
(Body = PREVIOUS_COORD/HIT/MISS X-coord Y-coord) or
(Body = SUNK/DESTROYED_FLEET X-coord Y-coord
ship_type minX
maxX minY maxY)
(X/Y-coords are the for the last shot, min/max-X/Y are the coords for the sunken ship)
4.
Process
situation
5.
Go
to DEFENDING/IDLE state
DEFENDING state:
1.
Receive
FIRE message (Body = FIRE X-coord Y-coord)
2.
Process
situation
3.
Send
Intelligence message
(Body = PREVIOUS_COORD/HIT/MISS X-coord Y-coord) or
(Body = SUNK/DESTROYED_FLEET X-coord Y-coord Ship-Type
minX maxX
minY maxY)
4.
Process
situation if necessary
5.
Go
to ATTACKING/IDLE state
The core (attacking/defending section) of the
protocol can also be seen as follows:
Attacker Defender
Send fire message
Receive
fire(d upon) message
Process
this information:
Update
own board
Form
reply to inform attacker of results
Send
reply message
Potentially
end the game or become the attacker
Receive reply message
Process this information:
Update
enemy board
Potentially end the game or become the defender
Protocol Constants
/* Networking
parameters */
PORT = 3333; // Port - get it!!
/* States */
IDLE = 0; // Not playing game - hasn't
started / has ended;
LISTENING =
1; // Server listening for client
to initalise communication
WAITING =
2; //
Client waiting for starting player, having intialise
// communications (setup TCP socket)
ATTACKING =
3; // Sending FIRE message, wait for
intelligence, processing
// intelligence
DEFENDING =
4; // Waiting for FIRE message,
processing situation, reporting
// intelligence
/* Messages */
// Housekeeping
START_MESSAGE
= 5; //
Message header
END_MESSAGE
= 6; //
Message footer
// Turn
PLAYER = 7; // Message
Type: Starting player
CLIENT =
8; //
Clients turn
SERVER =
9; //
Servers turn
// Events
FIRE =
10; //
Message Type: Attack
PREVIOUS_COORD
= 11; // Message Type:
Intelligence - have fired upon this
// location before
MISS = 12; //
Message Type: Intelligence - shot in open water
HIT = 13; //
Message Type: Intelligence - hit a ship (unknown
// type)
SUNK = 14; //
Message Type: Intelligence - hit a ship, ship
// totally destroyed and sunk, type
is indicated
DESTROYED_FLEET
= 15; // Message Type:
Intelligence - last ship is sunk,
// whole fleet destroyed. Type of ship is indicated
// Ship types
TUG = 16; //
Size = 2; Initial quantity = 2;
SUBMARINE =
17; // Size =
3; Initial quantity = 1;
CRUISER =
18; //
Size = 4; Initial quantity = 1;
DESTROYER =
19; // Size =
4; Initial quantity = 1;
AIRCRAFT_CARRIER
= 20; // Size = 5; Initial quantity = 1;
/* Game parameters */
BOARD_SIZE
= 10;
// create set of ships
and their types to use in creating a fleet
dockyard
= new Ship[6];
ship_types
= new int[6];
static
{
dockyard[0]
= new Tug();
dockyard[1]
= new Tug();
dockyard[2]
= new Submarine();
dockyard[3]
= new Cruiser();
dockyard[4]
= new Destroyer();
dockyard[5]
= new AircraftCarrier();
ship_types[0] = Protocol.TUG;
ship_types[1] = Protocol.TUG;
ship_types[2] = Protocol.SUBMARINE;
ship_types[3] = Protocol.CRUISER;
ship_types[4] = Protocol.DESTROYER;
ship_types[5] = Protocol.AIRCRAFT_CARRIER;
}
Proposed implementation
Below is a
UML diagram for my implementation.
Key
Inherits from
Implements
Shares containment
Contains (has only reference)
Depends
A class
A brief
explanation of the diagram / whole program is:
the Protocol class is a state machine, which, when activated, steps though the different stages on the protocol, until it
is stopped by the game ending. When
external operations are required it calls methods from interfaces to interact
with the user, the rest of the game or the network connection. To promote encapsulation, call back functions
for sending and messages were included in this class.
The ConnectionManager class deals with network connection and
sending/receiving of messages
The Renders
provide methods, though inheritance, to interact with the user.
The state
of the game is maintained though the Board, which is made up of different kinds
of Square, some of which contain different types of Ships. There are two boards maintained, one for the
player (the friend one) and one for the opponent (enemy one). The friend board is set up at the beginning
of the game. The enemy game is updated
as the game progresses as the point of the game is to find this out!
The correct
state of the game ensures that the right results are provided by invoking a
“fire” of “render” method on any type of square, through subsumption. For example whether a square as been fired
upon before is important to how is appears to the user.
The Game
class takes care of the rest, which basically consists of the methods that the
Protocol class requires, which aren’t handled by the Connection Manager and
setting up and starting the game.
