#[character.py]
class Character: 
  experience = 0
  hit_points = 10

  def get_weapon(self):
    weapon_choice = input("Weapon ([S]word, [A]xe, [B]ow: ").lower()

    if weapon_choice in 'sab':
      if weapon_choince == 's':
        return 'sword'
      elif weapon_choince == 'a':
        return 'axe'
      else:
        return 'bow'
    else:
      return self.get_weapon()

  def __init__(self, **kwargs):
    self.name = input("Name: ")
    self.weapon = self.get_weapon()

    for key, value in kwargs.items():
      setattr(self, key, value)

Testing

>>> from character import Character
>>> player = Character()
Name: Kenneth
Weapon ([S]word, [A]xe, [B]ow: Katana
Weapon ([S]word, [A]xe, [B]ow: K
Weapon ([S]word, [A]xe, [B]ow: S
>>> player.weapon
'sword'

DRY

“Don’t Repeat Yourself”. You can accomplish DRY by:

  • Grouping common operations into functions
  • Grouping common functionalities into classes
#[combat.py]:
import random 

class Combat: 
 dodge_limit = 6
 attack_limit = 6
 
 def dodge(self):
 roll = random.randint(1, self.dodge_limit)
 return roll > 4

 def attack(self):
 roll = random.randint(1, self.attack_limit)
 return roll > 4

This line return roll > 4 substitute the entire following code:

if roll > 4:
  return True
else:
  return False

Now that’s DRY!

Let’s add these abilities – attack and dodge – to our monsters and player.

#[character.py]:
from combat import Combat

class Character(Combat)
...

#[monster.py]:
from combat import Combat

class Monster(Combat):
...
Multiple Inheritence
class Goblin(Monster, Combat):
...

Testing

>>> from monster import Goblin
>>> hoggle = Goblin()
>>> hoggle.attack()
False
>>> hoggle.dodge()
True
>>> from character import Character
>>> player = Character()
Name: Kenneth
Weapon: ([S]word, [A]xe, [B]ow): s
>>> player.attack()
False
>>> player.attack()
True