Click here to Skip to main content
Click here to Skip to main content

Guess My Drawing!

, 9 Jan 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
A Windows Forms application to share a whiteboard with many clients with only one drawer, in a gamy way.

Introduction

This piece of code represents a windows application, it is basically a whiteboard sharing service between users using another code as a server; it consists of a whiteboard that’s shared between many people, one as a drawer and the others as guessers. The drawer is the guy who can draw on the white board, while the guessers are the people who receive the drawings and try to guess it. The first one, the drawer, writes a word describes what he’s drawing, without the guessers knowing it, then he starts to draw and the guessers try to guess the drawing, and the games goes on. The code is coded using C# and data are transferred using UDP.

Clients can log in by choosing any name they like and the server's IP. 

Using the code 

There're two code files, the server and the client one.

The Server:

It's a console application that adds clients to its list, and receives UDP messages from clients analyse them and forward/unforward them to other clients. For example, if a guesser guessed a word, other guessers will be notified of this in a text box, another example is the secret word of the drawing, it will not be forwarded to other clients but kept in the server to be checked with each guess.

The Client: 

This solution has two classes, the windows from class, and the panel class.

The windows form class is called Form1, a silly name! But it kinda meant something as it was my first C# project.

Anyway, the class consists of four methods to capture the clicks of the four buttons in the interface.

And it has two background threads, read() and DrawOnPanel().

First the read() method, it is for reading from the UPD connection after the user joins as a drawer or guesser.

public void read()
{
    Thread t = new Thread(new ThreadStart(delegate
    {
        while(!abortThreads)
        {
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
            byte[] data = {0};
            try
            {
                data = client.Receive(ref remoteEP);
                msg = Encoding.ASCII.GetString(data, 0, data.Length);

            }
            catch (SocketException e)
            {
                abortThreads = true;
            }

            if (msg.StartsWith("draw"))
            {
                msg = msg.Substring(5);
                int xVal = 0, yVal = 0;
                for (int i = 0; msg.Length - 1 > 0; i++)
                {
                    if (msg.Substring(i, 1) == "y")
                    {
                        xVal = Int32.Parse(msg.Substring(0, i));
                        msg = msg.Substring(i + 1);
                        i = 0;
                    }

                    if (msg.Substring(i, 1) == "x")
                    {
                        yVal = Int32.Parse(msg.Substring(0, i));
                        msg = msg.Substring(i + 1);
                        toDraw.Add(new Point(xVal, yVal));
                        i = 0;
                    }
                }
                startDrawing = true;
            }

            else if (msg.StartsWith("accept"))
                SetText(Encoding.ASCII.GetString(data, 0, data.Length));

            else if (msg.StartsWith("gues"))
            {
                if (msg.EndsWith("true"))
                    SetText(msg.Substring(5, msg.Length - 9) + " which was RIGHT! ");
                if (msg.EndsWith("false"))
                    SetText(msg.Substring(5, msg.Length - 10) + " which was WRONG! ");
            }

            else if (msg.StartsWith("quit"))
            {
                msg = "quit";
                data = Encoding.ASCII.GetBytes(msg);
                client.Send(data, data.Length);
                client.Close();
                SetText("The drawer quitted, the game is finished! ");
                abortThreads = true;
                Thread.CurrentThread.Abort();
            }
            else
            {
                if(msg.Length > 5) 
                    SetText(msgList.Text + Environment.NewLine + 
                      Encoding.ASCII.GetString(data, 4, data.Length - 4));
            }
        }
    }));
    t.IsBackground = true;
    t.Start();
}

It basically waits for a message using the receive method for the UDP, and then encode it to a string, msg, and then goes and checks for its content in a series of an if-else statements.

The second thread, DrawOnPanel(), draws whenever there's a draw message, and it's controlled by a boolean variable in the read() thread named startDrawing

private void DrawOnPanel()
{
    hwnd = thePanel.Handle;
    Thread t0 = new Thread(new ThreadStart(delegate
        {
            using (Graphics graphics = Graphics.FromHwnd(hwnd))
            {
                while (!abortThreads)
                {
                    if(startDrawing)
                    if (toDraw.Count > 0)
                    {
                        object holder = toDraw[0];
                        Point now = (Point)holder, previous = (Point)holder;
                        for (int i = 0; i < toDraw.Count; i++)
                        {
                            holder = toDraw[i];
                            now = (Point)holder;
                            graphics.DrawLine(MyPanel.p, now, previous);
                            previous = now;
                        }
                        Console.WriteLine(now + "  last  " + previous);
                        startDrawing = false;
                        toDraw.Clear();
                    }
                }
            }
        }));

    t0.IsBackground = true;
    t0.Start();
} 

