Elegant method to add two lists?



  • Is there an elegant method in MUX to add the contents of two lists together at each indexed position?

    For example:

    a = 1 2 3 4 5 6
    b = 10 20 30 40 50 60
    result: 11 22 33 44 55 66
    

    I already created something to add individual attributes together to create a, and it works but it is not elegant and not extensible.
    It should be much easier to deal with indexing an array than dealing with six different attributes using extract() or some other function.

    I've always assumed that character sheets usually looked more like:

    &PHYSICAL %#=2 3 3
    &STRENGTH %#=extract(u(%#/PHYSICAL),1,1)
    &DEXTERITY%#=extract(u(%#/PHYSICAL),2,1)
    ...
    

    Is this kind of array thinking fundamentally flawed, making it better to be verbose and explicit and not worry so much about extensibility?



  • @Hexagon said in Elegant method to add two lists?:

    Is there an elegant method in MUX to add the contents of two lists together at each indexed position?

    That's the example given in help mix()



  • @Cheesegrater Perfect, thank you. Not what I would have expect it to be called, but it's such a frequent use case that I figured it had to be there somewhere.



  • @Hexagon

    Although you have your answer, I store one trait per attribute. I am now so used to it that would not do it any other way.



  • @Thenomain Because of familiarity or because it is easier to manipulate the data? Good to know about the character sheets that you've made.

    Some things are pretty constant, like WoD or d20 attributes. On the other hand, there are definitely some variations in skills. I was attempting to err on the side of caution by referencing a list of allowed items. Those, however, had to be matched to a value somewhere. I tend to want to think of these things as nested dictionaries in an optimal case, or paired lists with matching indices.

    I've made these sorts of things before in spreadsheets, but pass by reference is getting really heavy. I get the feeling that I may be making things harder by trying to do them in a modular way.

    To look at it from a D&D perspective, I'm expecting a situation where it is easier to mix() lists to derive the following:

    Athletics = Proficiency Bonus + Attribute Bonus + Skill Ranks
    
    &_5E.CHAR_PROFICIENCY obj=2
    &_5E.CHAR_ATTRBONUS obj=[1] 2 1 0 0 0
    &_5E.CHAR_SKILLRANKS obj=2 2 2 [4] 3...
    &_5E.SKILLS codeobj=Acrobatics Animal_Handling Arcana [Athletics]...
    

    I guess that really does read as more complicated than simply adding 3 attributes, even if it does mean you'd have to retool it if you wanted to run something like Pathfinder.



  • @Hexagon said in Elegant method to add two lists?:

    @Thenomain Because of familiarity or because it is easier to manipulate the data?

    Both. I've dealt with systems where data is stored in a position-based attribute (i.e., 2 3 2 1 4 2 3 3 2), and that is fine if all the code around this is going to be fairly consistent. i.e., "strength is position 1" and "physical attributes are strength, dexterity, and stamina" is about as complex as you need it.

    You've found some of the issues with that. Sometimes you'll get a character generation rule that says, "Add 1 to a Finesse attribute." Now you have to make a list of power, finesse, and resistance attributes.

    What I've done is create more than one &attribute to describe a trait.

    &attribute.dexterity <data dictionary>=1.2.3.4.5
    &tag.attribute.dexterity <data dictionary>=physical.finesse
    

    This isn't perfect, but I have a consistent way to filter any kind of trait by one or more tags. I can easily list all physical attributes, skills, and merits though one function. This is much more useful with Fighting Styles.

    I tend to want to think of these things as nested dictionaries in an optimal case, or paired lists with matching indices.

    And that's the beauty of coding. As long as you're inside your parameters, there's no wrong way to do it.

    To look at it from a D&D perspective, I'm expecting a situation where it is easier to mix() lists to derive the following:

    Athletics = Proficiency Bonus + Attribute Bonus + Skill Ranks
    
    &_5E.CHAR_PROFICIENCY obj=2
    &_5E.CHAR_ATTRBONUS obj=[1] 2 1 0 0 0
    &_5E.CHAR_SKILLRANKS obj=2 2 2 [4] 3...
    &_5E.SKILLS codeobj=Acrobatics Animal_Handling Arcana [Athletics]...
    

    It took me a minute to notice you were missing a line:

    &_5E.ATTRIBUTES codeobj=[Strength] Dexterity ...
    

    --

    This is how my system might do that:

    &_attribute.strength <character>=13
    &modifier.strength <code object>=u( attr_mods, get(<character>/ _attribute.strength ))
    

    And the reason is this: I know D&D will do crazy things like, 'While Stunned, Strength Mod is divided by 2 round up, unless also Floating in which case round down'. I can change the modifier code however I want. This also means I can:

    &_skill.athletics <character>=4
    &skill.athletics <code object>=modifier.strength
    

    Or something similar to indicate: The Athletics skill is based on Strength.

    &roll.skill <code object>=add( <character skill>, <skill's attribute modifier>)
    

    --

    Again, there's no wrong way. There are ways that back you into corners that you'd rather not be in (I had to make my 'stat info' object Visible because of that, once, which was horrible), but you take the bits of code that work to make better bits of code.

    Have fun with it!



  • @Thenomain Good catch on the missing attribute. I actually have it but had omitted it in the sample code. You've given me a lot to think about. For instance, position-based probably won't work with Pathfinder because of exploding knowledge/profession skills unless I put them somewhere else. 5th Edition at least just calls the skill "arcana" and it's on all the sheets.



  • @Hexagon

    Absolutely code the way that is the best for the information you have. I don’t know what you mean by “exploding skills” but if that means some skills are handled differently than others, it should still be possible to teach your roller or stat lookup system how it should work.

    For instance, in World of Darkness there is a trait called Health Levels, but it depends on a lot of other traits. I store it as a line of code that looks up these other traits.

    I really have five: Max Health (size + stamina), three Damage Types, and Health Penalty (a convoluted formula of Max Heath and sum of damage, affects all rolls).



  • There may be a better name for it, but skills are in an alphabetical list right? This works fine until you get to Knowledge, which breaks into Knowledge: Arcana, Knowledge: History, Knowledge: Weird Campaign Thing #1, etc. They're just a bunch of blanks in the middle of the list to be filled in when appropriate. Maybe six are standard, and the rest are totally meant to be specific to your game. Profession does the same thing, but for literally any job you could have.

    So having those in the middle of a list you want to reference by position could be a challenge. If I wanted to keep that, and I may, I just have to break them out into a parallel list. Which means adapting the standard character sheet, but I'm already adapting an entire game, why wouldn't I update the character sheet to reflect the medium?

    I'm looking forward to working on the health system because I sort of expect it to be easier. It's just integer math. But d20 stuff is weird and I'll get it done and then I will remember "Oh you think you're clever? Now account for level draining attacks" and I'll have to go get a beer and think about it for a while.


Log in to reply