Network Trilma Game in C#


Game Description:

The Trilma game is one descendants of Halma and sometimes called "Chinese Checkers". Halma was designed by George H. Monks from Boston in 1883 and then becomes board game because of the simple rules. The game [1] has been developed as stand alone using C#, each player has ten checkers which are initially placed in the corners of the board and the aim of the game is to place all checkers in the opposite corner of the board. The following figures demonstrate the Trilma board:



How to play:

Each player uses a different colored set of checkers and places them into a point of the star. The idea of the game is to manipulate your checkers across the board to occupy the star point directly opposite. Never remove a checker after a jump is made. All checkers stay on playing board. The player getting all checkers across first wins.

The game is started by anyone. One can move or Jump in any direction as long as one follows the lines. As in checkers, move only one hole or jump only one marble; although successive jumps are permissible wherever they can be made in any direction.

Client/Server Game:

As most of the network games, both the Trilma server and client have implemented in the same program i.e. the same executable file can run the Trilma as a server or as a client depending on the user choice.

The main form of the game shown in the following figure gives the choice to the user to either start the game as the server by entering the port number and then clicking start, or as a client by providing the IP address and the port number of the Trilma server and then clicking join; in the client case the user will join to play with the already started server.



Implementation Details:

This section is going to describe the modifications that have done to fulfill the aim of the projects by making a network version of Trilma. This section is going to discuss the new classes and methods, Multithreading role, and the communication model and serialization role.

Classes & Methods employ Multithreading:

The following points introduce the main classes and methods and explain the flow of the program:

  • Four new files have been added to the original game files, f_TrilmaFormServer, Host to carry out the server part of the game and f_TrilmaFormClient, Reply to for carrying out the client part of Trilma game.
  • The Host's file contains two classes. The first, Host class, is responsible for accepting the client connection. The second, the Connection Class, is responsible for exchanging the message with client.
  • On the other hand the class called Reply is used by the clients to exchange the messages with the server.
  • The server instantiates an object from the class Host that is waiting to accepts the connection from the client; whenever the connection is established the server starts ListenToClients() method in a new Thread.
  • From the client side the work starts from playGame() method. And after getting connected the NetworkStream will be created and then a new thread for listening form the server will start. In the client side the Listening() method forms the peer of the ListenToClient() method from the server.
  • Finally, as mentioned in the previous points; the client and the server will start exchanging the messages between themselves. Actually each message is an object from the Class called TrilmaMoveSequence. Such an object is responsible for traveling the movement that done by one of the player to the other one over the network. The program depends on this object to show the movements on the game board.
  • The following code shows how the threads have been created on both the client and the server. Of course the server side thread handles the ListenToClient() method, while the client side thread handle Listening() method.

Thread servergame = new Thread( new ThreadStart(this.listenToClient));
Thread clientgame =
new Thread( new ThreadStart(this.listening));

Communication Model and Serialization:

After establishing the connection between Trilma client and server, we have a separate thread running on both of them that thread manages the socket connection encapsulated into network stream to the remote end. Each and every movement by any player will reach the other end as an object of TrilmaMoveSequence; because of that it is required for that object to be serialized at the sender side and deserialized at the receiver side.

The following figure shows this idea



The System.Runtime.Serialization namespace contains classes that can be used for serializing and deserializing objects. Serialization is the process of converting an object or a graph of objects into a linear sequence of bytes for either storage or transmission to another location. Deserialization is the process of taking in stored information and recreating objects from it.

The ISerializable interface provides a way for classes to control their own serialization behavior. Classes in the System.Runtime.Serialization.Formatters namespace control the actual formatting of various data types encapsulated in the serialized objects.

In this project serialization and deserialization process has been done using the Binary formatter provided by C# language without any manual manipulation.

The following part of code shows the methods that sued by the server to send and receive the object:

public void sendObject(int n,Object o)
{
try
{
n = n-1;
StreamWriter sw =
new StreamWriter(ns[n]);
StreamReader sr =
new StreamReader(ns[n]);
ns[n].Flush();
IFormatter sender =
new BinaryFormatter();
sender.Serialize(
this.ns[n],o);
}
catch(Exception er)
{
MessageBox.Show("Problem ... while sending object");
}
}
public TrilmaMoveSequence getObject(int n)
{
TrilmaMoveSequence moves =
new TrilmaMoveSequence();
n = n-1;
IFormatter getter =
new BinaryFormatter();
if(ns[n].DataAvailable)
{
moves = (TrilmaMoveSequence) getter.Deserialize(ns[n]);
ns[n].Flush();
return moves;
}
ns[n].Flush();
return null;
}
}
}

Conclusion and Future Work

While the serializing a simple technique for serializing and transmitting complex data classes, in the real world, on real networks, it is not often this easy because we can not assumed that all of the data to arrive at the receiver for the BinaryFormatter to deserialize the stream into the original class data. As you probably know by now, this is not necessarily what occurs on a real network. So it will be good idea to avoid this case in the program by manually sending the size of the serialized object to make the receiver assure that all the data has been received before deserialization.

Further more the client/server model of the game could be enhanced by making the game support more than tow clients, as there are six sides it is amazing to have six players playing the game over the network.


Similar Articles