Assignment 2009
Assignment 2009
04 41480
Object Oriented Programming
Assignment 2009
Dr M. Spann
In addition, the assignment will involve the development of a client/server system for
handling the communications necessary to support the online game. This is covered in
the appendix although its very similar to code we looked at in the Files and Streams
lecture.
2. Practical work
The assignment involves creating a system which allows 4 players to play the card
game gin rummy across a network. The simplified rules of gin rummy are explained
in Appendix IV.
One of the main tasks of this assignment is to develop a multi-threaded server, and
associated client. Networking in C# is similar to that in Java and is about the easiest
of any programming language. Essentially it involves reading or writing a Socket
which you can regard as a network end point. A simple introduction is given in
Appendix 1.
Server
Client
Player 1
Client
Client
Client
Player 2
Player 3
Player 4
allowing a game to be played interactively (in other words the user plays the hand)
or autonomously (the computer plays the hand). In either case, the decision about
whether a hand is a winning hand is determined by the computer. Thus you will
have to design some simple algorithms to support this functionality. Use pseudocode to express algorithm design in your report.
2. Design a graphical user interface to support the playing of the game. The GUI
should enable each players hand to be displayed and each player to play either
interactively (which will involve user interaction with the playing card images to
select cards to exchange) or automatically (which will involve a simple mouse
click instructing the computer to play the hand). Obviously you will make
extensive use of visual programming techniques to create your GUI.
3. Design the final system involving a server program which enables clients to
connect, plays the card game and communicates the plays to its clients. The
client program will handle the update of its graphical user interface according to
the information it receives from the server. A complication is that a player can play
interactively so that a particular play is generated locally at a client. In this case the
relevant information must be transmitted back to the server and then broadcast
out to all clients so that they can each update their GUIs accordingly. I wouldnt
recommend you attempt a peer to peer communication strategy as its considerably
more complex.
Another issue that you must consider in the design of the final system is the
amount of network traffic produced in the playing of a game and at what stage in
the game information can be passed from server to client. Imagine that this online
card game is being played by registered players for money. Player A should not be
able to cheat and be able to gain access to the hand held by player B either by
examining object values in player As program (for example through the use of a
debugger) or by sniffing network traffic. As a simple example, when the cards
are dealt, only the hand of each player is sent to its appropriate client and not the
hand of the other 3 players. Also the draw deck should only be held at the server
and not at each client. The draw decks top card should only be passed to the
appropriate player when required to be shown face up and is then, as in the actual
card game, visible to all players.
4. Resources
There are a set of playing card images which you can download from my web site
playing card images. The image file names correspond in an obvious way to the
card face value and suit. Also included are a couple of images of the cards back.
All of the images are in gif format and to read the files and store the image into an
Image object, use the static method Image.FromFile(string filename).
5. Assessment
This coursework represents all of the assessment for this module. The assessment
will be based on a submitted formal report as well as my assessment of your
programs functionality. You will be expected to give a demonstration of your
program to me and answer any questions about your program. Each student will be
allocated a 5 minute slot to do this.
3
Appendix I
Client/Server Networking
Questions and Answers
1) What is a client and what is a server?
Server: Sits around waiting for a client to connect.
Client: Connects to a server.
2) How does the client find the server?
Every server has an IP address (every PC in the lab has a different one), and a port
number. The client must know both of these in order to find the server.
3) So what is my IP address?
Type ipconfig in a command window (DOS prompt) and it will tell you.
Alternatively if your client and server are on the same machine you can use the IP
address 127.0.0.1 which means on this machine.
4) What port number should I use?
Any number you like above 1023 and below 65536. Just make sure that your
client and server are both using the same port. Also be aware that you cannot have
two servers listening on the same port.
5) What happens after I connect?
After you connect you use streams to send and receive messages between the client
and the server.
6) So how do I write this in C#?
Have a look at this (client and server) code in the next two appendices.
7) What about if there are multiple clients?
Good question! The above code will only work for a single client - if you read it
you should be able to work out why. You will need a multi-threaded server to
allow multiple simultaneous connections (because you have multiple clients) - you
will need to work out how to do this. Also you will need a multi-threaded client so
that code which talks to the server runs in a separate thread.
8) Exactly what is the sequence of events in the clients connecting to the server?
Its important to be clear about which bit is doing what, and when. Essentially you
start your server and multiple clients (each player runs a client). The clients then
all connect to the server, and the game starts. It might be helpful to consider a
typical sequence of events. We are assuming each client supports a GUI which has
a Connect button, pressed when the client is ready to connect to the server.
Connecting phase
1)
2)
3)
4)
5)
6)
7)
8)
9)
10)
Obviously, once all 4 clients have connected, the server will then enter its Game
phase and the game can then commence. The sequence is exactly the same if all
clients run on the same machine as the server.
9) What data is actually communicated?
The server could send a string indicating that the data being sent to the client was
a particular card drawn from the top of the draw deck. A 7 of hearts could be sent
as the string D7H for example. The D could be the code indicating its the
drawdeck top card. As another example, the client could send a string back to the
server indicating that its corresponding player has selected the card from the top
of the discard deck and exchanged it for a particular card in his hand. The server
would then have to communicate this to all other clients so that they could update
their GUIs accordingly.
10) Is this particularly object oriented?
No! Obviously you could design a protocol which involves simply passing
messages as strings between the client and server programs and each program
interpreting these strings in terms of the current status of the game. However, I
would recommend you make use of the immense power of object serialization (as
discussed in the Files and Streams lecture) to pass serialized objects between the
client and server. Obviously these objects could be individual playing cards, an
array of playing cards representing a players hand or an object representing the
current play (which cards to exchange and where they come from). Its pretty
easy to adapt the client and server programs shown in appendices II and III so
that objects and not strings are communicated (although, as a special case, a
string is an object!)
System;
System.Net;
System.Net.Sockets;
System.IO;
namespace TestServer
{
class MyTcpListener
{
public static void Main()
{
TcpListener server = null;
try
{
// Set the TcpListener on port 13000.
Int32 port = 10;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
Console.WriteLine("Waiting for client to connect");
TcpClient socketForClient = server.AcceptTcpClient();
Console.WriteLine("Connected!");
if (socketForClient.Connected)
{
Console.WriteLine("Client connected");
NetworkStream networkStream =
socketForClient.GetStream();
System.IO.StreamWriter streamWriter =
new System.IO.StreamWriter(networkStream);
System.IO.StreamReader streamReader =
new System.IO.StreamReader(networkStream);
string theString = "Server Message";
streamWriter.WriteLine(theString);
streamWriter.Flush();
theString = streamReader.ReadLine();
Console.WriteLine("Server: " + theString);
streamReader.Close();
networkStream.Close();
streamWriter.Close();
}
socketForClient.Close();
Console.WriteLine("Exiting...");
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}
}
}
System;
System.Net;
System.Net.Sockets;
System.IO;
namespace TestClient
{
public class MyTcpClient
{
static void Main(string[] args)
{
TcpClient socketForServer;
try
{
Int32 port = 10;
socketForServer = new TcpClient("127.0.0.1", port);
}
catch
{
Console.WriteLine("Failed to connect to server at
{0}:999", "127.0.0.1");
return;
}
NetworkStream networkStream =
socketForServer.GetStream();
System.IO.StreamReader streamReader = new
System.IO.StreamReader(networkStream);
System.IO.StreamWriter streamWriter = new
System.IO.StreamWriter(networkStream);
try
{
string outputString;
// read the data from the host and display it
{
outputString = streamReader.ReadLine();
Console.WriteLine("Client: " + outputString);
streamWriter.WriteLine("Client Message");
streamWriter.Flush();
}
}
catch
{
Console.WriteLine("Exception reading from Server");
}
// tidy up
networkStream.Close();
}
}
}
Appendix IV
The rules for a simplified game of gin rummy are as follows.
The game is for 4 players. Each player is dealt 7 cards from the pack. The top card from the
remaining deck is then drawn and placed face up as the first card in the discard pile. Each
player takes it in turns and can either draw the top card in the remaining deck, which is face
down, or the top card from the discard pile which is face up. The objective is to arrange
your 7 cards into one group of 4 and one group of 3 where a group can either be 3 or 4 cards
with the same face values (eg. three 7s or four queens) or a run of cards of the same suit
(eg 2,3,4 and 5 of spades). Normally the ace is taken as a one. The first player who gets to
this stage has won the game. Obviously the key to the game is to judiciously change a card
in your hand with the one drawn from the pack or the discard pile. Also other players can
see the cards you take from the discard pile which may give them a clue as to other cards
that you may need. You may or may not exchange the drawn card with one from your hand
depending on the suitability of the card drawn. In either case, one card is discarded and put
on the discard pile (face up for all the other players to see) so each player is always holding
7 cards. If all of the cards from the deck have been drawn and a player has yet to win, the
discard pile is re-shuffled and placed face down and the game continues.
10
/10
Report Presentation
Cover page
Page numbering
Contents page
Grammar and spelling
Section layout
Figure labelling and clarity
Correct use of references
/20
Program Design
Effective use of classes and object interactions
Discussion of object oriented issues relating to design
Effective use of clear formal or semi formal design diagrams
/20
Program Implementation
Code layout including use of comments
Effective use of dlls
Algorithm efficiency and correctness
Minimization of network traffic
Effective use of object serialization for client server communication
Effective use of multi threading
/30
Program Functionality
No, limited, full or extended operation
Ease of use of the graphical user interface
Useful information displayed during course of game
/10
Testing
Use of a systematic approach to sub system and full system testing
Testing for unexpected user interactions and inputs
Use of verifiable outputs such as screenshots
/10
Conclusions
Discussion of possible design and implementation improvements
Discussion of how well the program meets the specification and if not, why not
Overall summing up of what has been achieved and what has been learnt
11