我如何确保在井字游戏中通过网络发送的动作不会覆盖之前的动作

How can i ensure that moves sent over a network in a tic tac toe game does not overwrite the previous moves that were made

我正在创建一个具有联网功能的井字游戏。除了一个似乎无法弄清楚的逻辑错误外,一切正常。问题是,在网络上玩游戏时,如果玩家 X 采取行动,那么玩家 O 采取行动,X 之前采取的行动将覆盖我的球员 O 采取的行动。在没有为两个玩家联网的情况下播放 came 时,不会发生这种情况。

这是控制轮到谁并根据轮到谁设置值 X 或 O 的方法。

public MainForm()
    {
        InitializeComponent();
        display();

        network = new Network(this);

        btn = new Button();

    }

private void btnClick(object sender, EventArgs e)
    {

        btn = (Button)sender;

        if (btn.Name == "button1")
        {
            col = 1;
            row = 1;

        }
        else if(btn.Name == "button2"){
            col = 2;
            row = 1;

        }else if(btn.Name == "button3"){
            col = 3;
            row = 1;

        }else if(btn.Name == "button4"){
            col = 1;
            row = 2;

        }else if(btn.Name == "button5"){
            col = 2;
            row = 2;

        }else if(btn.Name == "button6"){
            col = 3;
            row = 2;

        }else if(btn.Name == "button7"){
            col = 1;
            row = 3;

        }else if(btn.Name == "button8"){
            col = 2;
            row = 3;
        }
        else if (btn.Name == "button9")
        {
            col = 3;
            row = 3;
        }


        MakeMove(row, col);

    }

public void MakeMove(int row, int col){

        if ((statusBar.Text == "Connecting...") ||
            (statusBar.Text == "Waiting for connection..."))
            return;


        //_____________________________________________________________________________________________
        //
        // Move network move
        //_____________________________________________________________________________________________
        //wServer = true;

        //MessageBox.Show("wServer is: " + wServer);
        if (((wServer == true) && (turn == true) && (isNetworkPlay == false)) ||
             ((wClient == true) && (turn == false) && (isNetworkPlay == false)))
        {
            //MessageBox.Show("retgr");
            network.SendMove(row, col);
        }
        else
        {
            if (((wServer == true) && (turn == false) && (isNetworkPlay == false)) ||
                ((wClient == true) && (turn == true) && (isNetworkPlay == false)))
                return;
        }

        //checks whos turn it is and sets the button to X or O
        //THIS IS WHERE I AM HAVING TROUBLE
        if (!turn)
        {
            //btn.Text = "X";

            SetControlPropertyValue(btn, "Text", "X");


        }
        else
        {
            //btn.Text = "O";
            SetControlPropertyValue(btn, "Text", "O");

        }

        turn = !turn;
        //btn.Enabled = false;
        SetControlPropertyValue(btn, "Enabled", false);

        turnCount++;

        //checks who wins
        checkWinner();

        display();


        isNetworkPlay = false;
    }![enter image description here][2]

