2015-06-25 4 views
2

ОК, это трудно для меня, чтобы обернуть мою голову вокруг этого, поскольку она так плохо пытается объяснить, насколько я могу, в чем моя проблема.Unity, C#, Словарь, вычисляющий десятки команд в матче

Прежде всего, я создаю систему оценки для игры fps, которую я делаю. теперь прямо сейчас система оценки использует структуру словаря «Дабл», которая имеет словарь в словаре.

playerScores = new Dictionary<string, Dictionary<string, int> >(); 

первый словарь создает список имен пользователей 2-й dictionery используется для хранения 4 ключа (убивает, смерти, помогает, TeamID)

так basicley его

playerScores[username][scoretype][scorevalue] 

прямо сейчас он в настоящее время хранит убийства и смерти игроков, а затем отображает их в лидирующей доске в порядке убывания убийств и группируется в какой команде они находятся, и все работает нормально.

проблема, с которой я сталкиваюсь, пытается определить способ подсчета очков команд для каждой команды. а также выяснить, какая команда имеет самый высокий балл. Я просто наклоняю голову.

это класс, который обрабатывает эти данные (а не код таблицы лидеров, но результат и прочее).

using UnityEngine; 
using System.Collections; 
using System.Collections.Generic; 
using System.Linq; 

public class MyMatchData : MonoBehaviour 
{ 



     Dictionary<string, Dictionary<string, int> > playerScores; 
     int changeCounter = 0; 
     public GameObject scoreBoard; 
     Canvas scoreBoardCan; 
     public float myTeamID = 0f; 
     string playerNameKey = "blank"; 
     float myDeaths = 0f; 
     float myKills = 0f; 




     // Use this for initialization 
     void Start() 
     { 
       scoreBoardCan = scoreBoard.transform.parent.GetComponent<Canvas>(); 





       myDeaths = 0f; 
       myKills = 0f; 
     } 

     void Init() 
     //init is just to make shure that we know playerscores is set b4 some one trys to use it 
     //(when ever some one calls the playerscores first they will call Init()) 
     { 



       if (playerScores != null) { 
         return; 
       }//If the player scores has been set then return out so we dont erase the scores 



       playerScores = new Dictionary<string, Dictionary<string, int> >(); //must tell it that theres a new dictionery else u will get null error 
       //playerScores [playerNameKey] = new Dictionary<string, int>(); // agane must tell it theres a new dictionery because this is the sub dictionery 
       //a new sub dictionerey must be created for evey player. setScore() will create a new sjub dictionerey for a player if one dose not yet exsist. 

     } 

     void Update() 
     { 

       if (Input.GetKeyDown (KeyCode.Tab)) { 
         changeCounter ++; 


         //scoreBoard.SetActive (!scoreBoard.activeSelf); 
         bool scoreBoardCanIsActive = scoreBoardCan.enabled; 
         scoreBoardCan.enabled = !scoreBoardCanIsActive; 
       } 

       if (Input.GetKeyDown (KeyCode.P)) { 

         ChangeScore ("sky", "kills", 1); 
       } 
     } 

     [RPC] 
     public void playerDied (bool wasBot, bool wasKilledBySomeone, string killedBy, string playerName, int playerTeam) 
     { 
       if (PhotonNetwork.isMasterClient) { 
         if (wasBot) { 
           Health hlscBot = GameObject.Find (playerName).GetComponent<Health>(); 
           hlscBot.GetComponent<PhotonView>().RPC ("DeSpawn", PhotonTargets.AllBuffered, "bot", playerName, playerName, playerTeam); 


         } else { 
           //player respawn stuff here 
           Debug.Log ("Host MyMatchData " + playerName); 
           Health hlsc = GameObject.Find (playerName).GetComponent<Health>(); 
           hlsc.GetComponent<PhotonView>().RPC ("DeSpawn", PhotonTargets.AllBuffered, "player", playerName, "null", -1); 

         } 
         //do Score dumping stuff here 
         if (wasKilledBySomeone == true) { 
           ChangeScore (playerName, "deaths", 1);//increase the players deaths 
           ChangeScore (killedBy, "kills", 1);//increase the killers score 
         } else { 
           ChangeScore (playerName, "deaths", 1);//increase the players deaths 
         } 

       } 
     } 

