I have decided that a text adventure would be better for me to learn from, as a visual game is confusing to me still. So, I was reading Chris O'leary's post about his text adventure game, Advent House, and got many ideas from there. I want to perfect his battle sequence though.
Here is the code he used with minor adjustments on my part in the random module. If someone could tell me where I am going wrong and give me an example I would greatly appreciate it!

# adding to christ o'leary's fight function
# to have integer returned use
# x = random.choice([0, 1])
# print x, type(x) # testing

# or x = random.randrange(0, 2)
# print x, type(x)

def main():
    global monster_HP1
    monster_HP1 = 5
    global hp
    hp = 10
    print """you are in a fight!
    Type 'h' to fight"""
    x = raw_input(': ')
    if x == 'h':
        fight_unicorn()
    else:
        print "Error"
        main()
        
def fight_unicorn():
    global monster_HP1
    global hp
    hit_miss = random.randrange(0, 2)
    print x, type(x)
    if hit_miss == 1:
        print "You hit the monster!"
        monster_HP1 = monster_HP1 - 1
        if monster_HP1 == 0:
            print "You win!"
            master_bedroom()
        else:
            monster_turn1()
    else:
        print "You Missed"
        monster_turn1()
def monster_turn1():
    monster_hit = random.randrange(0, 2)
    print x, type(x)
    if monster_hit == 1:
        print "You are hit!"
        hp = hp-1
        if hp == 0:
            print "Game Over"
    else:
        print "The monster missed"
        fight_unicorn()
main()

Recommended Answers

All 6 Replies

# adding to christ o'leary's fight function
# to have integer returned use
# x = random.choice([0, 1])
# print x, type(x) # testing

# or x = random.randrange(0, 2)
# print x, type(x)
import random

def main():
    global monster_HP1
    monster_HP1 = 5
    global hp
    hp = 10
    print """you are in a fight!
    Type 'h' to fight"""
    x = raw_input(': ')
    if x == 'h':
        fight_unicorn()
    else:
        print "Error"
        main()
        
def fight_unicorn():
    global monster_HP1
    global hp
    hit_miss = random.randrange(0, 2)
    #print x, type(x)
    if hit_miss == 1:
        print "You hit the monster!"
        monster_HP1 = monster_HP1 - 1
        if monster_HP1 == 0:
            print "You win!"
            master_bedroom()
        else:
            monster_turn1()
    else:
        print "You Missed"
        monster_turn1()
def monster_turn1():
    monster_hit = random.randrange(0, 2)
    #print x, type(x)
    global hp
    if monster_hit == 1:
        print "You are hit!"
        hp = hp-1
        if hp == 0:
            print "Game Over"
        else:
            fight_unicorn()
    else:
        print "The monster missed"
        fight_unicorn() # ADD IN
main()

i simply took out the print x, type(x) and added in a call back to fight unicorn

Chris

Well, that solved one problem, now I get a loop of you hit the monster/you missed the monster/ the monster hit/missed you. It goes on for a while and the ends the program. I checked my function calls and couldn't see the problem. It is probably so easy it's staring me right in the face without me knowing it.
here is the code now:

# adding to christ o'leary's fight function
# to have integer returned use
# x = random.choice([0, 1])
# print x, type(x) # testing

# or x = random.randrange(0, 2)
# print x, type(x)
import random

global monster_HP1
monster_JP1 = 5
global hp
hp = 20

def main():
    global monster_HP1
    monster_HP1 = 5
    global hp
    hp = 10
    print """you are in a fight!
    Type 'h' to fight"""
    x = raw_input(': ')
    if x == 'h':
        fight_unicorn()
    else:
        print "Error"
        main()
        
def fight_unicorn():
    global monster_HP1
    global hp
    hit_miss = random.randrange(0, 2)
    # print x, type(x)
    if hit_miss == 1:
        print "You hit the monster!"
        monster_HP1 = monster_HP1 - 1
        if monster_HP1 == 0:
            print "You win!"
        else:
            monster_turn1()
    else:
        print "You Missed"
        monster_turn1()
def monster_turn1():
    global monster_HP1
    monster_HP1 = 5
    global hp
    hp = 20
    monster_hit = random.randrange(0, 2)
    # print x, type(x)
    if monster_hit == 1:
        print "You are hit!"
        hp = hp-1
        if hp == 0:
            print "Game Over"
    else:
        fight_unicorn() # Chris added this for me
        print "The monster missed"
        fight_unicorn()
main()

I think this would be better written in a non recursive way like this

# adding to christ o'leary's fight function

import random
import sys

global monster_HP1
monster_HP1 = 5
global hp
hp = 7

def main():
    global monster_HP1, hp
    print """you are in a fight!
    Type 'h' to fight"""
    x = raw_input(': ')
    if x == 'h':
      while True:
        if your_turn():
          break
        if monster_turn1():
          sys.exit(0)
    else:
        print "Error"
        
def your_turn():
    global monster_HP1, hp
    hit_miss = random.randrange(0, 2)
    # print x, type(x)
    if hit_miss == 1:
        print "You hit the monster!"
        monster_HP1 = monster_HP1 - 1
        if monster_HP1 == 0:
            print "You win!"
            return True
    else:
        print "You Missed"
    return False
      
def monster_turn1():
    global monster_HP1, hp
    monster_hit = random.randrange(0, 2)
    # print x, type(x)
    if monster_hit == 1:
        hp = hp-1
        if hp == 0:
            print "The monster killed you!"
            print "Game Over"
            return True
        else:
          print "You are hit!"
    else:
        print "The monster missed"
    return False

main()

There are many problems in your code, for example you should not set the global variables in monster_turn1 . I also chose an initial value of hp=7 so that the monster has a chance to win :)

Okay, it still does the same thing, only this time the error log reads:
Traceback (most recent call last):
File "C:/Python25/howtofight.py", line 49, in <module>
main()
File "C:/Python25/howtofight.py", line 19, in main
sys.exit(0)
SystemExit: 0

This is how the battle is supposed to go...

1 press h to fight
user presses h
they hit or miss
monsters turn
monster hits or misses
your turn
user presses h to fight
repeat until one of you is dead.


Should I create a seperate function for when it is your turn again and you must press h? And, what is wrong with my code that it exits at the end of the program?
sys.exit is set to 0, so it shouldn't exit, right?

Okay, I fixed it a little bit. But it seems like I always lose. I set the global hp to 10, and it still lost. Is it not registering when the monster gets hit? Also, it seems like it is taking more that one turn at a time. Usually, it prints:
You hit the monster
you miss

then the monster take like five turns.
here is the new code:

import random
import sys

global monster_hp1
monster_hp1 = 5
global hp
hp = 10

def init_game():
    print """Welcome to NayNay's Quest"""
    main()
def main():
    global monster_hp1, hp
    print """You are in a fight
    type 'h' to fight """
    x = raw_input(': ')
    if x == 'h':
        while True:
            if your_turn():
                break
            if monster_turn1():
                sys.exit(0)
        else:
            print "Error"

def your_turn():
    global monster_hp1, hp
    hit_miss = random.randrange(0, 2)
    if hit_miss == 1:
        print "You hit the monster!"
        monster_hp1= monster_hp1 = -1
        if monster_hp1 == 0:
            print "You win"
            return True
        else:
            print "You missed."
        return False

def monster_turn1():
    global monster_hp1, hp
    monster_hit= random.randrange(0, 2)
    if monster_hit == 1:
        hp = hp -1
        if hp == 0:
            print "The monster killed you!"
            print "game over"
            init_game()
            return True
        else:
            print "The monster missed"
        return False
    main()

init_game()

Now what is wrong. Also, any suggestions on how to improve my code? I just want to get the battle sequence right before I use it in my game.

Here is how you could cleanly code this with classes. The idea is to follow closely the sequence of events that you described above and to write small functions with a clear meaning

from random import randrange

class InvalidChoice(Exception):
    pass

class QuestGame(object):
    def __init__(self):
        print "Welcome to NayNay's Quest"
        self.player_hp = 7
        
    def run(self):
        fight = FightSequence(self)
        fight.run_forever()

    def player_is_dead(self):
        return self.player_hp <= 0

class FightSequence(object):
    def __init__(self, game):
        self.game = game
        self.init_monster()

    def init_monster(self):
        self.monster_hp = 5
        
    def run_forever(self):
        while True:
            self.game.player_hp = 7
            self.init_monster()
            self.run()

    def run(self):
        try:
            while True:
                self.prompt_user()
                self.player_turn()
                if self.monster_is_dead():
                    print "You win!"
                    break
                self.monster_turn()
                if self.game.player_is_dead():
                    print "The monster killed you!"
                    break
        except InvalidChoice:
            pass

    def prompt_user(self):
        print """
You are in a fight
Type 'h' to fight""",
        choice = raw_input(': ')
        if choice != 'h':
            print "Error: invalid choice '%s'" % choice
            raise InvalidChoice

    def player_turn(self):
        hit_miss = randrange(0,2)
        if hit_miss:
            print "You hit the monster!"
            self.monster_hp -= 1
        else:
            print "You missed."

    def monster_turn(self):
        hit_miss = randrange(0,2)
        if hit_miss:
            print "The monster hit you!"
            self.game.player_hp -= 1
        else:
            print "The monster missed."

    def monster_is_dead(self):
        return self.monster_hp <= 0

game = QuestGame()
game.run()
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.