/*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); } } } }
/*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(); } }