# Character generator

I'm a total newbie teaching myself via Zed Shaw's Learn Python The Hard Way and I've gotten bored over a week long memorization lesson, so I thought I would make a character generator for a pen and paper RPG I'm writing. I havent really read about if statements or things like that, so I am experimenting here.

##########################################################
# Cyberpanky N.O.W Python Character Generator by Ray Weiss
#
# Created 9/24/2012
#
# Much thanks to Connor Daliposon
# That a Python newbie like me could understand
##########################################################

# Imports
import random
from pprint import pprint

# Hey there
print """
Hello world & welcome to the CYBERPANKY N.O.W. character generator.
Programmed by Ray Weiss.
To quit at anytime, press CNTRL-C.
"""

print "Lets figure out your stats first. Press enter to continue."
raw_input()

# Stat Roller
# Rolls 3D6 and adds the sum together and prints

def roll_stats():
a = random.randint(1, 6)
b = random.randint(1, 6)
c = random.randint(1, 6)
d = random.randint(1, 6)
list = [a, b, c, d]
list.sort()

# Modifiers

def pow_mod():
a = "|+1 to hit on mele attack rolls| "
b = "|+1 damage on mele attack rolls|"

if pow >= 15 and pow < 17:
return a
if pow >= 17:
return a + b
else:
return " ~no modifiers~"

def iq_mod():
a = "|-500\$ to invest in cyberspace| "
b = "|Reroll Street Doc abilities|"

if iq >= 15 and iq < 17:
return a
if iq >= 17:
return a + b
else:
return " ~no modifiers~"

def agi_mod():
a = "|+1 to hit with ranged weapons| "
b = "|-1 to hit with ranged weapons|"

if agi >= 12:
return a
if agi <= 9:
return b
else:
return " ~no modifiers~"

def con_mod():
a = "|+1 hit point per hit dice|"
b = "|-1 hit point per hit dice|"

if con >= 15:
return a
elif con <= 6:
return b
else:
return " ~no modifiers~"

def cyn_mod():
a = "|Add 10% to earned experience|"
b = "|Add 5% to earned experience|"
c = "|Subtract 10% from earned experience|"
d = "|Subtract 20% from earned experience|"

if cyn >= 15:
return a
elif cyn > 12 and cyn < 15:
return b
elif cyn > 6 and cyn < 9:
return c
elif cyn <= 6:
return d
else:
return " ~no modifiers~"

def cha_mod():
a = "|+1 to reaction rolls|"
b = "|-1 to reaction rolls|"

if cha >= 15:
return a
if cha <= 8:
return b
else:
return " ~no modifiers~"

# Prints stats + modifiers.
pow = roll_stats()
print "Power:", pow, pow_mod()
iq = roll_stats()
print "Intelligence:", iq, iq_mod()
agi = roll_stats()
print "Agility:", agi, agi_mod()
con = roll_stats()
print "Constitution:", con, con_mod()
cyn = roll_stats()
print "Cynicism:", cyn, cyn_mod()
cha = roll_stats()
print "Charisma:", cha, cha_mod()

print "\nIf you dont like your stats, tough shit. This is Cyberpanky N.O.W."
print "\nPress enter to continue."
raw_input()

# Choose Class

print """In Cyberpanky N.O.W. there are only 3 character classes.

1. Samurai: Badass mercenaries. Can make multiple attacks.
------------------------------------------------------------------------------
2. Street Docs: Hackers / Doctors. Can heal & hack.
------------------------------------------------------------------------------
3. Shaman: Magical prophets that follow spirit animals and cast miracles
------------------------------------------------------------------------------
"""
type = int(raw_input("Please type a 1, 2, or 3 > "))

if type == 1:
character_class = "Samurai"
class_power = """
* Attack multiple times for a -2 to hit penalty.
* Uses a D10 for Physical hit box.
* Has a + 1 to hit bonus that levels up to level 5.
"""
name = raw_input("\nAlright {}, tell me your name >".format(character_class))

elif type == 2:
character_class = "Street Doc"
class_power = """
* Roll IQ to mess with electronics
* Can heal party members after combat for 1D4 Hit Points
* Can perform cyberwear installation or surgery with proper tools.
"""
name = raw_input("\nAlright {}, tell me your name >".format(character_class))