     [RPC] 
     public void firstSpawn (string userName, int teamID) 
     { 

       if (!PhotonNetwork.isMasterClient) { 
         return; 
       } 


       SetScore (userName, "kills", 0); 
       SetScore (userName, "deaths", 0); 
       SetScore (userName, "assists", 0); 
       SetScore (userName, "teamID", teamID); 

     } 

     public int GetScore (string username, string scoreType) 
     { 
       Init(); 
       if (playerScores.ContainsKey (username) == false) { //this just meens if the player name receaved has not reconised then it must not of been set yet 
         return 0;// return the player score as 0 
       } 
       if (playerScores [username].ContainsKey (scoreType) == false) {// at this stage we know the player name is recorded in the dictionery but we need to check if there score has been recorded yet. if not then return 0 
         return 0;// return the player score as 0 
       } 
       return playerScores [username] [scoreType]; 
     } 

     public void SetScore (string username, string scoreType, int value) 
     { 
       Init(); 
       changeCounter ++; 

       if (playerScores.ContainsKey (username) == false) {//if the player has not been recorded in the dictionery yet. 
         playerScores [username] = new Dictionary<string, int>();// Creates a new dictinerey(sub dictionery) for that player. 
       } 

       playerScores [username] [scoreType] = value; // the players score is now the value of value 

     } 

     public void ChangeScore (string username, string scoreType, int amount) 
     { 
       Init(); 
       int currScore = GetScore (username, scoreType); 
       SetScore (username, scoreType, currScore + amount); 
     } 

     public string[] GetPlayerNames() 
     { 
       Init(); 
       return playerScores.Keys.ToArray(); 
     } 

     public string[] GetPlayerNames (string sortingScoreType) 
     { 
       Init(); 

       string[] names = playerScores.Keys.ToArray(); //have to convert to array because keys dont retun a array but a list of string of keys or somthing 

       return names.OrderByDescending (n => GetScore (n, sortingScoreType)).ToArray(); //this needs to beconverted toArray because of the same issue above 
       // ok so the names in this array (names) gets sorted by running the getscore function to find out who has what score. its complacated but works 
       //for that to work you need using System.Linq 

     } 

     public int GetChangeCounter() 
     { 
       return changeCounter; 
     } 


} 

Может ли кто-нибудь помочь мне разработать код для расчета баллов команд?

также может быть 2 команды или 3 или даже 12 команды, это зависит только от того, как настроен матч.

также большинство комментариев в коде для моего понимания кода, когда я его написал.

+4

Как насчет того, чтобы «перевернуть» этот ход мыслей и создать объект «Score», который содержит имя пользователя, убивает, убивает и любые другие данные, которые вы хотите (так что 1 запись), и создавая «Список » для хранения полного набора ? – Melvin

+2

100% одобрить предложение Мелвина. После того, как у вас есть список, LINQ предоставит вам множество методов для сортировки, агрегации и т. Д., Которые будут отвечать всем вашим потребностям с точки зрения показателей команды, высоких результатов и т. Д. –

+0

im allredey использует LINQ, следовательно, использует System.Linq; – skyzzle

ответ

0

Первое:

float myDeaths = 0f; 
float myKills = 0f; 

Если вы не можете достичь половины смерти/смерти четверть или даже 0.1569865 смерти, используйте int.

То, что я сделал бы что-то вроде этого:

internal class Game 
{ 
    public List<Team> Teams { get; set; } 
    public void firstSpawn(string userName, int teamID) 
    { 
     if (!PhotonNetwork.isMasterClient) 
     { 
      return; 
     } 
     Team team; 
     if (Teams.Any(t => t.TeamID == teamID)) 
     { 
      team = Teams.FirstOrDefault(t => t.TeamID == teamID); 
     } 
     else 
     { 
      team = new Team(teamID); 
      Teams.Add(team); 
     }    
     team.Users.Add(new User(userName)); 
    } 


