예제 #1
0
        private void clientComm(object p)
        {
            bool          isready = false;
            int           bytesRead;
            Player        threadPlayer = (Player)p;
            TcpClient     threadClient = threadPlayer.Tcp();
            NetworkStream threadStream = threadPlayer.Stream();

            byte[] buffer = new byte[255];

            byte[] start    = Encoding.GetEncoding("UTF-8").GetBytes("START\n");
            byte[] abnormal = Encoding.GetEncoding("UTF-8").GetBytes("#ABNORMAL\n");
            byte[] gameover = Encoding.GetEncoding("UTF-8").GetBytes("#GAME_OVER\n");
            byte[] illegal  = Encoding.GetEncoding("UTF-8").GetBytes("#ILLEGAL\n");
            byte[] win      = Encoding.GetEncoding("UTF-8").GetBytes("#WIN\n");
            byte[] lose     = Encoding.GetEncoding("UTF-8").GetBytes("#LOSE\n");
            byte[] draw     = Encoding.GetEncoding("UTF-8").GetBytes("#DRAW\n");


            while (true)
            {
                // wait for data to come in
                try
                {
                    bytesRead = threadStream.Read(buffer, 0, 255);
                    string bufferStr = Encoding.UTF8.GetString(buffer);

                    if (!threadPlayer.Opponent().Tcp().Connected)
                    {
                        break;
                    }

                    if (!isready && bufferStr.StartsWith("AGREE"))
                    {
                        threadPlayer.Stream().Write(start, 0, start.Length);
                        isready = true;
                        continue;
                    }

                    // if client clicks cancel
                    if (bytesRead == 0)
                    {
                        if (threadPlayer.Opponent() != null)
                        {
                            if (threadPlayer.Opponent().Tcp().Connected == true)
                            {
                                // tell opponent game ended
                                threadPlayer.Opponent().Stream().Write(abnormal, 0, abnormal.Length);
                            }
                        }
                        break;
                    }
                    // resign
                    else if (bufferStr.StartsWith("resign"))
                    {
                        //tell opponent game ended
                        threadPlayer.Opponent().Stream().Write(gameover, 0, gameover.Length);
                        threadPlayer.Opponent().Stream().Write(win, 0, win.Length);
                        break;
                    }
                    else if (bufferStr.StartsWith("+") || (bufferStr.StartsWith("-"))) // white move
                    {
                        // 処理中に対局が無くなると死ぬ
                        int gameIdx = -1;
                        for (int i = 0; i < games.Count; i++)
                        {
                            if (games[i].Id() == threadPlayer.GameId())
                            {
                                gameIdx = i;
                            }
                        }

                        if (gameIdx == -1)
                        {
                            Console.WriteLine("ERROR");
                            break;
                        }

                        Move move = new Move(bufferStr.Substring(1, 6));

                        // illegal move
                        if ((bufferStr.StartsWith("+") && threadPlayer.MyColor() != Color.WHITE) ||
                            (bufferStr.StartsWith("-") && threadPlayer.MyColor() != Color.BLACK) ||
                            !games[gameIdx].pos.IsLegalMove(move))
                        {
                            threadPlayer.Stream().Write(illegal, 0, illegal.Length);
                            threadPlayer.Stream().Write(lose, 0, lose.Length);
                            //tell opponent game ended
                            threadPlayer.Opponent().Stream().Write(gameover, 0, gameover.Length);
                            threadPlayer.Opponent().Stream().Write(win, 0, win.Length);
                            break;
                        }

                        // OKを送る
                        string mStr = (move.Promote() ? bufferStr.Substring(1, 6) : bufferStr.Substring(1, 5)) + ",OK";
                        byte[] ok   = Encoding.GetEncoding("UTF-8").GetBytes(mStr);
                        threadPlayer.Stream().Write(ok, 0, ok.Length);
                        threadPlayer.Opponent().Stream().Write(ok, 0, ok.Length);

                        // do move
                        if (games[gameIdx].pos.DoMove(move))
                        {
                            threadPlayer.Stream().Write(gameover, 0, gameover.Length);
                            threadPlayer.Stream().Write(win, 0, win.Length);
                            //tell opponent game ended
                            threadPlayer.Opponent().Stream().Write(gameover, 0, gameover.Length);
                            threadPlayer.Opponent().Stream().Write(lose, 0, win.Length);
                            break;
                        }
                    }
                    // chat
                    else
                    {
                        threadPlayer.Opponent().Stream().Write(buffer, 0, bytesRead);
                    }
                }
                // Client closed
                catch (System.IO.IOException)
                {
                    // tell opponent game ended
                    if (threadPlayer.Opponent() != null)
                    {
                        threadPlayer.Opponent().Stream().Write(abnormal, 0, abnormal.Length);
                    }
                    break;
                }
            }
            Console.WriteLine("Player #" + threadPlayer.PlayerId() + " left");
            threadStream.Close();
            threadClient.Close();

            lock (waitingPlayerLock)
            {
                if (waitingPlayer != null)
                {
                    if (waitingPlayer.PlayerId() == threadPlayer.PlayerId())
                    {
                        waitingPlayer = null;
                    }
                }
            }

            // find game from gameID and see if can remove from list
            lock (gamesLock)
            {
                for (int i = 0; i < games.Count; i++)
                {
                    if (games[i].Id() == threadPlayer.GameId())
                    {
                        if (threadPlayer.Opponent() != null)
                        {
                            if (games[i].Player1().Tcp().Connected == false && games[i].Player2().Tcp().Connected == false)
                            {
                                games.RemoveAt(i);
                                break;
                            }
                        }
                    }
                }
            }
        }