elif type == 3:
character_class = "Shaman"
class_power = """
* Can cast Miracles.
* Can call for a saving grace if they are on their last Cool Hit Box
* Can do favors for their god for more miracles, or pay a tithe.
"""
name = raw_input("\nAlright {}, tell me your name >".format(character_class))

# Alignment

print"""\nAlright {}, pick an alignment, it's not that important;

1. Narcissist: Cocky bastard, you think you are the best.
------------------------------------------------------------------------------
2. Neutral: Pretty self explanatory dipshit.
------------------------------------------------------------------------------
3. Nihilist: You care about nothing Lebowski, You'll cut off their Johnson.
------------------------------------------------------------------------------
""".format(name)

x = int(raw_input("Please type a 1, 2, or 3 > "))

if x == 1:
alignment = "Narcissist"

elif x == 2:
alignment = "Neutral"

elif x == 3:
alignment = "Nihilist"

print "\nOk you chose {} for an alignment, press enter to continue.".format(
alignment)
print """
------------------------------------------------------------------------------
"""
raw_input()

# Functions for ID generation

def gen_id():
global gender_id
one = "1. Straight male"
two = "2. Gay male"
three = "3. Transgender male pre-op"
four = "4. Transgender male post-op"
five = "5. Bisexual male"
six = "6. Straight female"
seven = "7. Gay female"
eight = "8. Transgender female pre-op"
nine = "9. Transgender female post-op"
ten = "10. Bisexual female"
list = [one, two, three, four, five, six, seven, eight, nine, ten]
pprint(list)
print "\nPlease hit enter to roll 1D10"
raw_input()
gender_id = random.choice(list)
print "You rolled {}, press enter to continue.".format(gender_id)
raw_input()

# Ethnic Profile
def eth_pr():
global ethnic_pr
one = "1. Native American"
two = "2. West European"
three = "3. East European"
four = "4. North Asian"
five = "5. South Asian"
six = "6. Pacific"
seven = "7. North African"
eight = "8. South African"
nine = "9. Slavic / Caucuses"
ten = "10. Hispanic"
list = [one, two, three, four, five, six, seven, eight, nine, ten]
pprint(list)
print "\nPlease hit enter to roll 1D10"
raw_input()
ethnic_pr = random.choice(list)
print "You rolled {}, press enter to continue.".format(ethnic_pr)
raw_input()

# Family Class Distinction
def fam_cls():
global fcd
one = "1. Homeless"
two = "2. Impoverished"
three = "3. Lower Class"
four = "4. Lower Middle Class"
five = "5. Middle Class"
six = "6. Comfortable"
seven = "7. Upper Middle Class"
eight = "8. Upper Class"
nine = "9. Job Creators"
ten = "10. Warren Buffett"
list = [one, two, three, four, five, six, seven, eight, nine, ten]
pprint(list)
print "Please hit enter to roll 1D10"
raw_input()
fcd = random.choice(list)
print "You rolled {}, press enter to continue.".format(fcd)
raw_input()

# Whats Good With Your Folks
def wha_goo():
global wg, one_x, two_x
one_x = "1. Things Are Good With Your Folks; Go to Current Family Affairs"
two_x = "2. Your folks are fucked; go to Your Folks Got Fucked"
list = [one_x, two_x]
pprint(list)
print "Please hit enter to roll 1D2"
raw_input()
wg = random.choice(list)
print "You rolled {}, press enter to continue.".format(wg)
raw_input()

def yo_fo():
global fogo_fuck
one = "1. Your parents were mugged and murdered, just like Batman"
two = "2. Your parents were both convicted of murder"
three = "3. Parents decapitated by a truck"
four = "4. Parents addicted to coke, put you in an orphanage"
five = "5. Parents were corporate spies and assinated in front of you"
six = "6. Parents abandonded you at a young age and joined a cult"
seven = "7. Your parents died from STDs contracted from aldultery"
eight = "8. Parents owed mob a bunch of money, sleeping with fishies"
nine = "9. Nuclear explosion incinerated parents, their shadow remains"
ten = "10. Parents shot themselves immediately after you were born."
list = [one, two, three, four, five, six, seven, eight, nine, ten]
pprint(list)
print "Please hit enter to roll 1D10"
raw_input()
fogo_fuck = random.choice(list)
print "You rolled {}, press enter to continue.".format(fogo_fuck)
raw_input()