在网络中class我有

  public void SendPacketTCP(Byte[] pDados)
    {
        //_____________________________________________________________________________________________
        //
        // Sends a packet via TCP
        //_____________________________________________________________________________________________

        try
        {
            if (objTicTacToe.wClient == true)
            {
                if (clientSockStream == null)
               {
                    MessageBox.Show("clientSockStream is NULL");
                    return;
               }


                if (clientSockStream.CanWrite)
                {
                    MessageBox.Show("clientSockStream NOT NULL");
                    clientSockStream.Write(pDados, 0, 2);
                    clientSockStream.Flush();
                }
            }
            else
            {
                if (serverSockStream == null)
                {
                    MessageBox.Show("serverSockStream is NULL");
                    return;
                }


                if (serverSockStream.CanWrite)
                {
                    MessageBox.Show("serverSockStream NOT NULL");
                    serverSockStream.Write(pDados, 0, 2);
                    serverSockStream.Flush();
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("An error ocurred: " + ex.Message + "\n" + ex.StackTrace);
            objTicTacToe.disconnect_Click(null, null);
            return;
        }

    }

    public void SendMove(int wRow, int wColumn)
    {
        //_____________________________________________________________________________________________
        //
        // Sends packet that shows move position
        //_____________________________________________________________________________________________


        MessageBox.Show("IN SEND MOVE. ROW is: " + wRow);
        MessageBox.Show("IN SEND MOVE. COL is: " + wColumn);

        byte[] buf = new byte[2];
        buf[0] = byte.Parse(Asc(wRow.ToString()).ToString());
        buf[1] = byte.Parse(Asc(wColumn.ToString()).ToString());

        //MessageBox.Show("IN SEND MOVE. Asc ROW is: " + Asc(wRow.ToString()).ToString());
        //MessageBox.Show("IN SEND MOVE. Asc COL is: " + Asc(wColumn.ToString()).ToString());
        //MessageBox.Show("IN SEND MOVE. BUF INDEX 0 is: " + buf[0]);
        //MessageBox.Show("IN SEND MOVE. BUF INDEX 1: " + buf[1]);

        SendPacketTCP(buf);

    }


  public void ConnectServer(string pIP)
    {

        //_____________________________________________________________________________________________
        //
        // Connect to a game server
        //_____________________________________________________________________________________________

        wServerIP = pIP;
        byte[] buf = new byte[1];

        thread_receive_client = new Thread(new ThreadStart(ThreadReceivingClient));
        thread_receive_client.Start();

    }


private void ThreadReceivingClient()
    {
        //_____________________________________________________________________________________________
        //
        // Thread for receiving packets from server
        //_____________________________________________________________________________________________

        try
        {

            byte[] buf = new byte[512];
            int bytesReceived = 0;

            tcpClient = new TcpClient(wServerIP, SERVERPORT);
            clientSockStream = tcpClient.GetStream();

            objTicTacToe.clearBoard();
            objTicTacToe.setStatusMessage("Connected!");

            wReceivingClient = true;

            while (wReceivingClient)
            {

                //_____________________________________________________________________________________________
                //
                // Thread is blocked until receives data
                //_____________________________________________________________________________________________

                try
                {
                    bytesReceived = clientSockStream.Read(buf, 0, 2);
                }
                catch
                {
                    return;
                }



                //_____________________________________________________________________________________________
                //
                // Processes network packet
                //_____________________________________________________________________________________________

                if (bytesReceived > 0)
                {
                    //_____________________________________________________________________________________________
                    //
                    // Control packet for game restart
                    //_____________________________________________________________________________________________

                    if (buf[0] == byte.Parse(Asc("R").ToString()))
                    {
                        objTicTacToe.clearBoard();
                        continue;
                    }

                    //_____________________________________________________________________________________________
                    //
                    // Packet indicating a game move
                    //_____________________________________________________________________________________________

                    int wRow = int.Parse(Convert.ToChar(buf[0]).ToString());
                    int wColumn = int.Parse(Convert.ToChar(buf[1]).ToString());
                    MessageBox.Show("IN ThreadReceivingClient. row is: " + wRow);
                    MessageBox.Show("IN ThreadReceivingClient. col is: " + wColumn);

                    if ((wRow > 0 && wRow < 4) && (wColumn > 0 && wColumn < 4))
                    {
                        objTicTacToe.isNetworkPlay = true;
                        objTicTacToe.MakeMove(wRow, wColumn);
                        MessageBox.Show("IN ThreadReceivingClient. MOVE WAS SENT");
                    }

                } //if (bytesReceived>0) 

            } //while (wReceivingClient)

        }
        catch (ThreadAbortException) { }
        catch (Exception ex)
        {
            MessageBox.Show("An error ocurred: " + ex.Message + "\n" + ex.StackTrace);
            objTicTacToe.disconnect_Click(null, null);
            return;
        }
    }



 public void StartServer()
    {

        //_____________________________________________________________________________________________
        //
        // Starts game server
        //_____________________________________________________________________________________________

        thread_receive_server = new Thread(new ThreadStart(ThreadReceivingServer));
        thread_receive_server.Start();
    }


    private void ThreadReceivingServer()
    {
        //_____________________________________________________________________________________________
        //
        // Thread for receiving packets from client
        //_____________________________________________________________________________________________



        try
        {
            byte[] buf = new byte[512];
            IPHostEntry localHostEntry = Dns.GetHostByName(Dns.GetHostName());
            int bytesReceived = 0;

            tcpListener = new TcpListener(localHostEntry.AddressList[0], SERVERPORT);

            tcpListener.Start();

            //_____________________________________________________________________________________________
            //
            // Thread is blocked until it gets a connection from client
            //_____________________________________________________________________________________________

            soTcpServer = tcpListener.AcceptSocket();

            serverSockStream = new NetworkStream(soTcpServer);

            objTicTacToe.clearBoard();
            objTicTacToe.setStatusMessage("Connected!");

            wReceivingServer = true;

            //objTicTacToe.turn = false;

            while (wReceivingServer)
            {

                //_____________________________________________________________________________________________
                //
                // Thread is blocked until receives data
                //_____________________________________________________________________________________________

                try
                {
                    bytesReceived = serverSockStream.Read(buf, 0, 2);
                }
                catch
                {
                    return;
                }

                //_____________________________________________________________________________________________
                //
                // Processes network packet
                //_____________________________________________________________________________________________

                if (bytesReceived > 0)
                {

                    //_____________________________________________________________________________________________
                    //
                    // Control packet for game restart
                    //_____________________________________________________________________________________________

                    if (buf[0] == byte.Parse(Asc("R").ToString()))
                    {
                        objTicTacToe.clearBoard();
                        continue;
                    }



                    //_____________________________________________________________________________________________
                    //
                    // Packet indicating a game move
                    //_____________________________________________________________________________________________

                    int wRow = int.Parse(Convert.ToChar(buf[0]).ToString());
                    int wColumn = int.Parse(Convert.ToChar(buf[1]).ToString());
                    MessageBox.Show("IN ThreadReceivingServer. row is: "+ wRow);
                    MessageBox.Show("IN ThreadReceivingServer. col is: " + wColumn);

                    if ((wRow > 0 && wRow < 4) && (wColumn > 0 && wColumn < 4))
                    {
                        objTicTacToe.isNetworkPlay = true;
                        objTicTacToe.MakeMove(wRow, wColumn);
                        MessageBox.Show("IN ThreadReceivingServer. MOVE WAS SENT");
                    }

                }   //if (bytesReceived>0) 

            }   //while (wReceivingServer)
        }
        catch (ThreadAbortException) { }
        catch (Exception ex)
        {
            MessageBox.Show("An error ocurred: " + ex.Message + "\n" + ex.StackTrace);
            objTicTacToe.disconnect_Click(null, null);
            return;
        }
    }

阅读问题下的评论以供参考,以便您理解下面的代码。我认为不需要解释,因为评论已经解释过了。

 //HERE IS THE FIX
        //checks whos turn it is and sets the button to X or O
        if (!turn)
        {

            //SetControlPropertyValue(btn, "Text", "X");
            if (row == 1 && col == 1)
            {
                SetControlPropertyValue(button1, "Text", "X");
                SetControlPropertyValue(button1, "Enabled", false);
            }
            else if (row == 1 && col == 2)
            {
                SetControlPropertyValue(button2, "Text", "X");
                SetControlPropertyValue(button2, "Enabled", false);
            }
            else if (row == 1 && col == 3)
            {
                SetControlPropertyValue(button3, "Text", "X");
                SetControlPropertyValue(button3, "Enabled", false);
            }
            else if (row == 2 && col == 1)
            {
                SetControlPropertyValue(button4, "Text", "X");
                SetControlPropertyValue(button4, "Enabled", false);
            }
            else if (row == 2 && col == 2)
            {
                SetControlPropertyValue(button5, "Text", "X");
                SetControlPropertyValue(button5, "Enabled", false);
            }
            else if (row == 2 && col == 3)
            {
                SetControlPropertyValue(button6, "Text", "X");
                SetControlPropertyValue(button6, "Enabled", false);
            }
            else if (row == 3 && col == 1)
            {
                SetControlPropertyValue(button7, "Text", "X");
                SetControlPropertyValue(button7, "Enabled", false);
            }
            else if (row == 3 && col == 2)
            {
                SetControlPropertyValue(button8, "Text", "X");
                SetControlPropertyValue(button8, "Enabled", false);
            }
            else if (row == 3 && col == 3)
            {
                SetControlPropertyValue(button9, "Text", "X");
                SetControlPropertyValue(button9, "Enabled", false);
            }


        }
        else
        {
            //what i was doing before
            //SetControlPropertyValue(btn, "Text", "O");
            if (row == 1 && col == 1)
            {
                SetControlPropertyValue(button1, "Text", "O");
                SetControlPropertyValue(button1, "Enabled", false);
            }
            else if (row == 1 && col == 2)
            {
                SetControlPropertyValue(button2, "Text", "O");
                SetControlPropertyValue(button2, "Enabled", false);
            }
            else if (row == 1 && col == 3)
            {
                SetControlPropertyValue(button3, "Text", "O");
                SetControlPropertyValue(button3, "Enabled", false);
            }
            else if (row == 2 && col == 1)
            {
                SetControlPropertyValue(button4, "Text", "O");
                SetControlPropertyValue(button4, "Enabled", false);
            }
            else if (row == 2 && col == 2)
            {
                SetControlPropertyValue(button5, "Text", "O");
                SetControlPropertyValue(button5, "Enabled", false);
            }
            else if (row == 2 && col == 3)
            {
                SetControlPropertyValue(button6, "Text", "O");
                SetControlPropertyValue(button6, "Enabled", false);
            }
            else if (row == 3 && col == 1)
            {
                SetControlPropertyValue(button7, "Text", "O");
                SetControlPropertyValue(button7, "Enabled", false);
            }
            else if (row == 3 && col == 2)
            {
                SetControlPropertyValue(button8, "Text", "O");
                SetControlPropertyValue(button8, "Enabled", false);
            }
            else if (row == 3 && col == 3)
            {
                SetControlPropertyValue(button9, "Text", "O");
                SetControlPropertyValue(button9, "Enabled", false);
            }

        }

我删除 btn 引用并直接访问基于 row/col 的按钮。