Zedd Zedd - 1 year ago 65
C# Question

Which class type should I use for sorted collection with key updating and value lookup

I am making a game in Unity with c# code and I want a character to have something like aggro table.

It will be something like (float, int) table where int is other character id and float is actual aggro value.

Basically, I have few things in mind:

  • The table should be sorted by float keys so I can quickly get top

  • I need to be able to frequently lookup entries by its int
    value because of (3)

  • I want to change float key frequently and have
    the table sorted up all the time

  • I dont care about memory usage
    as there wont be that many entries

  • I do care about performance of
    operations like inserting/removing/changing entries and re-sorting
    the list

I am not very experienced in C# saw few things like sortedlist/dictionary, but it doesnt seem to be optimalized for all the things I want.

Do you have any advice?

EDIT: Not sure if I did a good job at explaining what I want to achieve. It might be very similar to a table of football player names and number of goals they scored during the season. I will frequently ask for "most productive players" and also I will frequently update their scores by looking up their names and changing their stats, needing the table to be sorted all the time.

Answer Source

You could use a List<Character>, or an array excluding the player's character. You keep the List<Character> sorted with the highest aggro value at the front. To keep everything sorted every frame you run quicksort first. Once a Character has a lower aggro value than the player's aggro threshhold you escape out of the method.

If aggro is above the threshold just run the aggro check.

You could extend this to work for multiplayer by having a List<Player>. Something like:

void quicksort(List<Enemy> enemies, int first, int last)
   int left = first;
   int right = last;
   int pivot = first;

   while (last >= first)
       if(enemies[first].Aggro >= enemies[pivot].Aggro &&
           enemies[last].Aggro < enemies[pivot].Aggro)
           swapp(enemies, first, last)
       else if(enemies[first].Aggro >= enemies[pivot].Aggro)
       else if(enemies[last].Aggro < colliders[pivot].Aggro)

   swap(enemies, pivot, last);
   pivot = last;
   if(pivot > left)
      quicksort(enemies, left, pivot);
   if(right > pivot + 1)
     quicksort(enemies, pivot + 1, right);

void swap(List<Enemy> enemies, int left, right)
   var temp = enemies[right];
   enemies[right] = enemies[left];
   enemies[left] = temp;

void CheckAggro()
   quicksort(enemies, 0, enemies.Count - 1);
   for(int = 0; i < players.Count; i++)
       for(int j = 0 < enemies.Count; j++)
           if(players[i].AggroThreshhold < enemies[j].Aggro)
           // Perform what happens when enemy is high on aggro threshold.

If players have different aggro thresholds you could save all of the enemies who have aggro above the minimum to a separate List, and then do a check against that from the player with the lowest to highest threshold. Just keep the list of players sorted with the lowest aggro threshold first.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download