
Introduction
The word building game is a well known game all over the world. It is also called as scrabble. In this network-supported game, four players can play the game together sharing the same matrix board. Players can join their corresponding opponents directly by searching. I have used UDP sockets for searching the hosted game and TCP sockets for game processing. This game can be played within the subnet.
This network-supported game is intelligent. A player cannot fool the game by submitting non-English words. This game uses an English word list of around 55903 words. HashTable
of C# is used for this implementation. This data structure is used to store the words. The game performs lookup operation when a player submits the word. New words can be added in wordlist.txt file present in the bin folder. The network infrastructure developed in this game is general purpose. Any game can use this underlying network infrastructure. I have added Howtoplay.pdf file for the instructions to play the game.
Game
In general, this game is a two-player game. Like all other games, these two players will have turns to put a single English alphabet in the given matrix of boxes so that they can form an English word in vertical direction or horizontal direction. Each player will get points equal to the length of the English word they form. Finally, the player with more points will win the game.
Game roles
After hosting or joining the game, the game instance can run one of the following roles:
- Server Role
- Client Role
- Client Inactive Role
Server Role
The game will enter this role once it hosts the game. In this role, the client will act as a server where it will perform three tasks. First, it will listen for clients searching for an active host and reply to them with an acknowledgement message informing them of its presence. Second, it will wait for clients to request for joining the game. Once it receives the join request, it will process this request and it will reply to the sender with an acceptance message that has some needed information. Third, it will initialize and start the game by sending every client a special message notifying them about the game start event along with some other information to initialize the game state. The game will exit this role once it starts the game.

The following code snippet is a thread that will handle this role.
private static void TcpServerRole()
{
ServerListener = new TcpListener(GamePort);
ServerListener.Start();
Socket ss ;
NetworkStream ns ;
StreamReader sr;
StreamWriter sw;
string IncomingMessage ;
while (true)
{
ss = ServerListener.AcceptSocket();
ns = new NetworkStream(ss);
sr = new StreamReader(ns);
sw = new StreamWriter (ns);
IPAddress ip;
IncomingMessage = sr.ReadLine();
if (IncomingMessage=="NumberOfPlayers?")
{
sw.WriteLine(Game.ConnectedPlayers.Count.ToString());
sw.Flush();
}
if (IncomingMessage=="Players?")
{
for ( int i=0 ; i < Game.ConnectedPlayers.Count ; i++)
{
sw.WriteLine(Game.ConnectedPlayers[i].ToString());
sw.Flush();
sw.WriteLine(ClientsAddresses[i].ToString());
sw.Flush();
}
}
if (IncomingMessage.StartsWith("Join"))
{
string PlayerStr = IncomingMessage.Remove(0,4);
ip = ((IPEndPoint)ss.RemoteEndPoint).Address;
sw.WriteLine(Game.ConnectedPlayers.Count);
sw.Flush();
ClientsAddresses.Add(ip);
Game.ConnectedPlayers.Add(Game.ConvertStringToPlayer(PlayerStr));
NewClientUpdateOthers(PlayerStr,ip);
}
ss.Close();
}
}
Client Role
The game will enter this role by two ways: either by starting the game where it will switch from server role, or by receiving the turn message (the turn message notifies the client that it is his/her turn to play). In this role, the client can do two tasks. The first task is to receive the played action from the game and then send it to all other clients to update their internal game state. The second task is to pass the turn to the next player once the current player finishes his/her turn.

Inactive Client Role
This role is the entry role for clients joining the game. The game will also enter this role once it is finished playing and has passed the turn to the next player. In this role, the client will wait for update messages that can be one of the following:
- New player joined the game
- Game has started, initialize your state
- New action
- It is your turn
Once clients join the game, they will wait to receive a new player update message. This message will contain both the new player object along with the IP address, thus enabling the clients to update their player list. Also, clients will need to initialize their game state according to the "Start Game" update message. Once the player list is complete and the game state is initialized, the clients are ready to receive new actions played by the current player in order to update their game states as needed. The client will switch to Client role once it receives "Your Turn" message which indicates the current player has finished playing and it is now your turn to play.