.. 

And that's it for the Form1 class, other methods can be found in the source code. 

The panel class is called MyPanel and  it overrides the Panel class.

public class MyPanel : Panel and it overrides three mouse events methods, OnMouseDown()OnMouseUp(), and OnMouseMove() methods.

I'll go through them one by one. 

The first method, OnMouseDown()  has only one line, just to set a boolean value to true to indicate that we can start taking the points and store them in case of a drawer. 

protected override void OnMouseDown(MouseEventArgs e)
{
    mouse_down = true;
}

and the third method, OnMouseMove(), stores the points in an arraylist to be sent. 

protected override void OnMouseMove(MouseEventArgs e)
{
    if (Form1.isDrawer)
    {
        if (last_point.Equals(Point.Empty))
            last_point = new Point(e.X, e.Y);
        if (mouse_down)
        {

            IntPtr hwnd = this.Handle;

            using (Graphics graphics = Graphics.FromHwnd(hwnd))
            {
                Point pMousePos = new Point(e.X, e.Y);
                graphics.DrawLine(p, pMousePos, last_point);
                Console.WriteLine(pMousePos + "  last  " + last_point);
                pointss.Add(pMousePos);
            }
        }
        last_point = new Point(e.X, e.Y);
    }
} 

And the second method, OnMouseUp(), will convert the arraylist into a string and then into bytes and send them via the established UPD connection.

protected override void OnMouseUp(MouseEventArgs e)
{
    mouse_down = false;
    if (Form1.isDrawer)
    {
        string msg = "draw";
        for (int i = 0; i < pointss.Count; i++)
        {
            Point poi = (Point)pointss[i];
            msg += ("x" + poi.X + "y" + poi.Y);
        }
        msg += "x";
        pointss.Clear();
        byte[] data = Encoding.ASCII.GetBytes(msg);
        if (client != null)
            client.Send(data, data.Length);
    }
}

That sums up the main ideas of the tool, any questions about the code are welcomed. 

Points of Interest 

Some things I did in a strange way to get with my tool, you may think they are fun or creative, but eventually they worked stunningly! Here are some: 

- There's no free drawing capability in C#, so my trick was to draw small lines to make it look like a free drawing style.

- I convert the line points in the arraylist into a string to send them via the UDP connection easily.

Drawing on the panel was a headache without calling the Paint() method! I was only drawing in a small portion of the panel, so I used the tricky way in the DrawOnPanel() method that I developed to get rid of the problem, with the help of this question thread in Stackoverflow website:

The Reference.

 

 Conclusion

And by this I conclude my very first online article, if you have any feedback, questions, ideas or any comments, please do speak, it'd be my pleasure to hear all what is going on in your creative minds. 

History 

null; 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Albara Hakami
Software Developer
Saudi Arabia Saudi Arabia
Codes > Bio
Follow on   Twitter

Comments and Discussions

 
GeneralMy vote of 5 PinmemberMember 38528545-Apr-13 10:00 
GeneralMy vote of 5 PinmemberMember 38528545-Apr-13 10:00 
GeneralMy vote of 5 PinmemberAnurag Gandhi13-Jan-13 21:22 
GeneralMy vote of 5 PinmemberWasifa2510-Jan-13 7:53 
GeneralMy vote of 4 PinmemberSavalia Manoj M9-Jan-13 17:37 
GeneralMy vote of 5 PinmemberAhsan Murshed9-Jan-13 17:11 
Generalyou have done efforts on nice subject PinmemberAarti Meswania8-Jan-13 18:37 
GeneralRe: you have done efforts on nice subject PinmemberAlbara Hakami9-Jan-13 9:49 
QuestionMissing reference PinmemberHezek1ah29-Dec-12 15:36 
GeneralMy vote of 5 Pinmembergaga blues27-Dec-12 20:26 
GeneralRe: My vote of 5 PinmemberAlbara Hakami28-Dec-12 0:28 
GeneralMy vote of 5 PinmemberRavi Bhavnani27-Dec-12 15:33 
GeneralRe: My vote of 5 PinmemberAlbara Hakami27-Dec-12 15:36 
GeneralMy vote of 5 PinmemberVenkatesh Mookkan26-Dec-12 17:53 
GeneralRe: My vote of 5 PinmemberAlbara Hakami27-Dec-12 0:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141220.1 | Last Updated 9 Jan 2013
Article Copyright 2012 by Albara Hakami
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid