/// <summary> /// Execution of the Start command based on the given arguments /// and the client that sent it. /// </summary> /// <param name="args"> /// The arguments of this command. /// </param> /// <param name="client"> /// The client which sent this request. /// </param> public void Execute(string[] args, IClient client) { string name = args[0]; int rows = int.Parse(args[1]); int cols = int.Parse(args[2]); ISearchGame game = model.StartGame(name, rows, cols, client); if (!ReferenceEquals(game, null)) { // set condition to start the game game.SetStartWhenTrue((g) => (g.NumOfPlayer >= 2)); // send the client the game when it starts game.TellMeWhenTheGameStarts += () => client.SendResponse(game.ToJSON()); } else { if (!ReferenceEquals(model.GetGameByName(name), null)) { client.SendResponse(@"A game with that name already exists and cannot be replaced at this point."); } else { client.SendResponse(@"You're already a part of a game. Please close that game and try again."); } } }
/// <summary> /// Set "name" to the game name and returns the list of players /// Moves the client and returns the game where the player was moved /// </summary> /// <param name="move"> /// The direction of movement. /// </param> /// <param name="player"> /// The player that sent the Play command. /// </param> /// <return> /// True if the direction is legal,false otherwise. /// </return> public bool Play(Direction move, IClient player, string isExit) { Player p = connector.GetPlayer(player); ISearchGame game = connector.GetGame(p); return(game.MovePlayer(p, move, isExit)); }
/// <summary> /// Execution of the join command based on the given arguments and the client /// that sent this command. /// </summary> /// <param name="args"> /// The arguments of the command. /// </param> /// <param name="client"> /// The client that sent this command. /// </param> public void Execute(string[] args, IClient client) { string name = args[0]; try { if (model.Join(name, client)) { // get the game ISearchGame game = model.GetGameByName(name); // register a notifier to tell the client the game has started game.TellMeWhenTheGameStarts += () => client.SendResponse(game.ToJSON()); // check if we can start the game if (game.CanStart()) { game.MakePlayersNotifyEachOtherAboutTheirMoves((move) => { // create the notification message about the move if (move.ToString().ToLower() == "exit") { //Exit message. return("exit"); } JObject playObj = new JObject { ["Name"] = game.Name, ["Direction"] = move.ToString() }; return(playObj.ToString()); }); try { game.Start(); } catch { client.SendResponse("Failed To join. Something is wrong with the game setting."); } } } else { client.SendResponse(@"Falied to join. You already a part of an existing game. \r\n Please close that game and try again."); } } catch //(System.NullReferenceException) { client.SendResponse("Falied to join. No such game."); } }
/// <summary> /// Remove a client from all of the data in the connector. /// </summary> /// <param name="client"> /// The client that we wish to remove. /// </param> public void RemoveClient(IClient client) { Player p = connector.GetPlayer(client); ISearchGame game = connector.GetGame(p); // remove the clients player from his current game game?.RemovePlayer(p); // delete the clients player from the server connector.DeleteClient(client); // delete the game if the forfeit of the player made it end if (!ReferenceEquals(game, null) && game.HasEnded()) { connector.DeleteGame(game); } }
/// <summary> /// Start the game with the given name,number of rows,number of columns and creator. /// </summary> /// <param name="name"> /// The name of the game. /// </param> /// <param name="rows"> /// Number of rows. /// </param> /// <param name="cols"> /// Number of columns. /// </param> /// <param name="creator"> /// The creator of this game. /// </param> /// <returns> /// The SearchGame that was started. /// </returns> public ISearchGame StartGame(string name, int rows, int cols, IClient creator) { /* * If the game already exists, the user didn't used this command as he should and won't be getting a game. * If we would join the client anyway, we will ignore his requst to "rows", "cols" and maybe he does't want * to play in a different size maze(it's like the difference between requesting a 100 pieces puzzle and * getting a 2000 pieces puzzle). * If a game with that name already exists, We will generate a new game for the client if and only if * he's the only player is the exitising game or, the exisiting game has ended. */ bool toCreate = true; Player p = connector.GetPlayer(creator); ISearchGame g1 = connector.GetGame(p), g = null; if (!ReferenceEquals(null, g1)) { toCreate = g1.HasEnded() || (g1.NumOfPlayer == 1 && g1.GetPlayers().Contains(p)); } if (connector.ContainsGame(name)) { g = connector.GetGame(name); /* g.NumOfPlayer > 0 always because the server know only multiplayer games * replace the existing game if it has ended or the only player in it in the * one who asks to replace it.*/ toCreate &= (g.HasEnded() || (g.NumOfPlayer == 1 && g.GetPlayers().Contains(p))); } if (toCreate) { // delete exitsing games connector.DeleteGame(g); try { connector.DeleteGame(g1); } catch (Exception) { //The game with this name was deleted } // Create a game with this name. ISearchGame game = GenerateNewGame(name, rows, cols); connector.AddGame(game); connector.AddClientToGame(creator, game); game.AddPlayer(connector.GetPlayer(creator)); return(game); } return(null); }
/// <summary> /// Let the given player join the game with the given name. /// </summary> /// <param name="name"> /// The name of the game that the player wishes to join. /// </param> /// <param name="player"> /// The player that sent the Join command. /// </param> /// <returns> /// True if he joined the game, false otherwise. /// </returns> public bool Join(string name, IClient player) { Player myPlayer = connector.GetPlayer(player); ISearchGame game = connector.GetGame(name); // if the player isn't a part of an existing game and the game allows a player to join if (ReferenceEquals(null, connector.GetGame(myPlayer)) && game.CanAPlayerJoin()) { connector.AddClientToGame(myPlayer, name); return(game.AddPlayer(myPlayer)); } /*else if (!ReferenceEquals(null,connector.GetGame(myPlayer))) { * player.SendResponse(@"Deleted game named: " + connector.GetGame(myPlayer).Name + " to generate game: " + name); + connector.DeleteGame(connector.GetGame(myPlayer)); + connector.AddClientToGame(myPlayer, name); + return game.AddPlayer(myPlayer); + }*/ return(false); }
/// <summary> /// Compute the solution of the SearchGame with the given name by using /// the algorithm in the input. /// </summary> /// <param name="name"> /// The name of the SearchGame that will be solved. /// </param> /// <param name="algorithm"> /// The algorithm that we will use. /// </param> /// <returns> /// The solution that was computed. /// </returns> public Solution <Position> ComputeSolution(string name, Algorithm algorithm) { ISearchGame game = GetGameByName(name); if (!ReferenceEquals(game, null)) { // game was created/found string key = game.GetSearchArea(); if (cache.IsSolved(key)) { //Maze already solved, get solution from cache. return(cache.GetSolution(key)); } Solution <Position> solution = numToAlgorithm[algorithm].Search(game.AsSearchable()); //Add solution to the cache. cache.AddSolution(key, solution); return(solution); } return(new Solution <Position>()); }
/// <summary> /// Generate a new game, based on the generate command. /// </summary> /// <param name="name"> /// The name of the game that is going to be generated. /// </param> /// <param name="rows"> /// The number of rows. /// </param> /// <param name="cols"> /// The number of columns. /// </param> /// <returns> /// The SearchGame that will be generated. /// </returns> public ISearchGame GenerateNewGame(string name, int rows, int cols) { //// TODO check this works ///* // * we don't need to save the game in the dictionary because it's a single player game and // * doesn't has to be known by the sever. So when we write the client we'll want/need to // * make sure to do a mapping between inner names and their serialization and send only the // * serialization when the server is needed (for a solution for example). // * see "GetGame" for the only dependecy on/use of the serialization for single player. // */ //return generator.GenerateSearchGame(name, rows, cols); // TODO - also effected the code of GenerateMazeCommand. // No need to know the name of the single player game, but while the // client application is stupid will know it. Afterward we can replace it with the coe above ISearchGame game = generator.GenerateSearchGame(name, rows, cols); connector.AddGame(game); return(game); }
/// <summary> /// Delete a game from the connector. /// </summary> /// <param name="game"> /// Game that will be deleted. /// </param> public void DeleteGame(ISearchGame game) { connector.DeleteGame(game); }
/// <summary> /// Add a player to game entry. /// </summary> /// <param name="player"> /// The player which will be used as a key. /// </param> /// <param name="game"> /// The SearchGame which will be used as a value. /// </param> public void AddClientToGame(Player player, ISearchGame game) { playerToGame[player] = game; }
/// <summary> /// Add an entry that matches a client to his game in our data. /// </summary> /// <param name="client"> /// The client which will be used as a key. /// </param> /// <param name="game"> /// The game which will be used as a value. /// </param> public void AddClientToGame(IClient client, ISearchGame game) { AddClientToGame(GetPlayer(client), game); }
/// <summary> /// Delete the given SearchGame from the Connector's data. /// </summary> /// <param name="game"> /// The game that we wish to remove. /// </param> public void DeleteGame(ISearchGame game) { DeleteGame(game?.Name); }
/// <summary> /// Add a new SearchGame to the Connector's data. /// </summary> /// <param name="game"> /// The game that will be added. /// </param> public void AddGame(ISearchGame game) { nameToGame[game.Name] = game; }