The class Dice
seems unnecessary. The Stat
class in interesting, but asi
seems unclear, and mod
currently could return a string. Rather, you’d be better off chucking an error from stat when the value changes if mod
can’t resolve.
If you wanted to use classes, DndCharacter
seems something obvious to implement. Rather than having things like st = Stat("Strength")
hanging about in global space, have those live in a class.
You have functions for each of your races. They all begin with something like:
def choose_dwarf():
character_race = "Dwarf"
This is meant to set the global value for character_race
, but that mayn’t always work. That character_race
reasonably belong to DndCharacter
. Choose race should be passed an instance of DndCharacter
.
Feats, languages, and proficiencies are all floating about. They could be corralled into something more organized.
The stat pick looked neat. I played with this a little. You can probably apply this approach to other aspects of the code:
import random
def die_roll(sides):
return random.randint(1,sides)
def roll_stat():
return sum(sorted(die_roll(6) for _ in range (4))[1:])
class Stat:
# just made a list of these: only 20
MOD_LOOK = dict(((1, -5), (2, -4), (3, -4), (4, -3), (5, -3), (6, -2), (7, -2), (8, -1), (9, -1), (10, 0), (11, 0), (12, 1), (13, 1), (14, 2), (15, 2), (16, 3), (17, 3), (18, 4), (19, 4), (20, 5)))
def __init__(self, name, value = 1):
self.name = name
self.value = value
self.__validate()
def __repr__(self):
return "{}: {} ({})".format(self.name, self.value, self.mod())
def __iadd__(self, n):
self.value += n
return self
def __validate(self):
if self.value not in Stat.MOD_LOOK:
raise Exception("{} invalid stat value".format(self.value))
def mod(self):
return Stat.MOD_LOOK.get(self.value)
class Stats:
def __init__(self):
self.st = Stat("Strength")
self.dx = Stat("Dexterity")
self.cn = Stat("Constitution")
self.nt = Stat("Intelligence")
self.wm = Stat("Wisdom")
self.ch = Stat("Charisma")
def items(self):
return [self.st, self.dx, self.cn, self.nt, self.wm, self.ch]
class DndCharacter:
def __init__(self, name):
self.name = name
self.stats = Stats()
self.level = 1
self.alignment = " "
self.race = ""
self.dnd_class = ""
def show(self):
print(self.name + ", a level " + str(self.level) + " " + self.alignment + " " + self.race + " " + self.dnd_class + "\n")
print("Stats:")
for x in self.stats.items():
print(x)
def assign_stats(dnd_char):
attributes = sorted((roll_stat() for _ in range(len(dnd_char.stats.items()))), reverse=True)
for attr in dnd_char.stats.items():
pick = None
while pick == None:
try:
pick = int(input("Choose which number ({}) you will attribute to your {} stat: ".format(attributes, attr.name)))
except:
pass
if pick == None or pick not in attributes:
print("Error, try again.")
pick = None
attr += pick - 1 # don't like this - 1, perhaps other elements could be rethought
attributes.remove(pick)
x = DndCharacter("Alice")
assign_stats(x)
x.show()