Search Unity

Best way to create a double entry chart with exchangeable keys?

Discussion in 'Scripting' started by Redden44, Feb 19, 2020.

  1. Redden44

    Redden44

    Joined:
    Nov 15, 2014
    Posts:
    159
    Hello, I've got a bunch of factions and I need to store the reputation value that each faction has got toward all the other factions. Also I need a way to retrieve the data so that I can switch faction A and B position and they still point toward the same value; e.g. GetRep(Faction A, Faction B) should give the same result as GetRep(Faction B, Faction A).

    For now I've got a FactionManager class that contains a list of all factions and each Faction class has got a Dictionary<Faction, reputation> that contains each faction and the reputation toward them. When I need to update the reputation between two factions, the FactionManager calls each faction and update its reputation toward the other one. This way if I ask to Faction A what is its reputation toward Faction B or vice versa, I get the same result.
    It works but it seems a little dumb..instead of having a list of faction in each faction, what I would like to do is have a single data container inside the FactionManager.

    I could use a Dictionary<Faction, Dictionary<Faction, Reputation>> inside the FactionManager, but it won't change much, I mean I'll still have to store the data twice.

    I could use a dictionary with Tuples as Keys, and when I look for the reputation between two factions, I could look for <FactionA, FactionB> and if doesn't exist, do another search for <FactionB, FactionA>. Is this a reasonable approach?

    In alternative I could use a double array Faction[ , ], but then I'll have to store the data twice or do a double search as for the dictionary. Also if the number of factions changes I will have to rebuilt the array.

    Is there a better solution? Thanks!
     
  2. unit_dev123

    unit_dev123

    Joined:
    Feb 10, 2020
    Posts:
    989
    json has more options for storing and access or some tree data structure
     
  3. Redden44

    Redden44

    Joined:
    Nov 15, 2014
    Posts:
    159
    I don't need to save and load the data, I need to store it inside a c# class and retrieve it with a function using two keys (i.e. Faction A and B), also no matter the order of the parameters, the search should point to the same value.

    And please stop posting generic json advertising in my threads, thanks.
     
  4. Bisoncraft

    Bisoncraft

    Joined:
    Feb 5, 2016
    Posts:
    37
    Using a dictionary, you could sort your factions (for instance through name, or ID), then you could make sure in your methods calling the value, that you always call with the first faction name (for instance always call <Faction A, Faction B> and never <Faction B, Faction A>, in that case based on the alphabetic order).

    Alternately, you could accept to store the data twice. You would need to make sure that when you update a value, you would store for both ways. Sure, it would be a waste of data, but it must be negligible? As long as you make sure that your methods safely update both values at the same time.
     
  5. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    Is Reputation symmetric, i.e. if faction a have a Reputation of 10 vs faction b, will then b also have a reputation of 10 versus a (in pseudo Terms: is Rep(A,B) == Rep(B,A)?

    If so, you could use a simple 2D array that only uses the upper (or lower) triangle (similar to Unity's physics collider layer Settings)
     
  6. Redden44

    Redden44

    Joined:
    Nov 15, 2014
    Posts:
    159
    Yes Rep(A,B) == Rep(B,A).
    If I use a 2D array, I think I'll have to store the value twice, unless as Bisoncraft said I use a "rule" to store and retrieve the data, because in a 2D array [factionA, factionB] it's not the same as [factionB, factionA].
    Also I'll have to rebuild the array each time the game spawns a new faction.
     
  7. Redden44

    Redden44

    Joined:
    Nov 15, 2014
    Posts:
    159
    Yes the idea of using a rule to store and retrieve the data is cool but also a hassle, I think I'll stick to my current system and store the data twice :(
     
  8. Bisoncraft

    Bisoncraft

    Joined:
    Feb 5, 2016
    Posts:
    37
    Storing the data twice isn't a big issue, unless you start to have a lot of data. Make sure that you encapsulate access to the List or Dictionary of reputations, so that you've got only one method to read and one method to select. Otherwise, you're going to mix things at some point.
     
  9. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556

    If you know that f(i, k) == f(k, i) then couldn't you use f(min(i,k), max(i,k)) to only access one half of the array?
     
  10. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    and use a flat array to simulate