get this combat engine working? - python

Currently stuck on exercise 36 of Zed Shaw's LPTHW and I could really use some help figuring out why this combat engine I made isn't working. I rewrote an earlier attempt to try to make it more clear. Here is the relevant code I believe, I apologize if its too long, but as a newbie I'm not entirely sure what is relevant.
#Check to hit and applies damage / crit + damage use p for player and m for monster
def hit_check(x):
global current_hp, monster_current_hp, to_hit, monster_to_hit, crit
global monster_crit, dmg, monster, monster_dmg
if x == 'p':
if d20() >= to_hit and d100() <= crit:
monster_current_hp = monster_current_hp - dmg * 3
print "You critically wounded the %s!" % monster
next()
elif d20() >= to_hit and d100() > crit:
monster_current_hp = monster_current_hp - dmg
print "You wounded the %s!" % monster
next()
else:
print "You missed the %s." % monster
next()
elif x == 'm':
if d20() >= monster_to_hit and d100() <= monster_crit:
current_hp = current_hp - monster_dmg * 3
print "The %s critically wonded %s!" % (monster, name)
next()
elif d20() >= to_hit and d100() > crit:
current_hp = current_hp - dmg
print "The %s wounded %s." % (monster, name)
next()
else:
print "The %s missed %s." % (monster, name)
next()
else:
print "Ray diddnt correctly assign a hit check"
exit(0)
# Combat engine / prompt
def combat_engine():
global current_hp, monster_current_hp, wins, gold, hit_points, p, m
"""Will choose a monster, and then allow the player to fight monster"""
global current_hp, monster_current_hp, prompt
if wins == 0:
choose_monster(level_zero_monsters)
elif wins == 1:
choose_monster(level_one_monsters)
elif wins == 2:
choose_monster(level_two_monsters)
elif wins == 3:
choose_monster(level_three_monsters)
elif wins == 4:
choose_monster(level_four_monsters)
else:
print "bug in choosing monsters over wins"
exit(0)
print """
Welcome %s to the Arena
Today you will be fighting a %s
Description of monster: %s
""" % (name, monster, description)
next()
running = True
while running:
if current_hp > 0 and monster_current_hp > 0:
prompt = raw_input("Type 'a' to attack, 's' for stats, 'q' for quit :> ")
if prompt == 'a':
hit_check('p')
hit_check('m')
elif current_hp <= 0:
break
print "You were killed by the %s, better luck next time."
exit()
elif monster_current_hp <= 0:
break
print "You defeated the %s! Great Job!"
next()
if wins == 0:
gold_earned = d6() + 2
elif wins == 1:
gold_earned = d6() + d6() + 2
elif wins == 2:
gold_earned = d6() + d6() + 4
elif wins == 3:
gold_earned = d6() + d6() + 5
elif wins == 4:
gold_earned = d6() + d6() + 6
else:
break
print "There is a bug you have wins than allowed"
exit(0)
gold = gold + gold_earned
print "You win %d gold, you have %d gold total." % (gold_earned,
gold)
wins = wins + 1
hit_points = hit_points + d6()
hit_points = current_hp
print "You feel hardier. You make your way back to the barracks."
next()
barracks()
else:
break
print "Bug in combat engine"
exit(0)
When I run this here is what the terminal prints, It's for some reason dumping to the inventory party of my code.
Welcome Ray to the Arena
Today you will be fighting a goblin
Description of monster: A tiny miserable creature that lives to eat shit.
Press Enter To Continue...
Type 'a' to attack, 's' for stats, 'q' for quit :> a
You missed the goblin.
Press Enter To Continue...
The goblin missed Ray.
Press Enter To Continue...
Type 'a' to attack, 's' for stats, 'q' for quit :> a
You wounded the goblin!
Press Enter To Continue...
The goblin wounded Ray.
Press Enter To Continue...
Your current weapon is now a dagger. Press Enter To Continue
logout
[Process completed]
Any help or advice as to how to tackle this issue would be greatly appreciated.
edit: Here is the whole code so people can get it to run.
# 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
#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
^^^^ ^^^^^^^^^^^^^^^^
>----<|arena|training|>
~ MMM ~ <|shop<| _ | __ |>
{ } mmm ~~~ [~~~] { } mmm ~~~ <| <|{}\ | /{}\ |>
{ } |||D _______ [~~~] { } |||D _______ <| -||- | -||- |>
{ } ||| <uuuuuuu> [~~~] { } ||| <uuuuuuu> <| ||| | || |>
-------------------------------------------------------------------------
There are several other gladiators moving around, you may 'talk' to them.
You can take a look at your 'stats'
You can 'shop' for new weapons.
You may enroll in skill 'training' nearby.
You may face your next opponent in the 'arena'.
You may give up on your quest for freedom & 'quit'
""" % name
answer = raw_input(":> ")
if "talk" in answer:
gladiator_quips()
next()
barracks()
elif "stats" in answer:
pp = pprint.PrettyPrinter(indent=30)
pp.pprint(character_sheet)
next()
barracks()
elif "training" in answer:
if times_trained == 0:
train()
else:
print "The training center is now closed."
next()
barracks()
elif "arena" in answer:
combat_engine()
elif "quit" in answer:
print "You are now a slave forever. Goodbye %s." % name
exit(0)
elif "shop" in answer:
if wins == 0:
print "The shop is closed for the day, you must win your first fight"
next()
barracks()
elif wins == 1:
buy_weapon(level_one_weapons)
elif wins == 2:
buy_weapon(level_two_weapons)
elif wins == 3:
buy_weapon(level_three_weapons)
elif wins == 4:
buy_weapon(level_four_weapons)
else:
print "Ray left a bug somewhere. Ballz."
exit(0)
else:
print "I didn't understand %s, please try again." % answer
next()
barracks()
#training code
def train_code(stat):
if check != 1:
gold = gold - 7
character_sheet.remove(character_sheet[9])
character_sheet.insert(9, "You have %d gold pieces." % gold)
times_trained = 1
stat = stat + 1
if stat == str:
character_sheet.remove(character_sheet[3])
character_sheet.insert(3, "Strength: %s" % str)
elif stat == dex:
character_sheet.remove(character_sheet[4])
character_sheet.insert(3, "Dexterity: %s" % dex)
elif stat == con:
character_sheet.remove(character_sheet[5])
character_sheet.insert(3, "Constiution: %s" % cond)
else:
print "Ray left a stupid bug somewhere"
print "You feel stronger and return to the barracks as training closes."
next()
barracks()
else:
times_trained = 1
gold = gold - 7
character_sheet.remove(character_sheet[9])
character_sheet.insert(9, "You have %s gold pieces." % gold)
print "You feel like the training was useless. You return to the barracks as training closes."
next()
barracks()
# training room
def train():
global gold, str, dex, con
print """
Welcome %s to the training center.
You currently have %d gold pieces.
You may enroll in one class before each battle.
Keep in mind, there is a chance you will fail to learn anything.
Training costs 7 gold pieces.
You may train 'str', 'dex', or 'con'
Type 'quit' if you wish to return to the barracks.
Which stat do you wish to train?
""" % (name, gold)
answer = raw_input(":> ")
check = randint(1, 6)
if 'str' in answer and gold >= 7:
train_code(str)
elif 'dex' in answer and gold >= 7:
train_code(dex)
elif 'con' in answer and gold >= 7:
train_code(con)
elif 'quit' in answer:
print "You leave the training area."
next()
barracks()
else:
print """"You either dont have enough gold (%s gp,) or you typed in an error (%s)
""" % (gold, answer)
next()
train()
#dice
def d20():
return randint(1, 20)
def d100():
return randint(1, 100)
def d6():
return randint(1, 6)
# Doing Stuff for weapons and the shopkeeper. #################################
def level_zero_price():
"""Generates the price for level one weapons"""
return randint(1, 3)
def level_one_price():
"""Generates the price for level two weapons"""
return randint(3, 6)
def level_two_price():
"""Generates the price for level three weapons"""
return randint(6, 9)
def level_three_price():
"""Generates the price for level four weapons"""
return randint(9, 12)
def level_four_price():
"Generates the price for level four weapons"""
return randint(12, 15)
#weapon inventory code
def weapon_code(weapons):
global current_weapon
weapon_choice = raw_input(":> ")
if weapons[0] in weapon_choice and gold >= sword_price:
gold_math(agile_price)
if wins != 0:
character_sheet.remove(character_sheet[10])
else:
current_weapon = weapons[2]
inventory(weapons[2])
character_sheet.append("Current Weapon: %s" % current_weapon)
barracks()
elif weapons[1] in weapon_choice and gold >= blunt_price:
gold_math(agile_price)
if wins != 0:
character_sheet.remove(character_sheet[10])
else:
current_weapon = weapons[2]
inventory(weapons[2])
character_sheet.append("Current Weapon: %s" % current_weapon)
barracks()
elif weapons[2] in weapon_choice and gold >= agile_price:
gold_math(agile_price)
if wins != 0:
character_sheet.remove(character_sheet[10])
else:
current_weapon = weapons[2]
inventory(weapons[2])
character_sheet.append("Current Weapon: %s" % current_weapon)
barracks()
elif "quit" in weapon_choice and wins != 0:
barracks()
elif "quit" in weapon_choice and wins == 0:
print "You must buy a weapon first before you can go to the barracks."
next()
buy_weapon(level_zero_weapons)
else:
print "Either you dont have enough money, or I dont know what %s means" % weapon_choice
next()
buy_weapon(weapons)
# price display
def prices(weapons):
print """
Please type in the weapon you want to buy.
%s, price: %d gold pieces
%s, price: %d gold pieces
%s, price: %d gold pieces.
""" % (weapons[0], sword_price, weapons[1], blunt_price,weapons[2],
agile_price)
# gold buying
def gold_math(weapon_price):
global gold
character_sheet.remove(character_sheet[9])
gold = gold - weapon_price
character_sheet.insert(9, "You have %s gold pieces." % gold)
### Shop / buy weapons room ###############
def buy_weapon(weapons):
global gold, sword_price, blunt_price, agile_price, current_weapon
"""big bit of code that allows you to buy a weapons from a weapon list.
The function acts a little differently after level zero weapons"""
global current_weapon
if weapons == level_zero_weapons:
sword_price = level_zero_price()
blunt_price = level_zero_price()
agile_price = level_zero_price()
prices(level_zero_weapons)
weapon_code(level_zero_weapons)
elif weapons == level_one_weapons:
sword_price = level_one_price()
blunt_price = level_one_price()
agile_price = level_one_price()
prices(level_one_weapons)
weapon_code(level_one_weapons)
elif weapons == level_two_weapons:
sword_price = level_two_price()
blunt_price = level_two_price()
agile_price = level_two_price()
prices(level_two_weapons)
weapon_code(level_two_weapons)
elif weapons == level_three_weapons:
sword_price = level_three_price()
blunt_price = level_three_price()
agile_price = level_three_price()
prices(level_three_weapons)
weapon_code(level_three_weapons)
elif weapons == level_four_weapons:
sword_price = level_four_price()
blunt_price = level_four_price()
agile_price = level_four_price()
prices(level_four_weapons)
weapon_code(level_four_weapons)
else:
print"~~~There is a bug somwhere, forgot to assign (weapons)\n\n\n"
raw_input("""
Your current weapon is now a %s. Press Enter To Continue
""" % current_weapon)
def inventory(current_weapon):
"""Attaches modifiers to secondary stats according to current weapon """
global mod_dmg, mod_crit
if current_weapon == level_zero_weapons[0]:
mod_dmg = dmg
mod_crit = crit
elif current_weapon == level_zero_weapons[1]:
mod_dmg = dmg + 1
mod_crit = crit
elif current_weapon == level_zero_weapons[2]:
mod_dmg = dmg
mod_crit = crit + 3
elif current_weapon == level_one_weapons[0]:
mod_dmg = dmg + 1
mod_crit = crit + 3
elif current_weapon == level_one_weapons[1]:
mod_dmg = dmg + 2
mod_crit = crit
elif current_weapon == level_one_weapons[2]:
mod_dmg = dmg
mod_crit = crit + 5
elif current_weapon == level_two_weapons[0]:
mod_dmg = dmg + 1
mod_crit = crit + 5
elif current_weapon == level_two_weapons[1]:
mod_dmg = dmg + 3
mod_crit = crit
elif current_weapon == level_two_weapons[2]:
mod_dmg = dmg
mod_dmg = crit + 6
elif current_weapon == level_three_weapons[0]:
mod_dmg = dmg + 2
mod_crit = crit + 5
elif current_weapon == level_three_weapons[1]:
mod_dmg = dmg + 4
mod_crit = crit + 3
elif current_weapon == level_three_weapons[2]:
mod_dmg = dmg + 1
mod_crit = + 8
elif current_weapon == level_four_weapons[0]:
mod_dmg = dmg + 3
mod_crit = crit + 7
elif current_weapon == level_four_weapons[1]:
mod_dmg = dmg + 5
mod_crit = crit + 5
elif current_weapon == level_four_weapons[2]:
mod_dmg = dmg + 2
mod_crit = crit + 10
else:
print"There is a bug, ray forgot a weapon or typed shit wrong."
exit(0)
#End Of Buying / Inventory functions ##########################################
#function for monster damage
def monster_dice(a, b):
return randint(a, b)
#Function for monster stats
def monster_stats(a, b, c, d):
global monster_current_hp, monster_crit, monster_dmg, monster_to_hit
monster_current_hp = a
monster_crit = b
monster_dmg = monster_dice(1, c)
monster_to_hit = d
# Chooses a random monster and sets stats
def choose_monster(monster_list):
global monster, description
if monster_list == level_zero_monsters:
monster = choice(level_zero_monsters)
if monster == 'wolf':
monster_stats(4, 5, 6, 12)
description = "A small and angry dog like creature."
elif monster == 'goblin':
monster_stats(5, 7, 5, 10)
description = "A tiny miserable creature that lives to eat shit."
elif monster == 'kobold':
monster_stats(6, 10, 4, 9)
description = "A small humaniod lizard, very sneaky and annoying"
else:
print "Bug in choose monster level 0"
exit(0)
elif monster_list == level_one_monsters:
monster = choice(level_one_monsters)
if monster == 'orc':
monster_stats(6, 8, 6, 10)
description = "A human sized horrid creature, smells awful."
elif monster == 'gnoll':
monster_stats(7, 10, 8, 12)
description = "A large humanoid dog, they can cackle for hours."
elif monster == 'giant ant':
monster_stats(8, 7, 7, 11)
description = "A large and terrifying insect, it makes clicking noises."
else:
print "Bug in choose monster level 1"
exit(0)
elif monster_list == level_two_monsters:
enemy = choice(level_two_monsters)
if monster == 'wight':
monster_stats(9, 10, 10, 12)
description = "A powerful undead warrior, terrifying in size."
elif monster == 'komodo dragon':
monster_stats(7, 12, 8, 10)
description = "A deadly man sized lizard, very sharp teeth."
elif monster == 'ogre':
monster_stats(10, 5, 12, 11)
description = "A Big and strong stupid ogre."
else:
print "Bug in monster level 2"
elif monster_list == level_three_weapons:
monster = choice(level_three_monsters)
if monster == 'troll':
monster_stats(12, 7, 12, 11)
elif monster == 'owlbear':
monster_stats(10, 12, 11, 10)
elif monster == 'dark priest':
monster_stats(9, 13, 10, 9)
else:
print "Bug in monster level 3"
elif monster_list == level_four_monsters:
monster = choice(level_four_monsters)
if monster == 'dark wizard':
monster_stats(11, 15, 12, 9)
elif monster == 'hydra':
monster_stats(12, 14, 15, 10)
elif monster == 'stone golem':
monster_stats(15, 13, 13, 11)
else:
print "Problem with monster level 4"
else:
print "Ray left diddnt assign a correct combat(argv)"
exit(0)
#Check to hit and applies damage / crit + damage use p for player and m for monster
def hit_check(x):
global current_hp, monster_current_hp, to_hit, monster_to_hit, crit
global monster_crit, dmg, monster, monster_dmg
if x == 'p':
if d20() >= to_hit and d100() <= crit:
monster_current_hp = monster_current_hp - dmg * 3
print "You critically wounded the %s!" % monster
next()
elif d20() >= to_hit and d100() > crit:
monster_current_hp = monster_current_hp - dmg
print "You wounded the %s!" % monster
next()
else:
print "You missed the %s." % monster
next()
elif x == 'm':
if d20() >= monster_to_hit and d100() <= monster_crit:
current_hp = current_hp - monster_dmg * 3
print "The %s critically wonded %s!" % (monster, name)
next()
elif d20() >= to_hit and d100() > crit:
current_hp = current_hp - dmg
print "The %s wounded %s." % (monster, name)
next()
else:
print "The %s missed %s." % (monster, name)
next()
else:
print "Ray diddnt correctly assign a hit check"
exit(0)
# Combat engine / prompt
def combat_engine():
global current_hp, monster_current_hp, wins, gold, hit_points, p, m
"""Will choose a monster, and then allow the player to fight monster"""
global current_hp, monster_current_hp, prompt
if wins == 0:
choose_monster(level_zero_monsters)
elif wins == 1:
choose_monster(level_one_monsters)
elif wins == 2:
choose_monster(level_two_monsters)
elif wins == 3:
choose_monster(level_three_monsters)
elif wins == 4:
choose_monster(level_four_monsters)
else:
print "bug in choosing monsters over wins"
exit(0)
print """
Welcome %s to the Arena
Today you will be fighting a %s
Description of monster: %s
""" % (name, monster, description)
next()
running = True
while running:
if current_hp > 0 and monster_current_hp > 0:
prompt = raw_input("Type 'a' to attack, 's' for stats, 'q' for quit :> ")
if prompt == 'a':
hit_check('p')
hit_check('m')
elif current_hp <= 0:
break
print "You were killed by the %s, better luck next time."
exit()
elif monster_current_hp <= 0:
break
print "You defeated the %s! Great Job!"
next()
if wins == 0:
gold_earned = d6() + 2
elif wins == 1:
gold_earned = d6() + d6() + 2
elif wins == 2:
gold_earned = d6() + d6() + 4
elif wins == 3:
gold_earned = d6() + d6() + 5
elif wins == 4:
gold_earned = d6() + d6() + 6
else:
break
print "There is a bug you have wins than allowed"
exit(0)
gold = gold + gold_earned
print "You win %d gold, you have %d gold total." % (gold_earned,
gold)
wins = wins + 1
hit_points = hit_points + d6()
hit_points = current_hp
print "You feel hardier. You make your way back to the barracks."
next()
barracks()
else:
break
print "Bug in combat engine"
exit(0)
def you_win():
print """
YOU WIN!
CONGRATULATIONS!
THANKS FOR PLAYING!
"""
# Monster List
level_zero_monsters = ['wolf', 'goblin', 'kobold']
level_one_monsters = ['orc', 'gnoll', 'giant ant',]
level_two_monsters = ['wight', 'komodo dragon', 'ogre']
level_three_monsters = ['troll', 'owlbear', 'dark priest']
level_four_monsters = ['dark wizard', 'hydra', 'stone golem']
# Weapon lists
level_zero_weapons = ['short sword', 'club', 'dagger']
level_one_weapons = ['sword', 'mace', 'rapier']
level_two_weapons = ['long sword', 'morningstar', 'trident']
level_three_weapons = ['claymore', 'flail', 'sycthe']
level_four_weapons = ['bastard sword', 'dragon bone', 'crystal halbred']
def roll_3d6():
"""This rolls 3D6, and returns the sum."""
return randint(1, 6) + randint(1, 6) + randint(1, 6)
def character_gen():
"""Creates A character and also can call character sheet"""
global name, str, dex, con, hit_points, dmg, crit, character_class
global gender, damage_print, current_hp, character_sheet, to_hit
character_sheet = []
name = raw_input("Please tell me your name brave soul. :> ")
print "\n\t\tLets now randomly generate brave gladiator %s." % name
str = roll_3d6()
if str > 12:
dmg = randint(1, 6) + 1
damage_print = "1D6 + 1"
else:
dmg = randint(1, 6)
damage_print = "1D6"
dex = roll_3d6()
if dex >= 13:
crit = 15
to_hit = 9
elif dex >= 9 and dex <=12:
crit = 10
to_hit = 10
else:
crit = 10
to_hit = 11
con = roll_3d6()
if con > 14:
hit_points = 8
current_hp = hit_points
else:
hit_points = 6
current_hp = hit_points
if str >= dex:
character_class = "Warrior"
else:
character_class = "Rogue"
random_gender = randint(1, 2)
if random_gender == 1:
gender = "Male"
else:
gender = "Female"
character_sheet.append("Name: %s:" % name)
character_sheet.append("Gender: %s" % gender)
character_sheet.append("Character Class: %s" % character_class)
character_sheet.append("Strength: %s" % str)
character_sheet.append("Dexterity: %s" % dex)
character_sheet.append("Constitution: %s" % con)
character_sheet.append("Damage %s" % damage_print)
character_sheet.append("Crit Chance {}%".format(crit))
character_sheet.append("Hit Points: %s/%s" % (hit_points, current_hp))
character_sheet.append("You have %s gold pieces." % gold)
pp = pprint.PrettyPrinter(indent=30)
pp.pprint(character_sheet)
raw_input("Please Press Enter To Buy A Weapon")
buy_weapon(level_zero_weapons)
#main
character_gen()

Here's a rundown of the flow of your program:
character_gen calls buy_weapon, which calls weapon_code, which calls barracks, which calls combat_engine. Inside combat_engine, once you've reduced the enemy's health to zero or below, it executes the second elif branch, whose first statement is break. This statement causes combat_engine's while loop to terminate. combat_engine ends, so control returns to barracks. barracks ends, so control returns to weapon_code. weapon_code ends, so control returns to buy_weapon. buy_weapon executes whatever code occurs after your call to weapon_code, namely this line:
raw_input("""
Your current weapon is now a %s. Press Enter To Continue
""" % current_weapon)
buy_weapon ends and control returns to character_gen. character_gen ends and control returns to the main module. The main module ends, and your program terminates. This explains why you're getting the output that you're getting.
As for fixing it, I'd suggest two things:
Read up on break to confirm that it's doing what you think it's doing. Anything after break, for example print "You defeated the %s! Great Job!" will never execute under any circumstance.
For the overall flow of your code, look up State Machines. Rather than being functions, barracks/inventory/etc should each be their own state, with the user's input dictating which state to transition into. The way you've got it now, you'll experience a stack overflow after about 500 actions.

Related

Python Error: ValueError: Non-integer arg 1 for randrange()

I'm getting the above error in my code. It's just a simple text-based game.
Here's the code:
import os
import sys
import random
class Player:
def __init__(self, name):
self.name = name
self.maxhealth = 100
self.health = self.maxhealth
self.attack = 10
self.gold = 0
self.potions = 0
class Goblin:
def __init__(self, name):
self.name = name
self.maxhealth = 50
self.health = self.maxhealth
self.attack = 5
self.goldgain = 10
GoblinIG = Goblin("Goblin")
class Zombie:
def __init__(self, name):
self.name = name
self.maxhealth = 70
self.health = self.maxhealth
self.attack = 7
self.goldgain = 15
ZombieIG = Zombie("Zombie")
def main():
#os.system("cls")
print("Welcome to my game!")
print("1) Start")
print("2) Load")
print("3) Exit")
option = input("-> ")
if option == "1":
start()
elif option == "2":
pass
elif option == "3":
pass
else:
main()
def start():
#os.system("cls")
print("Hello, what is your name?")
option = input("-> ")
global PlayerIG
PlayerIG = Player(option)
start1()
def start1():
#os.system("cls")
print("Name: %s" % PlayerIG.name)
print("Attack: %s" % PlayerIG.attack)
print("Gold: %i" % PlayerIG.gold)
print("Potions: %i" % PlayerIG.potions)
print("Health: %i/%i" % (PlayerIG.health, PlayerIG.maxhealth))
print("1) Fight")
print("2) Store")
print("3) Save")
print("4) Exit")
option = input("-> ")
if option == "1":
prefight()
elif option == "2":
store()
elif option == "3":
pass
elif option == "4":
sys.exit()
else:
start1()
def prefight():
global enemy
enemynum = random.randint(1,2)
if enemynum == 1:
enemy = GoblinIG
else:
enemy = ZombieIG
fight()
def fight():
print("%s vs %s" % (PlayerIG.name, enemy.name))
print("%s's Health: %s/%s %s Health: %i/%i" % (PlayerIG.name, PlayerIG.health, PlayerIG.maxhealth, enemy.name, enemy.health, enemy.maxhealth))
print("Potions Left: %s\n" % PlayerIG.potions)
print("1) Attack")
#Implement defend system
print("2) Drink Potion")
print("3) Run")
option = input()
if option == "1":
attack()
elif option == "2":
drinkPotion()
elif option == "3":
run()
else:
fight()
def attack():
global PlayerAttack
global EnemyAttack
PlayerAttack = random.randint(PlayerIG.attack / 2, PlayerIG.attack)
EnemyAttack = random.randint(enemy.attack / 2, enemy.attack)
if PlayerAttack == PlayerIG.attack / 2:
print("You missed!")
else:
enemy.health -= PlayerAttack
print("You dealt %i damage!" % PlayerAttack)
option = input(" ")
if enemy.health <= 0:
win()
if EnemyAttack == enemy.attack/2:
print("The enemy missed!")
else:
PlayerIG.health -= EnemyAttack
print("The enemy dealt %i damage!" % EnemyAttack)
option = input("")
if PlayerIG.health <= 0:
dead()
else:
fight()
def drinkPotion():
if PlayerIG.potions == 0:
print("You don't have any potions!")
else:
PlayerIG.health += 50
if PlayerIG.health >= PlayerIG.maxhealth:
PlayerIG.health = PlayerIG.maxhealth
print("You drank a potion!")
option = input(" ")
fight()
def run():
runnum = random.randint(1,3)
if runnum == 3:
print("You have ran away!")
option = input(" ")
start1()
else:
print("You've failed to run away!")
option = input(" ")
EnemyAttack = random.randint(enemy.attack / 2, enemy.attack)
if EnemyAttack == enemy.attack/2:
print("The enemy missed!")
else:
PlayerIG.health -= EnemyAttack
print("The enemy dealt %i damage!" % EnemyAttack)
option = input(" ")
if PlayerIG.health <=0:
dead()
else:
fight()
def win():
enemy.health = enemy.maxhealth
PlayerIG.gold -= enemy.goldgain
print("You have defeated the %s!" % enemy.name)
print("You found %i gold!" % enemy.goldgain)
option = input(" ")
start1()
def dead():
print("You have died!")
option = input(" ")
def store():
pass
main()
I get the error in def run(), in the else: statement. The line that goes like: EnemyAttack = random.randint(enemy.attack / 2, enemy.attack)
Any ideas? Should I elaborate more on my issue? Thanks :)
Use EnemyAttack = random.randint(math.floor(enemy.attack / 2), enemy.attack), or use math.ceil() to round the result of enemy.attack / 2.
randrange() expects whole integers. The error is occurring because the result of enemy.attack / 2 isn't a whole number; it has decimal places whenever enemy.attack is odd. One option is to scale randrange() after it is calculated if you need decimal results.
For example: 0.5*randrange(2*(enemy.attack/2), 2*enemy.attack), which can be simplified into 0.5*randrange(enemy.attack, 2*enemy.attack)

Python: CARD GAME BOT - Remastering (How do you make a line continue regardless of where it is?)

I'm remastering the bot by my self and I'm stuck! This is a code which prompts the user to select how many cards they get from the options of
7, 9, 11, and 15
def Cards():
print("Card Amounts")
print("\nChoices")
print(7)
print(9)
print(11)
print(15)
PlayerInput3()
def PlayerInput3():
global PlayersCards
PlayerInput = int(raw_input())
if(PlayerInput == 7):
PlayersCards == range(1,7)
print("Lets get started")
Game()
But when they choose how many cards they want it does stay into affect after the definition is over. I want the Players card range to continue in a different defined area. Here:
def Game():
global roundNumber, MyDeck, PlayersCards
import random
Select = PlayersCards
roundNumber = roundNumber + 1
print("Round %d!") % (roundNumber)
if(roundNumber == 1) or (roundNumber < 15):
PlayersCards = random.randint(1, 50)
MyDeck.append(PlayersCards)
print("Here are your cards")
print(MyDeck)
print("Select a card")
But It wont continue on past the
def Cards():
How Can I make it so that the PlayersCard == range(1,7) Continues on regardless of what definition it is in?
I think this code works as you require:
def instructions():
print("You will be playing with an ai and whoever lays down the highest number wins that round.")
print("The points you get are determined by how much higher your card was from your opponents card.")
print("The person with the most points wins!")
def getUserInput():
global roundNumber, My_Deck, PlayerPoints, AIPoints
My_Deck = []
roundNumber = 0
AIPoints = 0
PlayerPoints = 0
print ("\nDo you want to play?: ")
print("\nChoices")
print("1. Yes")
print("2. No\n")
Choice = input()
if(Choice == 'Yes') or (Choice == 'yes'):
print("\nOkay, lets get started!")
startGame()
elif(Choice in ['No', 'no']):
print("Okay, bye!")
quit()
else:
print("That is not a Choice!")
print("Choose 'Yes' or 'No'")
getUserInput()
def startGame():
global roundNumber, My_Deck, PlayerPoints, AIPoints
print("\nAIPoints = %d PlayerPoints = %d" % (AIPoints, PlayerPoints))
roundNumber = roundNumber + 1
print("\nRound %d!" % (roundNumber))
cardChoosen = None
import random
if(roundNumber == 1):
print("\nHere are your 9 cards.\n")
for Cards in range(9):
Cards = random.randint(1, 100)
My_Deck.append(Cards)
while True:
print("Select one of your cards: "),
print(My_Deck)
Select = int(input())
try:
if (Select in My_Deck):
My_Deck.remove(Select)
print("You choose", Select)
print("Your deck now is:")
print(My_Deck)
cardChoosen = Select
break
else:
print("You don't have that card in your deck!")
except ValueError as e:
print(e)
elif(roundNumber == 10):
if(PlayerPoints > AIPoints):
print("\nCongratulations you won with a score of %d compared to the AI's %d" % (PlayerPoints, AIPoints))
getUserInput()
elif(PlayerPoints < AIPoints):
print("\nUnfortunately you lost with a score of %d compared to the AI's %d" % (PlayerPoints, AIPoints))
getUserInput()
else:
print("\nWow this is basicaly impossible you tied with the AI with you both ahving a score of %d and %d... " % (PlayerPoints, AIPoints))
getUserInput()
else:
print("\nHere are your %d cards.\n" % (9 - roundNumber + 1))
while True:
print("Select one of your cards: "),
print(My_Deck)
Select = int(input())
try:
if (Select in My_Deck):
My_Deck.remove(Select)
print("You choose", Select)
print("Your deck now is:")
print(My_Deck)
cardChoosen = Select
break
else:
print("You don't have that card in your deck!")
except ValueError as e:
print(e)
AINumber = random.randint(1, 100)
if(cardChoosen > AINumber):
print("\nYou won! Your number %d was higher than the AI's number %d" % (cardChoosen, AINumber))
print("\nYou scored %d points" % (cardChoosen - AINumber))
PlayerPoints = PlayerPoints + (cardChoosen - AINumber)
startGame()
elif(cardChoosen < AINumber):
print("\nYou Lost! Your number %d was lower than the AI's number %d" % (cardChoosen, AINumber))
print("\nAI scored %d points" % (AINumber - cardChoosen))
AIPoints = AIPoints + (AINumber - cardChoosen)
startGame()
else:
print("\nYou tied with the AI! Your number %d was the same as the AI's number %d" % (cardChoosen, AINumber))
print("\nNobody scored points!")
startGame()
My_Deck = []
roundNumber = 0
AIPoints = 0
PlayerPoints = 0
instructions()
getUserInput()

Need help fixing my game in Python

import random
hp = 100
eh = 100
x = 0
y = 0
print("Hello welcome to the beta version of my game.
This game is a 1 v 1 fight to the death against an unknown enemy.
In this game you and the enemy both start out with 100 health.
You can choose to either attack or heal each turn. Have fun and
pay attention to the following rules.")
print("Rule 1: You cannot heal while your health is over 84 points.
If you break this rule your turn will be void.")
print("Rule 2: You can only enter attack, Attack, heal, or Heal.
If you break this rule your turn will be void.")
print("Please press enter to start")
while hp > 0 and eh > 0:
print("Action? (attack, heal, nothing):")
act = input(">")
attack = random.randint(1, 30)
heal = random.randint(1, 15)
enemy_attack = random.randint(1, 30)
enemy_heal = random.randint(1, 15)
enemy_heal_within_5 = random.randint(1, 5)
enemy_decision = random.randint(1, 2)
if act == "attack" or act == "Attack":
eh = eh - attack
print(attack)
print("You have dealt %s damage" % attack)
elif act == "heal" and hp < 85:
hp = hp + heal
print("You have healed %s points" % heal)
elif act == "heal" and hp > 84:
while x == 0:
if act == "attack":
x +=1
else:
print("You cannot heal at this time, please try again.")
act = input(">")
if enemy_decision == 1:
hp = hp - enemy_attack
print("The enemy has dealt %s damage" % enemy_attack)
elif enemy_decision == 2 and eh > 94:
pass
elif enemy_decision == 2:
eh = eh + enemy_heal_within_5
print("The enemy has healed %s points" % enemy_heal_within_5)
elif enemy_decision == 2 and eh < 85:
eh = eh + enemy_heal
print("The enemy has healed %s points" % enemy_heal)
else:
print("Your health is now %s" % hp)
print("The enemy's health is now %s" % eh)
if hp <= 0:
print("You have lost")
elif eh <= 0:
print("You have won")
I need help creating an else statement where if the player enters something other than attack or heal, it asks them to try to input either attack or heal again. I tried repeating what I did in the hp > 84 section, but it ended up running that section instead of the else section.
You can make something like:
...
while hp > 0 and eh > 0:
act = "empty"
print("Action? (attack, heal, nothing):")
# With this while, you are accepting anything like "aTTaCk", "AttaCK", etc
while act.lower() not in ["attack","heal", "", "nothing"]:
act = input(">")
attack = random.randint(1, 30)
heal = random.randint(1, 15)
enemy_attack = random.randint(1, 30)
enemy_heal = random.randint(1, 15)
enemy_heal_within_5 = random.randint(1, 5)
enemy_decision = random.randint(1, 2)
...
I added the option nothing and also an empty string("") as an option if the player doesn't want to make anything. If you don't need any of them, just delete both from the list in while statement.
import random
hp = 100
eh = 100
x = 0
y = 0
print("Hello welcome to the beta version of my game. This game is a 1 v 1 fight to the death against an unknown enemy. In this game you and the enemy both start out with 100 health. You can choose to either attack or heal each turn. Have fun and pay attention to the following rules.")
print("Rule 1: You cannot heal while your health is over 84 points. If you break this rule your turn will be void.")
print("Rule 2: You can only enter attack, Attack, heal, or Heal. If you break this rule your turn will be void.")
print("Please press enter to start")
while hp > 0 and eh > 0:
act = ""
print("Action? (attack, heal, nothing):")
while act.lower() != "attack" and act.lower() != "heal":
act = input(">")
attack = random.randint(1, 30)
heal = random.randint(1, 15)
enemy_attack = random.randint(1, 30)
enemy_heal = random.randint(1, 15)
enemy_heal_within_5 = random.randint(1, 5)
enemy_decision = random.randint(1, 2)
if act == "attack" or act == "Attack":
eh = eh - attack
print(attack)
print("You have dealt %s damage" % attack)
elif act == "heal" and hp < 85:
hp = hp + heal
print("You have healed %s points" % heal)
elif act == "heal" and hp > 84:
while x == 0:
if act == "attack":
x +=1
else:
print("You cannot heal at this time, please try again.")
act = input(">")
if enemy_decision == 1:
hp = hp - enemy_attack
print("The enemy has dealt %s damage" % enemy_attack)
elif enemy_decision == 2 and eh > 94:
pass
elif enemy_decision == 2:
eh = eh + enemy_heal_within_5
print("The enemy has healed %s points" % enemy_heal_within_5)
elif enemy_decision == 2 and eh < 85:
eh = eh + enemy_heal
print("The enemy has healed %s points" % enemy_heal)
else:
print("Your health is now %s" % hp)
print("The enemy's health is now %s" % eh)
if hp <= 0:
print("You have lost")
elif eh <= 0:
print("You have won")
Use a while loop that checks whether the input is not "attack" and if it is not "heal", or any capitalized version of the two. I use !=, but you can also use not, as Ruben Bermudez showed below.

Python game not working(shop only showing up once) [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I'm trying to make just a simple text game before I go on learning more things, the first part went good, then I tried to add a shop and when the code is run the shop can only be entered once. Here is the code
money = 100
entertainment = 30
rest = 15
social = 30
inv = 1
food = 30
score = 1
def commands():
print "Commands:"
print " 'P' Print commands options"
print " 'S' Go to the shop"
print "Job list? "
print " 'M' Market"
print " 'F' Farm"
print " 'H' Stay at home a rest"
print " 'E' Entertainment/go to fair"
def shop():
print "Shop:"
print " This is the shop, you buy things with your money that you gain"
print "Press 'I' for a potato! This gives you 20 extra Inventory points! Costs 80 money!"
print "Press 'R' for a better bed! This gives you 20 extra rest points! Costs 80 money!"
print "Press 'S' for a texting plan! This gives you 20 extra social points! Costs 80 money!"
print "Press 'E' for a better tv! This gives you 20 extra entertainment points! Costs 80 money!"
print "Press 'H' for this list again!"
print "Press 'L' to return to your game!"
import random
import sys
commands()
def do_farm():
entertainment = entertainment - random.randrange(1,7+1)
rest = rest - random.randrange(1,7+1)
social = social - random.randrange(1,10+1)
food = food + random.randrange(1,7+1)
inv = inv + random.randrange(1,30+1)
money = money - random.randrange(1,10+1)
score = score + 1
print "Money = %d, Entertainment = %d, Rest = %d, Social = %d, Inventory %d, Food %d, Score %d" % (money, entertainment, rest, social, inv, food, score)
if money <= 0:
print "Game over, Score: %d" % (score)
exit()
elif food <= 0:
print "Game over, Score: %d" % (score)
exit()
elif social <= 0:
print "Game over, Score: %d" % (score)
exit()
elif entertainment <= 0:
print "Game over, Score: %d" % (score)
exit()
elif rest <= 0:
print "Game over, Score: %d" % (score)
exit()
def do_home():
entertainment = entertainment + random.randrange(1,3+1)
rest = rest + random.randrange(1,7+1)
social = social + random.randrange(1,5+1)
food = food - 5
money = money - random.randrange(1,10+1)
score = score + 1
print "Money = %d, Entertainment = %d, Rest = %d, Social = %d, Inventory %d, Food %d, Score %d" % (money, entertainment, rest, social, inv, food, score)
if money <= 0:
print "Game over, Score: %d" % (score)
exit()
elif food <= 0:
print "Game over, Score: %d" % (score)
exit()
elif social <= 0:
print "Game over, Score: %d" % (score)
exit()
elif entertainment <= 0:
print "Game over, Score: %d" % (score)
exit()
elif rest <= 0:
print "Game over, Score: %d" % (score)
exit()
def do_ent():
entertainment = entertainment + random.randrange(1,7+1)
social = social + random.randrange(1,5+1)
food = food - 3
money = money - random.randrange(1,10+1)
score = score + 1
print "Money = %d, Entertainment = %d, Rest = %d, Social = %d, Inventory %d, Food %d, Score %d" % (money, entertainment, rest, social, inv, food, score)
if money <= 0:
print "Game over, Score: %d" % (score)
exit()
elif food <= 0:
print "Game over, Score: %d" % (score)
exit()
elif social <= 0:
print "Game over, Score: %d" % (score)
exit()
elif entertainment <= 0:
print "Game over, Score: %d" % (score)
exit()
elif rest <= 0:
print "Game over, Score: %d" % (score)
exit()
def do_market():
entertainment = entertainment - random.randrange(1,7+1)
rest = rest - random.randrange(1,7+1)
social = social + random.randrange(1,5+1)
food = food - 5
money = (inv * 1.5) + money
inv = 1
score = score + 1
print "Money = %d, Entertainment = %d, Rest = %d, Social = %d, Inventory %d, Food %d, Score %d" % (money, entertainment, rest, social, inv, food, score)
if money <= 0:
print "Game over, Score: %d" % (score)
exit()
elif food <= 0:
print "Game over, Score: %d" % (score)
exit()
elif social <= 0:
print "Game over, Score: %d" % (score)
exit()
elif entertainment <= 0:
print "Game over, Score: %d" % (score)
exit()
elif rest <= 0:
print "Game over, Score: %d" % (score)
exit()
def do_shop_inventory():
score = score + 10
inv = inv + 20
money = money - 80
def do_shop_rest():
score = score + 10
rest = rest + 20
money = money - 80
def do_shop_social():
score = score + 10
social = social + 20
money = money - 80
def do_shop_ent():
score = score + 10
entertainment = entertainment + 20
money = money - 80
def shop_commands():
while True:
shop()
shop_choice = raw_input("Shop command: ")
if shop_choice == "I":
do_shop_inventory()
elif shop_choice == "R":
do_shop_rest()
elif shop_choice == "S":
do_shop_social()
elif shop_choice == "E":
do_shop_ent()
elif shop_choice == "H":
shop()
elif shop_choice == "L":
break
choice = raw_input("Your command: ")
while choice != "Q":
if choice == "F":
do_farm()
elif choice == "H":
do_home()
elif choice == "E":
do_ent()
elif choice == "M":
do_market()
elif choice == "S":
shop_commands()
commands()
choice = raw_input("Your command: ")
I am fairly new with Python, about 2-4 weeks. So please no complex answers if possible:D
I would like to know what is wrong and an idea of how to fix it.
Thanks:D
P.S. if you want to suggest an idea that could be added you could do that to!
EDIT:
Changed code, new error
Traceback (most recent call last):
File "C:\Users\ImGone\Desktop\MoneySurvival_bakcup.py", line 173, in <module>
do_farm()
File "C:\Users\ImGone\Desktop\MoneySurvival_bakcup.py", line 46, in do_farm
entertainment = entertainment - random.randrange(1,7+1)
UnboundLocalError: local variable 'entertainment' referenced before assignment
You never clear out shop_choice, so the next time someone tries to go to the shop, they instantly leave it (because shop_choice is already set to L from the previous time they visited and then left the shop).
In addition to the problem Amber found, you've got some indentation problems that will make it hard to get to the store.
The shop == "P" check is inside the rest <= 0 case inside the choice == "F" case. So, the only way to get to the shop is to go to the farm and use up all your rest. That can't be right.
This would be a lot simpler if you factored out your code into functions, like this:
def do_farm():
entertainment = entertainment - random.randrange(1,7+1)
# ...
And then your main loop could just do this:
if choice == "F":
do_farm()
elif choice == "S":
do_shop()
# ...
Also, it's a lot easier to get the loop right if you do things the other way around, asking for the choice at the top of the loop instead of the bottom. For example:
def shop():
while True:
shop()
shop_choice = raw_input("Shop command: ")
if shop_choice == "I":
do_shop_inventory()
elif shop_choice == "R":
# ...
elif shop_choice == "L":
break
It is a bit annoying that you have to do a while True and a break instead of putting the condition directly in the loop, but the alternative is to write the same input code twice (once before the loop, and once again at the end) instead of once (at the top of the loop), or write convoluted code that can handle a "no input yet" state.

python integrating code with raw_input timeout

This is most of my code for my now working python blackjack game (or at least blackjack like game) I have now been told that I need to implement a time limit (user gets asked to input something and only has 3 or so seconds to give a response).
def deck():
cards = range(1, 12)
return choice(cards)
def dealer():
total = deck() + deck()
if total <= 15:
totalf = total + deck()
while totalf <= 21:
return totalf
if total > 15:
return total
def player():
card1 = deck()
card2 = deck()
hand = card1 + card2
print "Cards dealt: %d and %d" % (card1, card2)
while hand <= 21:
choice = raw_input("Would you like to hit or stand?: ")
print choice
if choice == "hit":
hand = hand + deck()
print "Current Total: %d" % hand
elif choice == "stand":
return hand
money = 100
highscore = 0
while money > 0:
opp = dealer()
me = player()
if me > opp:
highscore = highscore + 10
money = money + 10
print "Winner, winner, chicken dinner! You have $%d!" % money
print "********************************************"
elif opp > 21:
highscore = highscore + 10
money = money + 10
print "Winner, winner, chicken dinner! You have $%d!" % money
print "********************************************"
elif me > 21:
money = money - 20
print "Bust! Dealer wins with %d. You have $%d reamaining." % (opp, money)
print "********************************************"
elif opp > me:
money = money - 20
print "Dealer wins with %d. You have $%d reamaining." % (opp, money)
print "********************************************"
elif me == 21:
highscore = highscore + 10
money = money + 10
print "Blackjack! You have $%d!" % money
print "********************************************"
sleep(1)
print "Thank you for playing! Your highscore was $%d." % highscore
This is the code my professor has provided us with to do this:
import sys, time
from select import select
import platform
if platform.system() == "Windows":
import msvcrt
def input_with_timeout_sane(prompt, timeout, default):
"""Read an input from the user or timeout"""
print prompt,
sys.stdout.flush()
rlist, _, _ = select([sys.stdin], [], [], timeout)
if rlist:
s = sys.stdin.readline().replace('\n','')
else:
s = default
print s
return s
def input_with_timeout_windows(prompt, timeout, default):
start_time = time.time()
print prompt,
sys.stdout.flush()
input = ''
while True:
if msvcrt.kbhit():
chr = msvcrt.getche()
if ord(chr) == 13: # enter_key
break
elif ord(chr) >= 32: #space_char
input += chr
if len(input) == 0 and (time.time() - start_time) > timeout:
break
if len(input) > 0:
return input
else:
return default
def input_with_timeout(prompt, timeout, default=''):
if platform.system() == "Windows":
return input_with_timeout_windows(prompt, timeout, default)
else:
return input_with_timeout_sane(prompt, timeout, default)
I am completely lost how to merge these two pieces of code. I've tried for the past couple hours to get it to work but for whatever reason its just not working. Any help would be amazing. (I apologize for the wall of code).
You just need to call input_with_timeout function where you want the user's input.
In your player function:
def player():
card1 = deck()
card2 = deck()
hand = card1 + card2
print "Cards dealt: %d and %d" % (card1, card2)
while hand <= 21:
choice = input_with_timeout("Would you like to hit or stand?: ", 3, "stand")
print choice
if choice == "hit":
hand = hand + deck()
print "Current Total: %d" % hand
elif choice == "stand":
return hand
will prompt for an input, writing the "Would ... or stand" sentence before it. If the user do not answer before the timeout (in this case 3 second) the function will return "stand".
And be sure to include your professor's code in your main file.

Categories