Пример #1
0
        /*private static void CheckForDrawByRepitition(SendState a_state);*/

        /// <summary>
        ///     This function will be the main gameplay function
        ///     It will be spawned in a new thread and then it converts the arguments back into the objects they actually are(Socket, Socket, SendState)
        ///     Then in a forever loop it will call select on both sockets
        ///     Whichever responds it will read the gamestate from
        ///     If the board changed between gamestates it will check for draw by repitition
        ///     after updating whose move it is and how much time is left, if no change in board the above will not happen
        ///     the board, chat, and notation will be updated and sent to the other client
        ///     If the game is over an exception will be thrown to take the function out of the forever loop
        /// </summary>
        ///     ChessServer.ChessServer.Play(Object a_whiteSocket, Object a_blackSocket, Object a_initialGameState)
        ///
        ///     NAME
        ///
        ///         ChessServer.ChessServer.Play - function to keep a game going between 2 users
        ///
        ///     SYNOPSIS
        ///
        ///         void Play(Object a_whiteSocket, Object a_blackSocket, Object a_initialGameState);
        ///
        ///     RETURNS
        ///
        ///         void
        ///
        ///     AUTHOR
        ///
        ///         Elliott Barinberg
        ///
        ///     DATE
        ///
        ///         10:22 AM 3/27/2018
        /// <param name="a_whiteSocket">white socket passed as thread parameter</param>
        /// <param name="a_blackSocket">black socket passed as thread parameter</param>
        /// <param name="a_initialGameState">inital SendState passed as thread parameter</param>
        private static void Play(Object a_whiteSocket, Object a_blackSocket, Object a_initialGameState)
        {
            Socket        m_white     = (Socket)a_whiteSocket;
            Socket        m_black     = (Socket)a_blackSocket;
            SendState     m_gameState = (SendState)a_initialGameState;
            Exception     m_endGame   = new Exception("Game over");
            ArrayList     m_checkRead = new ArrayList();
            NetworkStream m_networkStream;
            StreamReader  m_streamReader;
            string        m_message = String.Empty;

            while (true)
            {
                try
                {
                    // reset checkRead
                    m_checkRead.RemoveRange(0, m_checkRead.Count);
                    m_checkRead.Add(m_white);
                    m_checkRead.Add(m_black);
                    if (m_checkRead.Count == 2 && m_white.Connected && m_black.Connected)
                    {
                        Socket.Select(m_checkRead, null, null, -1);
                    }
                    else
                    {
                        m_gameState.ServerError = true;
                        SendClientsGameState(m_gameState, m_white, m_black, null);
                    }

                    for (int i = 0; i < m_checkRead.Count; i++)
                    {
                        m_networkStream = new NetworkStream((Socket)m_checkRead[i]);
                        m_streamReader  = new StreamReader(m_networkStream);
                        m_message       = m_streamReader.ReadLine(); // throws exception if socket disconnected
                        SendState state = new SendState();
                        state = JsonConvert.DeserializeObject <SendState>(m_message);

                        // has the board changed if so the following is the change to be made
                        if (!IsSameBoard(state.Board, m_gameState.Board))
                        {
                            m_gameState.TakenPieces   = state.TakenPieces;
                            m_gameState.CheckMate     = state.CheckMate;
                            m_gameState.StaleMate     = state.StaleMate;
                            m_gameState.GameOver      = state.GameOver;
                            m_gameState.WhiteToMove   = state.WhiteToMove;
                            m_gameState.WhiteTimeLeft = state.WhiteTimeLeft;
                            m_gameState.BlackTimeLeft = state.BlackTimeLeft;
                            m_gameState.AllPositions  = state.AllPositions;
                            CheckForDrawByRepitition(m_gameState);
                            if (m_gameState.DrawByRepitition)
                            {
                                m_gameState.GameOver = true;
                                SendClientsGameState(m_gameState, m_white, m_black, null);
                                throw m_endGame;
                            }
                        }

                        // update the rest and send it out
                        m_gameState.Board    = state.Board;
                        m_gameState.Chat     = state.Chat;
                        m_gameState.Notation = state.Notation;
                        SendClientsGameState(m_gameState, m_white, m_black, (Socket)m_checkRead[i]);
                        if (m_gameState.DrawByRepitition && (Socket)m_checkRead[i] == m_white)
                        {
                            SendClientsGameState(m_gameState, m_white, m_black, m_white);
                            throw m_endGame;
                        }
                        else if (m_gameState.DrawByRepitition)
                        {
                            SendClientsGameState(m_gameState, m_white, m_black, m_black);
                            throw m_endGame;
                        }
                    }
                }
                catch (Exception e)
                {
                    if (e.Message == "Game over")
                    {
                        // game ended naturally
                        break;
                    }
                    else if (e.HResult == -2146232800)
                    {
                        // disconnect
                        m_gameState.GameOver             = true;
                        m_gameState.OpponentDisconnected = true;
                        SendClientsGameState(m_gameState, m_white, m_black, null);
                        break;
                    }
                    else
                    {
                        // should not be
                        Console.WriteLine(e.Message);
                    }
                }
            }
        }
