Click here to Skip to main content
15,895,606 members
Articles / Programming Languages / C#
Article

Word Building Network Game With Intelligence

Rate me:
Please Sign up or sign in to vote.
3.36/5 (8 votes)
6 Feb 20055 min read 48.8K   2.2K   29  
Word building game using C#.

gamemenu

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.

serverrole

The following code snippet is a thread that will handle this role.

C#
private static void TcpServerRole()
{
    // start a TCP listener
    ServerListener = new TcpListener(GamePort);
    ServerListener.Start();

    //declare some variables
    Socket ss ; //server socket
    NetworkStream ns ;
    StreamReader sr;
    StreamWriter sw;
    string IncomingMessage ;

    while (true)
    {
        // wait for incoming messages
        ss = ServerListener.AcceptSocket(); 

        // create network, reader and writer streams
        ns = new NetworkStream(ss);
        sr = new StreamReader(ns);
        sw = new StreamWriter (ns);

        IPAddress ip; 
        // read the incoming message
        IncomingMessage = sr.ReadLine();

        // ((Type 1))
        // request for total number of connected players
        if (IncomingMessage=="NumberOfPlayers?") 
        {    
            // reply with the number of players
            sw.WriteLine(Game.ConnectedPlayers.Count.ToString());
            sw.Flush(); 
        }

        // ((Type 2))
        // request for all connected players
        if (IncomingMessage=="Players?") 
        {    
            // loop over all connectd players
            for ( int i=0 ; i < Game.ConnectedPlayers.Count ; i++)
            {    
                // send the player object
                sw.WriteLine(Game.ConnectedPlayers[i].ToString());
                sw.Flush();
                // send the player IP Address
                sw.WriteLine(ClientsAddresses[i].ToString());
                sw.Flush();
            }
        }

        // ((Type 3))
        // request to join the game
        if (IncomingMessage.StartsWith("Join"))
        {
            // get the player string by removing un-needed part
            string PlayerStr = IncomingMessage.Remove(0,4);
            // get the client (new player) IP Address
            ip = ((IPEndPoint)ss.RemoteEndPoint).Address;
            // send back the client, the Turn Index
            sw.WriteLine(Game.ConnectedPlayers.Count);
            sw.Flush();

            // add the new player IP Address
            ClientsAddresses.Add(ip);

            // Add the new player to connected players
            Game.ConnectedPlayers.Add(Game.ConvertStringToPlayer(PlayerStr));

            // update all other clients of the new player
            NewClientUpdateOthers(PlayerStr,ip);
        }

        // close the socket, end of request
        ss.Close(); 

    } //end while
}

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.

serverrole

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.

serverrole

Following code snippet will handle this role:

C#
private static void UnactiveClient()
{
    // set the port that I will listen to
    int port = GamePort + Game.MyTurnIndex ;

    // create a TCP Listener 
    TcpListener Client = new TcpListener(port);
    Client.Start(); // start listening

    // define variables
    TcpClient cs ;
    NetworkStream ns ;
    StreamReader sr;
    string update;

    bool MyTurnFlag = true; 

    // loop until you receive your turn
    while (MyTurnFlag)
    {
        // wait for updates
        cs = Client.AcceptTcpClient();  

        // create network & reader streams
        ns = cs.GetStream();
        sr = new StreamReader(ns);

        // read the update
        update = sr.ReadLine();
                
        // string array to deal with the update
        string[] updateMsg; 

        // is it a NEW PLAYER Update Message
        if (update.StartsWith("New Player -->"))
        {
            // remove first part (Length of NewPlayer --> is 14)
            update = update.Remove(0,14); 

            // add the new player object 
            Game.ConnectedPlayers.Add(Game.ConvertStringToPlayer(update));

            // reads the new player IP Address
            update = sr.ReadLine();

            // add the new player IP Address to Address List
            ClientsAddresses.Add(update);

            // close the socket
            cs.Close();

        } 

        // is it a Game Start Update Message
        else if(update.StartsWith("Start Game-->"))
        {
            // A received message can be "Start Game-->5#2
            // Upto 5#2 everything is removed
            // 5 is the number of columns
            // 2 is the number of rows
            //remove unneeded info.
            update = update.Remove(0,13); 

            string[] rowcol = update.Split(new char[] {'#'});
            int row = Convert.ToInt32(rowcol[0]);
            int col = Convert.ToInt32(rowcol[1]);

            // These values will be used by MatrixDisplay function
            form.row = row;
            form.col = col;

            Game.IsGameStarted = true; // game state is started
            // close the client
            cs.Close();
            // display matrix on the user form
            form.Invoke(new displayMethod(form.MatrixDisplay),null);
        }
        else if ( update.StartsWith("alphabet"))
        {
            // Example alphabet-10-10-a#colour#

            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('#');

            // pass the parameters to DisplayAlphaBet method
            // This function displays the alphabet
            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 extraction
            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();
        }

        // is it a Your Turn Message
        else if (update.StartsWith("TURN")) 
        {
            Game.MyTurn = true; // Set my turn
            MyTurnFlag = false; // exit from this state
            cs.Close(); // close the socket
            Client.Stop(); // stop client mode; do not listen for updates

            // Current player is the local Player
            Game.CurrentPlayerObj = Game.LocalPlayer;
        }
        else //ignore other messages
            cs.Close(); 
    } // End of while(true) statement
}

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.

serverrole

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.

serverrole

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

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Saudi Arabia Saudi Arabia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --