Unity,C#,Dictionary,计算球队在一场比赛中的得分
本文关键字:一场 计算 Dictionary Unity | 更新日期: 2023-09-27 17:59:30
好吧,我很难理解这件事,因为我太不舒服了,尽量清楚地解释我的问题是什么。
首先,我为我制作的fps游戏创建了一个评分系统。现在,评分系统使用了一个可复制的Dictionary结构,即Dictionary中有一个Dictionary。
playerScores = new Dictionary<string, Dictionary<string, int> > ();
第一个字典创建了一个用户名列表,第二个字典用于保存4个密钥(击杀、死亡、辅助、团队ID)
所以基本上它的
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支球队,这取决于比赛的安排。
代码中的大多数注释也是为了我在编写代码时理解它。
第一个:
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
的玩家?