Search code examples
pythontext-based

Text Based Mechanics in Python: Class, Dictionary, or List?


I'm fairly new to coding in python (3) as somewhat of a hobby, but having fun playing around with some game mechanics without worrying about GUI. I'm currently working on a civilization-type text based game whose foundations lie in an old excel document. It's fairly centred on math and logic, which I think made for a pretty easy but in-depth set of mechanics.

Anyway, the game allows for researching tech, producing buildings, growing citizens, gathering culture etc. One thing I'm struggling with is the military system.

I have a number of different units for the player to produce. Let's say each unit has a name, strength and resilience (eg. 'Archer', '10', '80'). Wars are based on total player strength (I can calculate this). After each war, the unit's strength decreases by it's resilience ie. this Archer would decrease to 80% of its original strength after a war to strength 8.

However, I'm having trouble working out how the user can create units in a fashion that allows this mechanic. I originally used a Unit() class (with different units eg. archer, spearman as objects) with a 'quantity' argument alongside name/strength/resilience for amount of units built, but every time I ran the function to calculate the effect of resilience I realised I was affecting not only currently produced units but all future versions of the unit too. I was running something like the following:

class Unit():
  def __init__(self, name, quantity, strength, resilience)
  self.name = name
  self.quantity = quantity
  self.strength = strength
  self.resilience = resilience

archer = Unit('archer', 0, 10, 80)

etc...

Each time the user built a unit, the 'quantity' would increase. However I've come to understand that it's probably this method of coding is probably what is limiting me. Reading other threads tells me I should be aiming to not store object data in such a way, right?

I've been playing around and researching and I can't seem to get my head around the solution (which I'm sure is there). I'm having trouble finding the right way of storing each unit's basic data (name, strength, resilience) while allowing the user to produce multiple, unique copies of each unit. Each unit should be a class? A sub class? It should be stored in a dictionary? A list?

I apologise for the lack of code in this post, but I don't exactly have erroneous code - I'm just lacking the logic and python knowledge to find the right systems to make this work properly. Been playing with dictionaries, lists, loops, inherited classes, but I just can't get it right.

How would one create multiple archers who each take damage, without affecting future archers that might be produced?

Thanks if anyone can suggest something. Other than this I'm having a lot of fun coding in python!


Solution

  • The point of a class is that it lets you create many instances of that class. You don't need to (and can't/shouldn't) subclass Unit for each unit. You simply need to instantiate the Unit class:

     archer1= Unit('archer', 0, 10, 80)
     archer2= Unit('archer', 0, 10, 80)
    

    Now you have two separate archer units with separate stats. If one of them fights in a war and its attributes change, the other won't be affected:

     archer1.strength= 0
     print(archer2.strength) # prints 10
    

    Of course, this means you don't need the quantity attribute and you need to store all units in some kind of data structure like a list:

     all_my_archers= [archer1, archer2]
     #create a 3rd archer
     all_my_archers.append(Unit('archer', 0, 10, 80))
    

    This is less important, but you should also consider subclassing Unit to create an Archer class:

    class Unit:
        def fight_war(self):
             self.strength= self.strength * self.resilience / 100.0
    
    class Archer(Unit):
        name= 'archer'
        strength= 10
        resilience= 80
    

    Since all archer units start with the same stats (I assume), this will eliminate the need to specify the strength and resilience every time you create a new archer unit (you can just do archer4= Archer() now), and you can still change a unit's stats without affecting other units.