# Current Family Affairs
def cu_fa():
global cur_fam, one_y, two_y
one_y = "1. Things are ok with family, go to Nature Or Nurture"
two_y = "2. Your family is fucked, go to Your Family Is Fucked"
list = [one_y, two_y]
pprint(list)
print "Please hit enter to roll 1D2"
raw_input()
cur_fam = random.choice(list)
print "You rolled {}, press enter to continue.".format(cur_fam)
raw_input()

def fa_fu():
global fam_fuk
one = "1. Market tanked with president Paul, dead broke family."
two = "2. Home invaders raped and murded the women in your family"
three = "3. Racial Supremisicist drove your family from their home"
four = "4. Whole family was abducted by aliens, never seen again"
six = "6. Family was accidentally napalmed by the UN, all dead."
seven = "7. Family came down with malaria"
eight = "8. Family has some obvious dealings with Illuminati"
nine = "9. Family eaten alive by cannibals"
ten = "10. Make it up dipshit"
list = [one, two, three, four, five, six, seven, eight, nine, ten]
pprint(list)
raw_input()
fam_fuk = random.choice(list)
print "You rolled {}, press enter to continue.".format(fam_fuk)
raw_input()

# Nature Or Nurture
def na_nu():
global nat_nur
one = "1. Your childhood was very boring & average"
two = "2. Your childhood was spent moving from city to city"
three = "3. Your childhood was depraved; hungry and lonely"
four = "4. Your childhood was rewarding, social & fun."
five = "5. You were a sick child, spent a lot of time in bed"
six = "6. You were sent to a preppy boarding school as a kid"
seven = "7. You got addicted to drugs; it screwed you up."
eight = "8. You killed another kid, spent time in a hospital"
nine = "9. You were a child genius, but had few friends"
ten = "10. Make it up dipshit"
list = [one, two, three, four, five, six, seven, eight, nine, ten]
pprint(list)
print "Please hit enter to roll 1D10"
raw_input()
nat_nur = random.choice(list)
print "You rolled {}, press enter to continue.".format(nat_nur)
raw_input()

# General Disposition
def ge_di():
global gen_dis
one = "1. Friendly"
two = "2. Unfriendly"
three = "3. Shy"
four = "4. Outgoing"
five = "5. Unpretentious"
six = "6. Pretentious"
seven = "7. Hyperactive"
eight = "8. Depressed"
nine = "9. Wonderful Human Being"
ten = "10. Scumbag"
list = [one, two, three, four, five, six, seven, eight, nine, ten]
pprint(list)
print "Please hit enter to roll 1D10"
raw_input()
gen_dis = random.choice(list)
print "You rolled {}, press enter to continue.".format(gen_dis)
raw_input()

# Whats the most important thing in the world
def wh_wo():
global wha_wor
one = "1. Money"
two = "2. Kicking ass"
three = "3. Getting fucked up"
four = "4. Family & friends"
six = "6. The internet"
seven = "7. Faith"
eight = "8. Style"
nine = "9. Anarchy"
ten = "10. Selfishness"
list = [one, two, three, four, five, six, seven, eight, nine, ten]
pprint(list)
print "Please hit enter to roll 1D10"
raw_input()
wha_wor = random.choice(list)
print "You rolled {}, press enter to continue.".format(wha_wor)
raw_input()

# Who is to blame for the worlds problems?
def wh_pr():
global who_pro
one = "1. Corporations"
two = "2. Leftists"
three = "3. Fate"
four = "4. Religion"
five = "5. The Illuminatus"
six = "6. The News Media"
seven = "7. The UN"
nine = "9. Aliens"
ten = "10. President Ron Paul"
list = [one, two, three, four, five, six, seven, eight, nine, ten]
pprint(list)
print "Please hit enter to roll 1D10"
raw_input()
who_pro = random.choice(list)
print "You rolled {}, press enter to continue.".format(who_pro)
raw_input()

# How do you solve the worlds problems
def ho_pr():
global how_pro
one = "1. Kill them all"
two = "2. But them out"
three = "3. Intimidation"
four = "4. Diplomacy"
six = "6. Seduction"
seven = "7. New-Age spirituality"
eight = "8. Religious fanaticism"
nine = "9. Federal power"
ten = "10. Who gives a shit"
list = [one, two, three, four, five, six, seven, eight, nine, ten]
pprint(list)
print "Please hit enter to roll 1D10"
raw_input()
how_pro = random.choice(list)
print "You rolled {}, press enter to continue.".format(how_pro)
raw_input()

