HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

LPTHW exercise 36 game

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
gameexerciselpthw

Problem

This has taken me months to complete. From what little testing I have done, it seems to work. Let me know what I can do to spruce things up. I can't wait to start learning some more advanced concepts that would have made this easier.

```
# Imports, lots of imports,

from random import randint

from random import choice

import pprint

from sys import exit

#Setting some core stats
wins = 0
times_trained = 0
gold = randint(1, 3) + 2

# Start Streen
def start_screen():
print"""
\t\tTHE LEGEND OF DOOBIEUS ARENA

\t\tProgrammed poorly by Ray Weiss
"""
next()

#Some Quips for the barracks
def gladiator_quips():

q = []
q.append('A warrior grunts, "A sword is more versatile than other weapons."')
q.append('A rogue remarks "Oi I heard that training improves your primary skills."')
q.append('A wench stats "At least you can fight for your freedom %s."' % character_class)
q.append('A drunk sings you a song of the legend of Doobieus poorly.')
q.append('A guard remarks how his polearm gets more lucky hits')
q.append('A slave mentions that maces pack a heavy punch.')
q.append('A barkeep laments "I need a vacation."')
q.append('A one eyed gladiator recalls his youth before slavers killed his family.')
q.append('A child remarks how training can affect abilities.')
quips = choice(q)
print quips

#nice little function that brings up the next page prompt
def next():
raw_input("Press Enter To Continue...")

# Barracks need to restrict training after training. Also need to
# add training restrictions.
def barracks():
print """
Welcome to the barracks %s
^^^^ ^^^^^^^^^^^^^^^^
>----
~ MMM ~
{ } mmm ~~~ [~~~] { } mmm ~~~
{ } |||D _______ [~~~] { } |||D _______
{ } ||| [~~~] { } |||
--------------------------------------------------

Solution

The good news - you'll have to totally rewrite your game. But first...

gladiator_quips - quips would be better as a global constant, considering that it never changes, although one entry will need to be added after the character is generated.

The training code contains a serious error - you pass the value of the statistic to be changed, but you don't allow the possibility that there may be more than one with the same value. Instead, pass the name of the stat.

if 'str' in answer and gold >= 7:
    train_code('str')


and then use it as follows:

if stat == 'str':


train includes global for variables that it doesn't use. I shall refer you to Console weapons shop for adventure game -
try to avoid (restrict) the use of global. It also doesn't global something it should (check). Remember - global is tricky.

Also wrt check, it's only used in two places, one function to set it, the other to use it - there's no need for it at all, since it doesn't really serve any purpose - just do

`if random.randint( 1, 6 ) != 1:`


on the one occasion it's used, and eliminate one global!

train can also be simplified (and improved) a bit by noticing that part of each condition is repeated:

def train():
    print  TRAIN_STATEMENT % (name, gold)
    answer = raw_input(":> ")
    if 'quit' in answer:
        print "You leave the training area."
        next()
        barracks()
    elif gold >= 7:
        if 'str' in answer:
            train_code("str")
        elif 'dex' in answer:
            train_code("dex")
        elif 'con' in answer:
            train_code("con")
        else: 
            print """"You typed in an error (%s)""" % (answer)
            next()
            train()
    else:
        print """"You don't have enough gold (%d gp,)""" % (gold)
        next()
        train()


I'm going to suggest (again!) isolating the use of a global to a specific function, so you have functions similar to:

def change_gold( delta_gold ):
    global gold
    gold = gold + delta_gold
    character_sheet[9] = "You have %s gold pieces." % gold


There's no need to remove and reinsert list elements, just change them.
Also, change_strength, change_dexterity, change_weapon etc. There is a very good reason for this, which you will learn as soon as you learn about classes. I note that you already have a function called gold_math which does the above function, but there are two problems:
1) the parameter is called weapon_price, which doesn't make sense if that's not the function is used for - it could also be used for training costs, thereby reducing duplication.
2) the name itself doesn't say what the function does, 'math' doesn't mean anything.

times_trained is also badly used - it's used as a boolean, so use True and False for its values, and rename it to something like has_been_trained, since that's what it represents.

I'm uncertain whether hit_check does what you want - do you really intend to call d20 etc multiple times, or do you intend only once?

this_to_hit = d20()
this_crit = d100()
if x == 'p':
    if this_to_hit >= to_hit and this_crit = to_hit: # this_crit > crit is implied
        monster_current_hp = monster_current_hp - dmg
        print "You wounded the %s!" % monster
        next()
    else: 
        print "You missed the %s." % monster
        next()
#etc


There is (a lot) more to say, but it's now time to say something about the structure of the program, since you've now learnt about while loops.

If you follow the function calls that your program is making, they go something like:

start_screen()
character_gen()
    buy_weapon()
        weapon_code()
            barracks()
                train()
                    train_code()
                        barracks()
                            etc


where every function call chains off to another call, never returning - you can see this by the stack trace that occurs when, for example, you're killed.
This was OK while you didn't know about loops, but this can (and should!) now be improved. What you need to do is adapt your code such that it follows the following structure:

start_screen()
character_gen()
buy_weapon()
while True:
    action = barracks()
    if action == "talk":
        print gladiator_quips()
    elif action == "training":
        train()
    elif action == "stats":
        stats()
    elif action == "arena":
        alive = combat_engine()
        if ( not alive ) or beaten_all_arena:
            break
    elif action == "quit"
        break
do_closing_action()


It will take some time, but it will be well worth it for your project.

Code Snippets

if 'str' in answer and gold >= 7:
    train_code('str')
if stat == 'str':
`if random.randint( 1, 6 ) != 1:`
def train():
    print  TRAIN_STATEMENT % (name, gold)
    answer = raw_input(":> ")
    if 'quit' in answer:
        print "You leave the training area."
        next()
        barracks()
    elif gold >= 7:
        if 'str' in answer:
            train_code("str")
        elif 'dex' in answer:
            train_code("dex")
        elif 'con' in answer:
            train_code("con")
        else: 
            print """"You typed in an error (%s)""" % (answer)
            next()
            train()
    else:
        print """"You don't have enough gold (%d gp,)""" % (gold)
        next()
        train()
def change_gold( delta_gold ):
    global gold
    gold = gold + delta_gold
    character_sheet[9] = "You have %s gold pieces." % gold

Context

StackExchange Code Review Q#18167, answer score: 4

Revisions (0)

No revisions yet.