Пример #2
0
        /*private static SendState ConvertGameStateToSendState(GameState a_gameState);*/

        /// <summary>
        ///     This function first converts the game length sent by the client into an index of gamestate in tempgamestate
        ///     Then if there is one client it will wait for the second
        ///     If there is a second client it launches a thread with gamestate and clients in Play
        /// </summary>
        ///     ChessServer.ChessServer.ProcessNewGame(int a_message)
        ///
        ///     NAME
        ///
        ///         ChessServer.ChessServer.ProcessNewGame - converts the client message into the gamestate which it belongs in
        ///
        ///     SYNOPSIS
        ///
        ///         SendState ChessServer.ProcessNewGame(int a_message);
        ///              a_message -> int describing how long of a game to play
        ///
        ///     RETURNS
        ///
        ///         void
        ///
        ///     AUTHOR
        ///
        ///         Elliott Barinberg
        ///
        ///     DATE
        ///
        ///         10:22 AM 3/27/2018
        /// <param name="a_message">int describing how long of a game to play</param>
        private static void ProcessNewGame(int a_message)
        {
            int       m_index = 0;
            SendState state   = new SendState();

            // make index based on specified game length
            switch (a_message)
            {
            case 1:
                m_index = 0;
                break;

            case 5:
                m_index = 1;
                break;

            case 10:
                m_index = 2;
                break;

            case 15:
                m_index = 3;
                break;

            case 30:
                m_index = 4;
                break;

            case 60:
                m_index = 5;
                break;

            case 75:
                m_index = 6;
                break;

            default:
                break;
            }

            // if 2 players already at the index, reset the players
            if (tempStateHolder.ElementAt(m_index).Player2 != null)
            {
                tempStateHolder[m_index].Player1 = null;
                tempStateHolder[m_index].Player2 = null;
            }


            // if the first player is not there generate the gamestate and make them player 1
            if (tempStateHolder.ElementAt(m_index).Player1 == null)
            {
                GenerateNewGamestate(m_index);
                tempStateHolder.ElementAt(m_index).Player1 = myClients.Last();
                tempStateHolder.ElementAt(m_index).WaitingForSecondPlayer = true;
                tempStateHolder.ElementAt(m_index).EndPoint1 = myEndPoints.Last();
                state = ConvertGameStateToSendState(tempStateHolder.ElementAt(m_index));
                SendClientsGameState(state, tempStateHolder.ElementAt(m_index).Player1, null, null);
            }

            // add player 2 and start the thread
            else
            {
                tempStateHolder.ElementAt(m_index).Player2 = myClients.Last();
                tempStateHolder.ElementAt(m_index).WaitingForSecondPlayer = false;
                tempStateHolder.ElementAt(m_index).EndPoint2 = myEndPoints.Last();
                tempStateHolder.ElementAt(m_index).AddToAllPositions(tempStateHolder.ElementAt(m_index).Board);
                state = ConvertGameStateToSendState(tempStateHolder.ElementAt(m_index));
                SendClientsGameState(state, tempStateHolder.ElementAt(m_index).Player1, tempStateHolder.ElementAt(m_index).Player2, null);
                Thread thread = new Thread(() => Play(tempStateHolder[m_index].Player1, tempStateHolder[m_index].Player2, state));
                thread.Start();
            }
        }