    public void playerDied(bool wasBot, bool wasKilledBySomeone, User killer, User dead, Team playerTeam) 
    { 
     if (PhotonNetwork.isMasterClient) 
     { 
      if (wasBot) 
      { 
       Health hlscBot = GameObject.Find(dead.Name).GetComponent<Health>(); 
       hlscBot.GetComponent<PhotonView>().RPC("DeSpawn", PhotonTargets.AllBuffered, "bot", dead.Name, dead.Name, playerTeam); 
      } 
      else 
      { 
       //player respawn stuff here 
       Debug.Log("Host MyMatchData " + dead.Name); 
       Health hlsc = GameObject.Find(playerName).GetComponent<Health>(); 
       hlsc.GetComponent<PhotonView>().RPC("DeSpawn", PhotonTargets.AllBuffered, "player", dead.Name, "null", -1); 
      } 

      //do Score dumping stuff here 
      dead.Death(); // The dead is dead, no matter if suicide or not 
      if (wasKilledBySomeone) 
      { 
       killer.Kill();//increase the killers score 
      } 
     } 
    } 

    public bool getTheHigherTeamBy(Types type) 
    { 
     return Teams.Any(team => team.getTeamScore(type) == Teams.Max(t => t.getTeamScore(type))); 
    } 
} 

internal class Team 
{ 
    public int TeamID { get; set; } 
    public List<User> Users { get; set; } 


    public Team(int id = 0) 
    { 
     TeamID = id; 
    } 

    public int getTeamScore(Types type) 
    { 
     return Users.Sum(u => u.Score.getScoreFromType(type)); 
    } 
    public string[] getPlayerNames() 
    { 
     return Users.Select(u => u.Name).ToArray(); 
    } 

    public string[] GetPlayerNames(Types sortingScoreType) 
    { 
     return Users.OrderByDescending(u => u.Score.getScoreFromType(sortingScoreType)).Select(u => u.Name).ToArray(); 
    } 

} 

public enum Types 
{ 
    Kill, 
    Death, 
    Assist // Not sure about that one 
} 
internal class Score 
{ 
    private readonly Dictionary<Types, int> points = new Dictionary<Types, int>(); 

    public Score() 
    { 
     // Fill the dictionnary with all the available types 
     foreach (Types type in Enum.GetValues(typeof(Types))) 
     { 
      points.Add(type, 0); 
     } 
    } 
    public int getScoreFromType(Types type) 
    { 
     return points[type]; 
    } 
    public void incrementScoreForType(Types type, int amount = 1) 
    { 
     points[type] += amount; 
    } 

} 

internal class User 
{ 
    public string Name { get; set; } 
    public Score Score { get; set; } 

    public User(string name = "Default") 
    { 
     Name = name; 
     Score = new Score(); 
    } 

    public int getScoreFromType(Types type) 
    { 
     return Score.getScoreFromType(type); 
    } 

    public void changeScore(Types type, int amount) 
    { 
     Score.incrementScoreForType(type, amount); 
    } 

    public void Death() 
    { 
     Score.incrementScoreForType(Types.Death); 
    } 
    public void Kill() 
    { 
     Score.incrementScoreForType(Types.Kill); 
    } 
    public void Assist() 
    { 
     Score.incrementScoreForType(Types.Assist); 
    } 
} 

В общем, лучше работать с классами, чем со строками, которые представляют поддельные объекты: Как вы можете заботиться о двух игроках, названных ARandomName, которые находятся в та же команда?

+0

Спасибо за ваше предложение, но я боюсь, что доза не поможет.Вы в основном просто перезаписали мой код и не дали мне аналог моего вопроса, ведьма «может ли кто-нибудь помочь мне выработать какой-то код для расчета баллов команд», также есть причина, почему словарь имеет в нем имена пользователей, и это потому, что его мультиплеер. хост должен вычислить данные, если каждый из них управляет собственным счетом, тогда баллы будут выходить из синхронизации. – skyzzle

+0

@ user3781715 Я внес много изменений, включая недостающие вопросы из вашего вопроса, лучше? –

 Смежные вопросы

  • Нет связанных вопросов^_^