# ID Generation

print ("Alright {}, now we need to figure out your personality & life story."
.format(name))
print "\n\t\t1. Ethnics, Genes, & Looks"
age = random.randint(1, 10) + 15
print "Press enter to continue dipshit."
raw_input()
print "Age:", age
print "\t\tGender Identity\n"
gen_id()
print"""
------------------------------------------------------------------------------
"""
print "\t\tEthnic Profile\n"
eth_pr()
print"""
------------------------------------------------------------------------------
"""
print "\t\t2. Ballz Of Our Fathers"
print "\n"
print "\t\tFamily Class Distinction"
fam_cls()
print"""
------------------------------------------------------------------------------
"""
print "\t\tWhat's Good With Your Folks"
wha_goo()
print"""
------------------------------------------------------------------------------
"""
if wg == one_x:
fogo_fuck = "none"
print "\t\tCurrent Family Affairs"
cu_fa()
print"""
------------------------------------------------------------------------------
"""
if cur_fam == one_y:
fam_fuk = "none"
print "\t\tNature Or Nurture?"
na_nu()
print"""
------------------------------------------------------------------------------
"""
if cur_fam == two_y:
print "\t\t Your Family Is Fucked"
fa_fu()
print"""
------------------------------------------------------------------------------
"""
print "\t\tNature Or Nurture?"
na_nu()
print"""
------------------------------------------------------------------------------
"""
if wg == two_x:
yo_fo()
print"""
------------------------------------------------------------------------------
"""
print "\t\tCurrent Family Affairs"
cu_fa()
print"""
------------------------------------------------------------------------------
"""
fam_fuck = "none"
print "\t\tNature Or Nurture?"
na_nu()
print"""
------------------------------------------------------------------------------
"""
if cur_fam == one_y:
fam_fuck = "none"
print "\t\tNature Or Nurture?"
na_nu()
print"""
------------------------------------------------------------------------------
"""
if cur_fam == two_y:
print "\t\t Your Family Is Fucked"
fa_fu()
print"""
------------------------------------------------------------------------------
"""
print "\t\t3. What Makes you tick"
print "\n"
print "\t\tGeneral Disposition"
ge_di()
print"""
------------------------------------------------------------------------------
"""
print "\t\tWhat's The Most Important Thing In The World?"
wh_wo()
print"""
------------------------------------------------------------------------------
"""
print "\t\tWho Is To Blame For The World's Problems?"
wh_pr()
print"""
------------------------------------------------------------------------------
"""
print "\t\tHow Do You Solve Your / The Worlds Problem"
ho_pr()
print"""
------------------------------------------------------------------------------
"""

#Starting Money
gold = roll_stats() * 100

print "Ok so lets sum that up, please hit enter to continue"
raw_input()

print"""
------------------------------------------------------------------------------
"""

# Print Character Sheet Function.
def char_shee():
print "Name:", name
print "Class:", character_class
print "Class Powers:", class_power
print "Alignment:", alignment
print "Power:", pow, pow_mod()
print "Intelligence:", iq, iq_mod()
print "Agility:", agi, agi_mod()
print "Constitution:", con, con_mod()
print "Cynicism:", cyn, cyn_mod()
print "Charisma:", cha, cha_mod()
print "Money:", gold
print"""
\t\t{0}'s History
\t\t------------------
\t\tAge:{1}
\t\t{2}
\t\t{3}
\t\t{4}
\t\t{5}
\t\t{6}
\t\t{7}
\t\t{8}
\t\t{9}
\t\tGeneral Disposition: {10}
\t\tMost important thing is: {11}
\t\tWho is to blame for worlds problems: {12}
\t\tHow to solve the worlds problems: {13}
""".format(name, age, gender_id, ethnic_pr, fcd, wg, fogo_fuck, cur_fam,fam_fuk, nat_nur, gen_dis, wha_wor, who_pro, how_pro)

char_shee()
print "Press enter to continue"
raw_input()

# Export to text file?