Following code snippet will handle this role:
private static void UnactiveClient()
{
int port = GamePort + Game.MyTurnIndex ;
TcpListener Client = new TcpListener(port);
Client.Start();
TcpClient cs ;
NetworkStream ns ;
StreamReader sr;
string update;
bool MyTurnFlag = true;
while (MyTurnFlag)
{
cs = Client.AcceptTcpClient();
ns = cs.GetStream();
sr = new StreamReader(ns);
update = sr.ReadLine();
string[] updateMsg;
if (update.StartsWith("New Player -->"))
{
update = update.Remove(0,14);
Game.ConnectedPlayers.Add(Game.ConvertStringToPlayer(update));
update = sr.ReadLine();
ClientsAddresses.Add(update);
cs.Close();
}
else if(update.StartsWith("Start Game-->"))
{
update = update.Remove(0,13);
string[] rowcol = update.Split(new char[] {'#'});
int row = Convert.ToInt32(rowcol[0]);
int col = Convert.ToInt32(rowcol[1]);
form.row = row;
form.col = col;
Game.IsGameStarted = true;
cs.Close();
form.Invoke(new displayMethod(form.MatrixDisplay),null);
}
else if ( update.StartsWith("alphabet"))
{
string x1s;
string y1s;
int index;
index = update.IndexOf("-");
update = update.Remove(0,index+1);
index = update.IndexOf("-");
x1s = update.Substring(0,index);
update = update.Remove(0,index+1);
index = update.IndexOf("-");
y1s = update.Substring(0,index);
string update1 = update.Remove(0,index+1);
update1 = update1.Substring(0,1);
index = update.IndexOf("#");
string colour = update.Remove(0,index+1);
colour = colour.TrimEnd('#');
form.DisplayAlphaBet(Convert.ToInt32(x1s),
Convert.ToInt32(y1s), update1,colour);
cs.Close();
}
else if(update.StartsWith("Game Over"))
{
string[] ln = update.Split(new char[] {'#'});
ln[0] = ln[0].Remove(0,9);
MessageBox.Show(ln[0] + " Won the game " + "Score:" + ln[1]);
cs.Close();
}
else if (update.StartsWith("word"))
{
int index;
string Stringtemp1;
string Stringtemp2;
Stringtemp1 = update;
Stringtemp2 = update;
index = Stringtemp1.IndexOf("#");
Stringtemp1 = Stringtemp1.Remove(0,index+1);
index = Stringtemp1.IndexOf("@");
Stringtemp1 = Stringtemp1.Substring(0,index);
int LabelIndex = Convert.ToInt32(Stringtemp1);
index = Stringtemp2.IndexOf("@");
Stringtemp2 = Stringtemp2.Remove(0,index+1);
int LabelScore = Convert.ToInt32(Stringtemp2);
index = 0;
index = update.IndexOf("#");
update = update.Substring(0,index);
index = 0;
ArrayList xs = new ArrayList();
ArrayList ys = new ArrayList();
index = update.IndexOf("-");
update = update.Remove(0,index+1);
index = update.IndexOf("W");
string coordinates = update.Substring(0,index);
update = update.Remove(0,index+1);
index = update.IndexOf("-");
update = update.Remove(0,index+1);
string[] ln = coordinates.Split(new char[] {'-'});
for (int i=0;i < ln.Length;i+=2)
xs.Add(ln[i]);
for (int i=1;i < ln.Length;i+=2)
ys.Add(ln[i]);
form.DisplayColour(xs,ys,update,LabelIndex,LabelScore);
cs.Close();
}
else if (update.StartsWith("TURN"))
{
Game.MyTurn = true;
MyTurnFlag = false;
cs.Close();
Client.Stop();
Game.CurrentPlayerObj = Game.LocalPlayer;
}
else
cs.Close();
}
}
Diagrammatic view
When a user clicks the Host button, three threads will be started. Under Form1.cs class, a thread called as UpdateThread
is started. This thread takes the information from ICommon
interface and updates the information to the user interface form. UdpServerRole
thread listens for UDP broadcast messages and acknowledges with the IP address of the machine where the game is hosted.
TcpServerRole
deals with network messaging. It receives the messages from the network and responds to them and also updates to the interface ICommon
. When a user clicks the Start Game button, TcpServerRole
and UdpServerRole
threads will be stopped and the main user will do some action. The following figures show a nice multi-threading environment.

When a user clicks the Join button, UpdateThread
and ClientThread
start executing. ClientThread
is a general purpose thread. When a user joins the game or loses his turn, this thread will run. It accepts New player, Start Game, Alphabet, Game Over, Word, and Turn messages from the network and updates to the interface ICommon
.

Limitations
- Only four players can play.
- Cannot play if behind a firewall or a NAT.
- Players must agree before playing in order for them to know their IPs.
- Since it is implemented in C#, it will not run on machines without .NET runtime environment.
Conclusion
In this article, a general-purpose network infrastructure is presented. Any game that is similar to the implemented word building game can be plugged into this infrastructure. The article serves as a re-usable component in other developments.
Acknowledgment
This game implementation is a course project for course ICS-571 (Information and Computer Science) namely Client/Server programming, taught by Assistant Professor Nasir Al-Darwish at King Fahad University of Petroleum and Minerals, Kingdom of Saudi Arabia, Dhahran. His email address is darwish@kfupm.edu.sa. From this course, many new concepts have been learned and implemented.
References