【问题标题】:Best way to store 3 pieces of data as a single entry将 3 条数据存储为单个条目的最佳方法
【发布时间】:2011-02-02 07:36:08
【问题描述】:

对于游戏服务器,我想在玩家击杀时记录详细信息,存储它,然后每隔一段时间更新到 sql 数据库。

我现在感兴趣的部分是存储击杀信息的最佳方法。 我想在更新时传递给 sql server 的是 {PlayerName, Kills, Deaths},其中杀戮和死亡是更新期间的总和。

所以我假设我会按照以下方式构建一个列表 {鲍勃, 1, 0} {坦率, 0, 1} {汤姆, 1, 0} {坦率, 0, 1} 然后在更新时,将列表合并到 {frank, 14, 3}etc

有人可以提供一些建议吗?

【问题讨论】:

  • 这就是类的用途。
  • 因为类应该在游戏服务器中使用,答案应该注意多线程!

标签: c# list arrays dictionary multidimensional-array


【解决方案1】:
class PlayerDeathKills
{
    public int PlayerId;
    public int NumDeaths;
    public int NumKills;
}

编辑其实这样更好:

class DeathsKills
{
    public int NumDeaths;
    public int NumKills;
}

IDictionary<int, DeathsKills> playerDeathKills = new Dictionary(...);

public void AddKill(int killerId, int victimId)
{
    DeathKills killer;
    if (!playerDeathKills.TryGetValue(killerId, out killer)) {
        killer = new DeathKills();
        playerDeathKills.Add(killerId, killer);
    }
    killer.NumKills ++;

    DeathKills victim;
    if (!playerDeathKills.TryGetValue(victimId, out victim)) {
        victim = new DeathKills();
        playerDeathKills.Add(victimId, victim);
    }
    victim.NumDeaths ++;
}

【讨论】:

  • 我该如何使用它?我有点新手抱歉:)
  • 并使用增量,而不是新名称,每次出现 0、1。
【解决方案2】:

我的版本

class Player
{
    private readonly string _Name;
    private int _KillsCount = 0;
    private int _DeathsCount = 0;
    private bool _IsChanged = false;

    public string Name
    {
        get { return _Name; }
    }

    public int DeathsCount
    {
        get { return _DeathsCount; }
        private set
        {
            if (_DeathsCount != value)
            {
                _DeathsCount = value;
                _IsChanged = true;  
            }   
        }
    }

    public int KillsCount
    {
        get { return _KillsCount; }
        private set
        {
            if (_KillsCount != value)
            {
                _KillsCount = value;
                _IsChanged = true;  
            }
        }
    }

    public bool IsChanged
    {
        get { return _IsChanged; }
        set { _IsChanged = value; }
    }

    public Player(string name)
    {
        _Name = name;
    }

    public void Kill(Player killer)
    {
        DeathsCount++;
        killer.KillsCount++;
    }
}

class Example
{
    private readonly Collection<Player> _Players = new Collection<Player>();
    private bool _IsUpdateEnabled;
    private int _UpdateTimeout = 1000;

    public void Start()
    {
        var frank = new Player("Frank");
        var tom = new Player("Tom");
        _Players.Add(frank);
        _Players.Add(tom);

        _Players.Add(new Player("Bob"));

        _IsUpdateEnabled = true;
        new Thread(UpdateThreadMethod).Start();

        // Frank kills Tom ):
        tom.Kill(frank);

        // Where is Bob?
        var bob = _Players.First(p => p.Name == "Bob");

        // Bob kills Frank
        frank.Kill(bob);

        // Tom kills Bob
        bob.Kill(tom);
    }

    private void UpdateThreadMethod()
    {
        while (_IsUpdateEnabled)
        {
            foreach (var player in _Players)
            {
                if (player.IsChanged)
                {
                    // update database
                    // e.g. "update stats set kills = @kills, deaths = @deaths where name = @name"
                    // where
                    // @kills is players.KillsCount
                    // @deaths is player.DeathsCount
                    // @name is player.Name
                    player.IsChanged = false;
                }
            }

            Thread.Sleep(_UpdateTimeout);
        }   
    }

    public void ShowResults()
    {
        foreach (var player in _Players)
        {
            Console.WriteLine("Player name: {0}, kills: {1}, deaths: {2}", player.Name, player.KillsCount, player.DeathsCount);
        }
    }
}

【讨论】:

  • 好的,我认为这比我所追求的要复杂一些。我要做的就是在 kill 事件上,更新一个列表。该列表包含 PlayerName、Kills、Deaths。因此,在杀戮事件中,杀手会更新,他们的杀戮会增加 1,然后受害者的另一个更新会增加死亡。然后我需要能够轻松地循环提取这些信息。
  • 玩家列表怎么样?这正是您正在寻找的。​​span>
  • 列表中的每个玩家都有击杀数和死亡数。也许我不明白什么?
  • 哦,好吧.. 不,我认为我不理解.. 那么我应该写什么来获取集合中每个玩家的详细信息? _Players 中的 foreach 播放器? 编辑哦,我刚刚看到你已经在那里了..我想我现在明白了..
  • 你如何判断一个玩家被杀或被杀?我看到你添加了一个新玩家,但是已经存在的玩家怎么办......即如果玩家鲍勃连续获得 3 次击杀......
【解决方案3】:

你觉得这个结构怎么样?

public class Murder
    {
        public DateTime Time { get; set;}
        public Player Killer { get; set; }
        public Player Killed { get; set;}

        public Murder(DateTime time, Player killer, Player killed)
        {
            Time = time;
            Killer = killer;
            Killed = killed;
        }
    }

public class Player
{
    public int DeathNumber{ get; set;}
    public int KillNumber { get; set; }

}

public static class MainClass
{
    static Dictionary<DateTime, Murder> murders = new Dictionary<DateTime, Murder>();

    //Add new murder. Save it to murders and refresh Player statistics.
    public static void AddMurder(Player killer, Player killed)
    {
        DateTime now = DateTime.Now;
        murders.Add(now, new Murder(now, killer, killed));
        killer.KillNumber++;
        killed.DeathNumber++;
    }

    public static void GameProcessExample()
    {
        AddMurder(new Player(), new Player());
        Thread.Sleep(1000);
        AddMurder(new Player(), new Player());

        //You can use LINQ to select any murders you need: by date or just some number of the last murders.
        var q = from murder in murders
                where murder.Key > DateTime.Now.AddHours(-1)
                select murder;
    }
}

【讨论】:

  • 如何查看玩家的击杀数?
  • @Matt,你应该使用 Player.KillNumber
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 2016-08-27
  • 1970-01-01
  • 1970-01-01
  • 2016-02-04
  • 2013-09-22
  • 1970-01-01
相关资源
最近更新 更多