views:

138

answers:

3

For a game server, I want to record details when a player makes a kill, store this, and then at intervals update to a sql database.

The part i'm interested in right now is the best method of storing the kill information. What i'd like to pass to the sql server on update would be {PlayerName, Kills, Deaths}, where the kills and deaths are a sum for the period between updates.

So i'm assuming i'd build a list along the lines of {bob, 1, 0} {frank, 0, 1} {tom, 1, 0} {frank, 0, 1} then on update, consolidate the list to {frank, 14, 3}etc

Can someone offer some advice please?

+2  A: 
class PlayerDeathKills
{
    public int PlayerId;
    public int NumDeaths;
    public int NumKills;
}

Edit In fact, this is even better:

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 ++;
}
Dean Harding
How do I use that? I'm a bit of a novice sorry :)
Matt
I updated my answer with a better example.
Dean Harding
And use increments, not a new Name, 0, 1 for each occurrence.
NickLarsen
ah ok.. thats quite brilliant.. thanks for that :D
Matt
A: 

How do you like this structure?

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;
    }
}
Hun1Ahpu
how would I access the number of kills a player has?
Matt
@Matt, you should use Player.KillNumber
Hun1Ahpu
A: 

My version

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);
        }
    }
}
bniwredyc
OK, I think this is a bit more complicated that what I'm after..All I'm trying to do is on the kill event, update a list. The list has PlayerName, Kills, Deaths. So on the kill event, a update goes for the killer, which adds 1 to their kills, and then another update to the victim, which adds a death.I then need to be able to easily extract this information in a loop.
Matt
What about a list of Players? It's exactly what you're looking for.
bniwredyc
yeah, but the list needs to have the number of kills and number of deaths also..
Matt
Each Player in the list has number of kills and deaths. Maybe I don't understand something?
bniwredyc
Oh ok.. Na I think its me thats not understanding.. So what do I write to get the details for each player in the Collection? foreach Player in _Players ?*edit* Oh I just saw that you already had that there.. I think I understand now..
Matt
I've edited answer, see ShowResults() method
bniwredyc
How do you tell it that a player got a kill or a death?? I see you add a new player, but what about a player that's already there.. i.e. if player bob gets 3 kills in a row..
Matt
see updated Start() method
bniwredyc
Thats perfect.. Thankyou so so much!!!
Matt