I'm writing my first game and would love some advice on how to get away from all this hardcoding I'm using... Each Character has "abilities" (all individual functions) but I can't seem to figure out how to streamline this. Example:

def lightning_bolt(self):
    if self.is_stunned:
        print("Stunned...ability unsuccessful.")
    elif self.is_confused:
        confused_test = roll_d_x(2)
        if confused_test == 1:
            print("Confused...ability unsuccessful.")
        defender.mobility = (defender.mobility / 2)
        success = self.success_check()
        defender.mobility = (defender.mobility * 2)
        if success:
            volatile_roll = roll_d_x(10)
            if volatile_roll == 1:
                defender.lose_health(((self.energy * 0.5) + 10))
                stun_test = roll_d_x(4)
                if stun_test == 1:
                    defender.is_stunned = True
            print("Ability failed.")

Note: all abilities must pass this "stunned and confused test" and a "volatile test". I will be defining a function for those. *I wanted to make "class Ability:", but I want each character to have their own individual abilities. Is there a way to nest classes or something? Any ideas to streamline aspects like "cost" and "damage dealt", etc.?

  • 2
    \$\begingroup\$ This is incomplete code and is considered as an off-topic here, you should provide the full code and a clear description of what this could is intended to do and samples of input and output. I'm voting to close this question. \$\endgroup\$ – bullseye Oct 5 '19 at 15:39
  • 3
    \$\begingroup\$ Please do provide additional code for context. There are quite a few possible directions for improvement here. \$\endgroup\$ – Austin Hastings Oct 5 '19 at 17:21
  • 1
    \$\begingroup\$ Thank you for commenting. I will scratch this question and reask with much more code. I didn't want to spam. New here. \$\endgroup\$ – Claude Fried Oct 5 '19 at 20:38

I have asked that you provide more code, and I hope that you do.

Until then, I suggest you have a look at the Visitor Pattern and its implementation using multiple dispatch.

You have a lightning attack. You are applying certain effects, including some effects that are common to all attacks.

You have not yet reached the point where some defenders will be immune to lightning, or take reduced damage, or immune to stun, but you will.

It makes more sense to Tell, don't Ask in thise situation. You tell the defender that they were attacked by lightning, and let the defender handle things.

The default behavior would be substantially what you have shown. But you could then create a defender subclass that was immune to lightning, or suffered reduced damage, and the logic would be located with that particular defender, which improves your code organization and maintainability.

Beyond that, since your defender seems to be a class already (based on the code you have shown), it should be easy to encode the "standard attack checks" into the base class in a single method. You can then raise an exception or return a sentinel value to indicate that the attack is blocked due to stun or confusion, or just print out the results (not recommended).

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.