#character sheet function for writing
def character_sheet():
sheet = []
sheet.append("Name: " + name)
sheet.append("Class: " + character_class)
sheet.append("Class Powers :" + class_power)
sheet.append("Alignment: " + alignment)
sheet.append("Power: {0} {1}".format(pow, pow_mod()))
sheet.append("Intelligence: {0} {1}".format(iq, iq_mod()))
sheet.append("Agility: {0} {1}".format(agi, agi_mod()))
sheet.append("Constitution: {0} {1}".format(con, con_mod()))
sheet.append("Cynicism {0} {1}".format(cyn, cyn_mod()))
sheet.append("Charisma: {0} {1}".format(cha, cha_mod()))
sheet.append("Money: " + str(gold))
sheet.append("""
\t\t{0}'s History
\t\t------------------
\t\tAge:{1}
\t\t{2}
\t\t{3}
\t\t{4}
\t\t{5}
\t\t{6}
\t\t{7}
\t\t{8}
\t\t{9}
\t\tGeneral Disposition: {10}
\t\tMost important thing is: {11}
\t\tWho is to blame for worlds problems: {12}
\t\tHow to solve the worlds problems: {13}
""".format(name, age, gender_id, ethnic_pr, fcd, wg, fogo_fuck, cur_fam,fam_fuk, nat_nur, gen_dis, wha_wor, who_pro, how_pro))

# Return the string with newlines
return '\n'.join(sheet)

print """Just because I like you, let me know if you want this character
saved to a text file. Please remember if you save your character not to
name it after something important, or you might lose it.
"""
text_file = raw_input("Please type 'y' or 'n', if you want a .txt file > ")
if text_file == "y":
filename = raw_input("\nWhat are we calling your file, include .txt > ")
target = open(filename, 'w')
target.write(character_sheet())
target.close()
print "\nOk I created your file."
print """
Thanks so much for using the Cyberpanky N.O.W Character Generator
By Ray Weiss
Goodbye
"""
else:
print """
Thanks so much for using the Cyberpanky N.O.W Character Generator
By Ray Weiss
Goodbye
"""

• Small tip, that top comment should be a docstring. May 23 '15 at 16:34

def roll_stats():
a = random.randint(1, 6)
b = random.randint(1, 6)
c = random.randint(1, 6)
d = random.randint(1, 6)
list = [a, b, c, d]


Call it dice or something more descriptive then list. You can also use list = [random.randint(1,6) for x in xrange(4)] rather then creating the variables separately.

    list.sort()


Instead of sorting it and slicing it use: list.remove(min(list))

    return add


Don't assign variables just to return them on the next line, use return sum(list[1:4])

def pow_mod():
a = "|+1 to hit on mele attack rolls| "
b = "|+1 damage on mele attack rolls|"

if pow >= 15 and pow < 17:


Don't take input to a function from global variables, pass it as a parameter

        return a
if pow >= 17:
return a + b
else:
return " ~no modifiers~"


You return strings, but conceptually you are returning a list of modifiers. I suggest returning the list. You can then format the list anyway you like in the caller.

You've got a number of functions very similiar to this, it suggests moving some of the details into data structures. I'd do it like this:

POW_MODIFIERS = [
# specify minimum and maximum stat the modifier applies to
(15, 9999, "+1 to hit on mele attack rolls"),
(17, 9999, "+1 damage on mele attack rolls")
]

def calc_modifiers(stat, modifiers):
return [modifier for minimum, maximum, modifier in modifiers if minimum <= state <= maximum]

def format_modifiers(modifiers):
if modifiers:
return ' '.join('|%s|' % modifier for modifier in modifiers)
else:
return ' ~no modifiers~ '


By creating lists like POW_MODIFIERS for all your stats, you can reuse the functions for all the different stats. You should be able to apply similiar techniques to your other decisions. I'd also look at storing the data in a seperate file, perhaps using JSON.

I would suggest moving all your top level code into a main() routine and collecting it all in one place rather than having top level code and routines interspersed. I like to structure my code like this:

import sys

def main():
... top level code ...
routine1()
...
routine2()
...
all_done()

def routine1():
... do work here ...

def routine2():
... do work here ...

def all_done():
... finish up ...

if __name__ == '__main__':
main(sys.argv)


By doing it this way, if my code is in a file named, say, 'code.py', I can play with in the python interpreter by doing, eg.

python
>>> import code
>>> code.all_done()       # test routine all_done() by itself
>>> ^D


With the top level code interspersed with the function definitions, when you try to import code, it all gets run. You can't run the pieces independently.