/// <summary> /// Code to test the behavior of the Cube object. /// </summary> private static void TestCube() { Console.WriteLine("Starting TestCube()"); // create a cube Cube c = new Cube(20, 30, -2987746, 5318, 5318, false, "bill", 1026.3458); Console.Write("Original cube: "); PrintCubeData(c); Console.WriteLine(); // serialize cube string message = JsonConvert.SerializeObject(c); Console.WriteLine("Cube serialized to: " + message); // deserialize cube Cube r = JsonConvert.DeserializeObject<Cube>(message); Console.Write("Deserialized cube: "); PrintCubeData(r); Console.WriteLine(); Console.WriteLine("TestCube() done"); }
public void removeCube(Cube cube) { //return cubes.Remove(cube); }
///// <summary> ///// Code to test the behavior of the World object. ///// </summary> //private static void TestWorld() //{ // Console.WriteLine("Starting TestWorld()"); // // create world, player id 1234 // World w = new World(100, 100, 1234); // // add cube // Cube c = new Cube(50, 48, -300000, 1234, 1234, false, "Player", 200); // Console.Write("Adding cube: "); // PrintCubeData(c); // Console.WriteLine(); // w.AddCube(c); // PrintWorldCubes(w); // // add same cube with different data // c = new Cube(55, 42, -300000, 1234, 1234, false, "Player", 203); // Console.Write("Adding cube: "); // PrintCubeData(c); // Console.WriteLine(); // w.AddCube(c); // PrintWorldCubes(w); // // add different cube // c = new Cube(3, 15, -400000, 100, 100, true, "", 1); // Console.Write("Adding cube: "); // PrintCubeData(c); // Console.WriteLine(); // w.AddCube(c); // PrintWorldCubes(w); // // add cube of similar mass to another // c = new Cube(75, 18, -200000, 2240, 2240, false, "Enemy", 203); // Console.Write("Adding cube: "); // PrintCubeData(c); // Console.WriteLine(); // w.AddCube(c); // PrintWorldCubes(w); // // kill a cube // c = new Cube(75, 18, -200000, 2240, 2240, false, "Enemy", 0); // Console.Write("Adding cube: "); // PrintCubeData(c); // Console.WriteLine(); // w.AddCube(c); // PrintWorldCubes(w); // // get player cubes // Console.WriteLine("Checking player cubes in current state"); // IEnumerable<Cube> pc = w.GetPlayerCubes(); // PrintPlayerCubes(w); // // add cube for player's team // c = new Cube(75, 18, -200000, 1250, 1234, false, "Player", 200); // Console.Write("Adding cube: "); // PrintCubeData(c); // Console.WriteLine(); // w.AddCube(c); // PrintWorldCubes(w); // // get player cubes again // Console.WriteLine("Checking player cubes in current state"); // pc = w.GetPlayerCubes(); // PrintPlayerCubes(w); // Console.WriteLine("TestWorld() done"); //} /// <summary> /// A helper method to print cube data to a line on console. Prints a line, not a newline. /// </summary> /// <param name="c"></param> private static void PrintCubeData(Cube c) { Console.Write("{X:"+c.X+",Y:"+c.Y+",argb_color:"+c.argb_color+",uid:"+c.uId+",team_id:"+c.teamId+",food:"+c.food+",Name:"+c.Name+",Mass:"+c.Mass+"}"); }
public void update(string values) { Cube rebuilt = JsonConvert.DeserializeObject <Cube>(values); }
public void addCube(Cube cube) { cubes[cube.UID] = cube; }
/// <summary> /// Checks if this cube is overlapping the center of another given cube (parameter) /// </summary> public bool Collides(Cube other) { return((this.left <= other.loc_x && other.loc_x <= this.right) && (this.top <= other.loc_y && other.loc_y <= this.bottom)); }
/// <summary> /// updates the world on all changes /// </summary> private void Update() { List <Cube> eatenCubes = new List <Cube>(); lock (world) { if (foodCount < world.MaxFood) { for (int i = foodCount; i < world.MaxFood; i++) { Cube food = world.CreateFood(); world.cubeList.Add(food.uid, food); foodCount++; SendCube(food); } } if (VirusCount < world.MaxVirus) { for (int i = VirusCount; i < world.MaxVirus; i++) { Cube virus = world.CreateVirus(); world.cubeList.Add(virus.uid, virus); VirusCount++; SendCube(virus); } } foreach (Cube playerCube in PlayerDictionary.Values) { double Player_Top = playerCube.loc_y - (playerCube.Width / 2); double Player_Bottom = playerCube.loc_y + (playerCube.Width / 2); double Player_Left = playerCube.loc_x - (playerCube.Width / 2); double Player_Right = playerCube.loc_x + (playerCube.Width / 2); foreach (Cube cube in world.cubeList.Values) { if ((playerCube.uid != cube.uid)) { if ((Player_Left < cube.loc_x) && (cube.loc_x < Player_Right) && (Player_Top < cube.loc_y) && (cube.loc_y < Player_Bottom)) { //beginning of team split check if ((playerCube.team_id > 0 && playerCube.team_id == cube.team_id)) { //setting the timer to the current time to check split time TimeSpan timerLapse = DateTime.Now - playerCube.trackCube; //if time not up to 5s bounce off each other if (timerLapse.TotalSeconds < 5) { double Cube_Top = cube.loc_y - (cube.Width / 2); double Cube_Bottom = cube.loc_y + (cube.Width / 2); double Cube_Left = cube.loc_x - (cube.Width / 2); double Cube_Right = cube.loc_x + (cube.Width / 2); if (Cube_Top < Player_Bottom) { double result = Player_Bottom - Cube_Top; cube.loc_y += result; if (cube.loc_y + (cube.Width / 2) > world.WorldHeight) { cube.loc_y = world.WorldHeight - (cube.Width / 2); } } else if (Cube_Bottom > Player_Top) { double result = Cube_Bottom - Player_Top; cube.loc_y -= result; if (cube.loc_y - (cube.Width / 2) < 0) { cube.loc_y = 0 + (cube.Width / 2); } } if (Cube_Right > Player_Left) { double result = Cube_Right - Player_Left; cube.loc_x -= result; if (cube.loc_x - (cube.Width / 2) < 0) { cube.loc_x = 0 + (cube.Width / 2); } } else if (Cube_Left < Player_Right) { double result = Player_Right - Cube_Left; cube.loc_x += result; if (cube.loc_x + (cube.Width / 2) > world.WorldWidth) { cube.loc_x = world.WorldWidth - (cube.Width / 2); } } foreach (Cube s in SplitDictionary[cube.team_id]) { if (cube.uid == s.uid) { s.loc_x = cube.loc_x; s.loc_y = cube.loc_y; } } } //merge team cubes after time elapse else { //have to make sure that the 'cube' isn't the main player cube otherwise it will get eaten by one of //it's own splits if (!AllSockets.Values.Contains(cube)) { playerCube.Mass += cube.Mass; cube.Mass = 0; //checks to see if the merged player cube's mass is greater than it's maxMass and if it is changes it if (playerCube.Mass > playerCube.maxMass) { playerCube.maxMass = playerCube.Mass; } //adding splitted cube's stats to player cube's playerCube.countOfEatenCubes += cube.countOfEatenCubes; if (cube.namesOfEatenPlayers.Count > 0) { foreach (string name in cube.namesOfEatenPlayers) { playerCube.namesOfEatenPlayers.Add(name); } } //trying to fix bug where player will merge together and get bigger than world if (playerCube.Width >= world.WorldHeight || playerCube.Width >= world.WorldWidth) { playerCube.Mass = Math.Pow(playerCube.Mass, 0.5); } SplitDictionary[cube.team_id].Remove(cube); eatenCubes.Add(cube); if (SplitDictionary[playerCube.team_id].Count <= 1) { SplitDictionary.Remove(playerCube.team_id); playerCube.team_id = 0; } SendCube(cube); } } } //end of function if two cubes are on the same team //eating food and viruses else { if (cube.IsVirus == true) { VirusHit(playerCube); VirusCount--; } //eating food and other players and checking to make sure the player doesn't get larger than the world. else { playerCube.Mass += cube.Mass; cube.Mass = 0; //checks to see if player's mass now is greater than it's max mass and if it is, changes it if (playerCube.Mass > playerCube.maxMass) { playerCube.maxMass = playerCube.Mass; } //trying to fix bug where the player will grow bigger than the world if (playerCube.Width >= world.WorldHeight || playerCube.Width >= world.WorldWidth) { playerCube.Mass = Math.Pow(playerCube.Mass, 0.5); } //adds dead cube to a list to be taken off of player or world dictionary eatenCubes.Add(cube); //adds 1 to count of cubes eaten for the player playerCube.countOfEatenCubes++; //adds name of eaten player to player's playersEaten list. if (cube.food != true) { playerCube.namesOfEatenPlayers.Add(cube.Name); cube.deathOfCube = DateTime.Now; cube.timeAlive = cube.deathOfCube - cube.startOfCube; //send dead cube to database now? } SendCube(cube); } } } } } //end of going through world with player //handles Attrition if (playerCube.Mass > world.AttritionRate) { //double n = Math.Pow(playerCube.Mass, 1.2) / 10000; double n = Math.Pow(playerCube.Mass, 1.3) / 10000; //Gets rid of more mass to prevent huge cubes that swallow up the world. playerCube.Mass = playerCube.Mass - n; } //Sends player cube to all sockets SendCube(playerCube); } //end of going through playerDictionary //for splitted cubes to help with ranking int splittedCubesTeamID; double totalMassOfPlayer; //hasSet stores splitted cubes and update world foreach (HashSet <Cube> cubeHashSet in SplitDictionary.Values) { totalMassOfPlayer = 0; splittedCubesTeamID = 0; foreach (Cube splittedCube in cubeHashSet) { splittedCubesTeamID = splittedCube.team_id; //keeps track of what team id we are on double splittedCube_Top = splittedCube.loc_y - (splittedCube.Width / 2); double splittedCube_Bottom = splittedCube.loc_y + (splittedCube.Width / 2); double splittedCube_Left = splittedCube.loc_x - (splittedCube.Width / 2); double splittedCube_Right = splittedCube.loc_x + (splittedCube.Width / 2); foreach (Cube cube in world.cubeList.Values) { if ((splittedCube_Left < cube.loc_x) && (cube.loc_x < splittedCube_Right) && (splittedCube_Top < cube.loc_y) && (cube.loc_y < splittedCube_Bottom)) { if (splittedCube.team_id != cube.team_id) { splittedCube.Mass += cube.Mass; cube.Mass = 0; //checks to see if splitted cube's mass is greater than it's maxMass and update maxMass if it is. if (splittedCube.Mass > splittedCube.maxMass) { splittedCube.maxMass = splittedCube.Mass; } //updates count of food eated splittedCube.countOfEatenCubes++; //adds dead cube to list to be taken out of world and/or player list eatenCubes.Add(cube); //player has eaten another player if (cube.IsVirus != true && cube.Name != string.Empty) { splittedCube.namesOfEatenPlayers.Add(cube.Name); cube.deathOfCube = DateTime.Now; cube.timeAlive = cube.deathOfCube - cube.startOfCube; //send cube to database now? } SendCube(cube); } } } SendCube(splittedCube); //keeps track of players total mass; totalMassOfPlayer += splittedCube.Mass; } //sets maxMass of player if player is split up foreach (Cube player in AllSockets.Values) { if (splittedCubesTeamID == player.team_id) { if (totalMassOfPlayer > player.maxMass) { player.maxMass = totalMassOfPlayer; //updates other list with players new max mass value world.cubeList[player.uid].maxMass = player.maxMass; PlayerDictionary[player.uid].maxMass = player.maxMass; } } } } //goes through high list ranking if (AllSockets.Count >= 1) { List <Cube> playerMaxMassList = new List <Cube>(); foreach (Cube player in AllSockets.Values) { playerMaxMassList.Add(player); } if (playerMaxMassList.Count == 1) { //HighestRanks = new Dictionary<int, Cube>(); HighestRanks[1] = playerMaxMassList[0]; world.cubeList[playerMaxMassList[0].uid].highestRank = 1; PlayerDictionary[playerMaxMassList[0].uid].highestRank = 1; } else { //sorts cubes by thier maxMass playerMaxMassList.Sort(delegate(Cube x, Cube y) { return(x.maxMass.CompareTo(y.maxMass)); }); //if list is less than 5, sets number of times it will add a person to the high rank int numOfRanks; if (playerMaxMassList.Count >= 5) { numOfRanks = 5; } else { numOfRanks = playerMaxMassList.Count; } //puts highest maxMasses in the high rank dictionary for (int i = 1; i <= numOfRanks; i++) { HighestRanks[i] = playerMaxMassList[i - 1]; if (playerMaxMassList[playerMaxMassList.Count - i].highestRank < i) { playerMaxMassList[i - 1].highestRank = i; } if (playerMaxMassList[playerMaxMassList.Count - i].Mass != 0) { world.cubeList[playerMaxMassList[playerMaxMassList.Count - i].uid].highestRank = i; PlayerDictionary[playerMaxMassList[playerMaxMassList.Count - i].uid].highestRank = i; } } } } //deletes eaten cubes from player dictionary and world list foreach (Cube deadCube in eatenCubes) { if (PlayerDictionary.ContainsKey(deadCube.uid)) { PlayerDictionary.Remove(deadCube.uid); if (AllSockets.Values.Contains(deadCube)) { Socket temp = new Socket(SocketType.Stream, ProtocolType.Tcp); foreach (KeyValuePair <Socket, Cube> playerCube in AllSockets) { if (playerCube.Value.uid == deadCube.uid) { SendCube(deadCube); //adding dead player to database SQLDatabase.AddPlayerToDatabase(deadCube); //Close socket temp = playerCube.Key; playerCube.Key.Close(); } } AllSockets.Remove(temp); } } if (world.cubeList.ContainsKey(deadCube.uid)) { if (deadCube.food == true) { foodCount--; } world.cubeList.Remove(deadCube.uid); } } } }
/// <summary> /// Handles every request from the client /// </summary> /// <param name="state"></param> public void Handle_Data_from_Client(PreservedState state) { if (NetworkingCode.IsConnected(state.State_Socket)) { int MessageEnd; lock (world) { //getting message from the client and desecting the message to respond accordingly while ((MessageEnd = state.data.ToString().IndexOf('\n')) >= 0) { //message recived string message = state.data.ToString().Substring(0, MessageEnd); state.data.Remove(0, MessageEnd + 1); string[] positionArray = message.Split(' '); string xpos = positionArray[1]; string ypos = positionArray[2]; //geting mouse location xpos = xpos.Remove(xpos.Length - 1); ypos = ypos.Remove(ypos.Length - 1); double mouse_x; double mouse_y; bool Double_x = double.TryParse(xpos, out mouse_x); bool Double_y = double.TryParse(ypos, out mouse_y); mouseLocX = mouse_x; mouseLocY = mouse_y; Cube Updated_player = AllSockets[state.State_Socket]; //handles move requests if (message.Substring(1, 4) == "move") { //will decrease the speed as the mass gets bigger, speed starts at 50 double playerSpeed = 1000 / (Updated_player.Mass * 0.5); //double playerSpeed = 1; if (!(Updated_player.team_id == 0)) { foreach (Cube SplitCubes in SplitDictionary[Updated_player.team_id]) { MoveCube(mouse_x, mouse_y, SplitCubes, playerSpeed); } } else { MoveCube(mouse_x, mouse_y, Updated_player, playerSpeed); AllSockets[state.State_Socket] = Updated_player; } } //handling split request else if (message.Substring(1, 5) == "split") { //loop through to see get split 20 times if (splitCount > world.MaxSplit) { splitCount = 0; } else { //splitting and ensuring team id is assigned splitCount++; if ((Updated_player.Mass > world.MinSplitMass) && splitCount <= world.MaxSplit) { if (Updated_player.team_id == 0) { TeamIDCount++; Updated_player.team_id = TeamIDCount; Updated_player.Mass = Updated_player.Mass / 2; Cube SplittedCube = world.Split(Updated_player); SplitTheCube(mouse_x, mouse_y, SplittedCube); SplitDictionary.Add(Updated_player.team_id, new HashSet <Cube>() { SplittedCube, Updated_player }); } //else if player already splitted else { HashSet <Cube> NewSplitCubes = new HashSet <Cube>(); foreach (Cube OldCube in SplitDictionary[Updated_player.team_id]) { OldCube.Mass = OldCube.Mass / 2; Cube SplittedCube = world.Split(OldCube); SplitTheCube(mouse_x, mouse_y, SplittedCube); NewSplitCubes.Add(SplittedCube); NewSplitCubes.Add(OldCube); } SplitDictionary[Updated_player.team_id] = NewSplitCubes; } // end else } //end if } //end else } //end if } // end while } //end lock NetworkingCode.i_want_more_data(state); } else { //Removes socket from list if no information is coming in lock (world) { PlayerDictionary.Remove(AllSockets[state.State_Socket].uid); world.cubeList.Remove(AllSockets[state.State_Socket].uid); if (AllSockets[state.State_Socket].team_id != 0) { SplitDictionary.Remove(AllSockets[state.State_Socket].team_id); } //adding dead player to database SQLDatabase.AddPlayerToDatabase(AllSockets[state.State_Socket]); AllSockets.Remove(state.State_Socket); if (AllSockets.Count == 0) { //Awaiting Network client connections NetworkingCode.Server_Awaiting_Client_Loop(Handle_New_Client_Connections, 11000); } } } }
/// <summary> /// The second and final callback function to be called upon receiving data from the game server. /// Here we convert a string containing information for cubes into Cube objects. We process these /// cubes into our world and then ask the server for more cube strings. /// </summary> /// <param name="state"></param> private void processReceivedData(PreservedState state) { // Pull out the string containing cube info from the state parameter String stringFromServer = state.strBuilder.ToString(); if (stringFromServer.Length > 0) { // Cubes are divided by newline characters in the string String[] cubes = stringFromServer.Split('\n'); String lastCube = cubes[cubes.Length - 1]; // if the last string received from the server ended with a partial cube, we need to // prepend this to the first cube in the current batch of cubes if (partiallyReceivedCube != "") { cubes[0] = partiallyReceivedCube + cubes[0]; partiallyReceivedCube = ""; } // if the info of the last cube in the message was incomplete. if (lastCube != "") { // save away the partial cube info partiallyReceivedCube = lastCube; } // Remove the last element of the array. If the last cube was incomplete, // it's safe to delete the last element because we already saved. If the last cube was // complete, it's still safe to delete the last element because it will contain an empty string cubes = cubes.Take(cubes.Length - 1).ToArray(); // Must lock because the world object is being used in the Paint method above lock (world) { // Loop through string looking for all \n // Pull each \n terminated String and convert to Cube foreach (String item in cubes) { Cube cube = JsonConvert.DeserializeObject <Cube>(item); // The first cube we receive is the player's cube if (world.Cubes.Count == 0) { // The team_id is used to identify all cubes belonging to the player team_id = cube.uid; // For the view port scaling, we want to keep track of the main player cube mainPlayerCubeId = cube.uid; } if (cube.uid == mainPlayerCubeId) { mainPlayerCubeWidth = cube.Width; // If the main player's cube has 0 mass, we're dead. The server smartly // sets the main player cube to another player cube if the main player // cube dies after a split but other player cube(s) remain. if (cube.Mass == 0) { GameOver = true; } } // If this cube hasn't been added to the world yet, add it. world.AddOrUpdateCube(cube); } } // Clear out the state's stringBuilder for the next incoming message state.strBuilder.Clear(); // Request a "move" command from the server sendMoveOrSplit("Move"); // Ask the server for more cube data Network.i_want_more_data(state); } }
private void NetworkManager_PacketListener(string[] chunks) { foreach (var bCube in chunks.Select(Cube.FromJson)) { _numberOfPacketsReceived++; lock (_world) { if (bCube.IsFood) { _world.UpdateFoodCube(bCube); // If a food cube packet is sent again, it means remove it // } else { _world.UpdatePlayerCube(bCube); } } if (_myCube == null) { continue; } if (_myCube.Uid == bCube.Uid) { _myCube = bCube; } lock (_teamCubes) { if (_myCube.TeamId != bCube.TeamId || bCube.TeamId == 0) { continue; } var index = _teamCubes.FindIndex(cube => cube.Uid == bCube.Uid); if (!bCube.IsDead) { if (index == -1) { _teamCubes.Add(bCube); } else { _teamCubes[index] = bCube; } } else { if (index != -1) { _teamCubes.RemoveAll(cube => cube.Uid == bCube.Uid); } } } } if (_myCube?.IsDead ?? false) { MyCubeDied(); } }