Here is the full code:
import random
import numpy as np
world = {}
class Player():
def __init__(self, health, maxHealth, baseDmg, dmg, name, weapons, items, isAlive, previousRoom, roomName):
self.health = health
self.maxHealth = maxHealth
self.baseDmg = baseDmg
self.dmg = dmg
self.name = name
self.weapons = weapons
self.items = items
self.isAlive = isAlive
self.previousRoom = previousRoom
self.room = world[roomName]
def Move(self, direction):
if direction not in self.room.exits:
print("Cannot Move In That Direction!")
return
newRoomName = self.room.exits[direction]
self.previousRoom = world[self.room.name]
print("Moving to", newRoomName)
self.room = world[newRoomName]
def MoveBack(self):
self.room = world[self.previousRoom.name]
print("Moving to", self.room.name)
class Enemy():
def __init__(self, health, dmg, hasLoot, lootItem, isAlive):
self.health = health
self.dmg = dmg
self.hasLoot = hasLoot
self.lootItem = lootItem
self.isAlive = isAlive
class Weapon():
def __init__(self, name, dmg, description):
self.name = name
self.dmg = dmg
self.description = description
class Item():
def __init__(self, name, amt, description):
self.name = name
self.amt = amt
self.description = description
class Room():
def __init__(self, name, description, exits, hasWeapon, weapon, hasItem, item, hasEnemy, enemy, isFirstVisit, coords):
self.name = name
self.description = description
self.exits = exits
self.hasWeapon = hasWeapon
self.weapon = weapon
self.hasItem = hasItem
self.item = item
self.hasEnemy = hasEnemy
self.enemy = enemy
self.isFirstVisit = isFirstVisit
self.coords = coords
#######################Dungeon Generation###################
rooms = np.zeros((11, 11))
maxRooms = 7
possibleNextRoom = []
def startLevel():
for r in range(len(rooms[0])):
for c in range(len(rooms[1])):
rooms[r][c] = 0
possibleNextRoom.clear()
halfHeight = int(len(rooms[1]) / 2)
halfWidth = int(len(rooms[0]) / 2)
rooms[halfWidth][halfHeight] = 1
def resetLevel():
for r in range(len(rooms[0])):
for c in range(len(rooms[1])):
rooms[r][c] = 0
possibleNextRoom.clear()
def countRooms():
roomCount = 0
for r in range(len(rooms)):
for c in range(len(rooms)):
if rooms[r][c] == 1:
roomCount += 1
return roomCount
def findPossibleRooms():
for r in range(len(rooms) - 1):
for c in range(len(rooms) - 1):
if rooms[r][c] == 1:
if rooms[r][c+1] != 1:
possibleNextRoom.append((r, c+1))
if rooms[r][c-1] != 1:
possibleNextRoom.append((r, c-1))
if rooms[r-1][c] != 1:
possibleNextRoom.append((r-1, c))
if rooms[r+1][c] != 1:
possibleNextRoom.append((r+1, c))
def addRoom():
x = random.randrange(0, len(possibleNextRoom))
rooms[possibleNextRoom[x][0]][possibleNextRoom[x][1]] = 1
possibleNextRoom.pop(x)
def generateLevel():
global x, possibleNextRoom
startLevel()
while countRooms() < maxRooms:
countRooms()
findPossibleRooms()
addRoom()
def makeRoomsForLevel():
counter = 1
for r in range(len(rooms)):
for c in range(len(rooms)):
if rooms[c][r] == 1:
world[f"room{counter}"] = Room(
f"room{counter}",
"",
{},
False,
None,
False,
None,
False,
None,
True,
(r, c)
)
counter += 1
def findRoom(x, y):
for i in range(len(world)):
if world[f"room{i+1}"].coords == (x, y):
return f"room{i+1}"
return None
def findExits():
for i in range(len(world)):
x, y = world[f"room{i+1}"].coords
exits = dict()
#east
if rooms[x, y+1] == 1:
exits["E"] = findRoom(x, y+1)
#south
if rooms[x+1, y] == 1:
exits["S"] = findRoom(x+1, y)
#west
if rooms[x, y-1] == 1:
exits["W"] = findRoom(x, y-1)
#north
if rooms[x-1, y] == 1:
exits["N"] = findRoom(x-1, y)
world[f"room{i+1}"].exits = exits
############################################################
generateLevel()
makeRoomsForLevel()
findExits()
WoodenSword = Weapon("Wooden Sword", 5, "A wooden sword. Looks like a kid's toy.")
IronDagger = Weapon("Iron Dagger", 8, "Small, sharp, and pointy. Good for fighting monsters!")
HealthPot = Item("Health Potion", 1, "A Potion of Instant Health. Restores 10 Health.")
goblin1 = Enemy(25, 2, True, [HealthPot, IronDagger], True)
player = Player(10, 10, 5, 5, "", [], [], True, "room1", "room1")
def ShowInv():
print("*******************************")
print("Name:", player.name)
print("Health:", player.health)
print("Weapons:")
for i in player.weapons:
print(" ===============================")
print(" Weapon:", i.name)
print(" Description:", i.description)
print(" Damage:", i.dmg)
print(" ===============================")
print("Items:")
for i in player.items:
print(" ===============================")
print(" Item:", i.name)
print(" Amount:", i.amt)
print(" Description:", i.description)
print(" ===============================")
print("*******************************")
def testItems(item):
exists = item in player.items
return exists
def fight(enemy):
print("Your Health:", player.health)
print("Enemy Health:", enemy.health)
ans = input("What would you like to do?\n>>")
if ans == "attack":
chance = random.randrange(1, 20)
if chance >= 10:
enemy.health -= player.dmg
else:
print("You did not roll high enough...\nYour turn has been passed...")
if ans == "heal":
chance = random.randrange(1, 20)
if testItems(HealthPot):
if chance >= 10:
x = 0
for item in player.items:
if item == HealthPot:
player.health += 10
if player.health > player.maxHealth:
player.health = player.maxHealth
item.amt -= 1
if item.amt <= 0:
player.items.pop(x)
break
x += 1
else:
print("You did not roll high enough...\nYour turn has been passed...")
if ans == "run":
chance = random.randrange(1, 20)
if chance >= 10:
player.MoveBack()
else:
print("You did not roll high enough...\nYour turn has been passed...")
if enemy.health > 0 and player.health > 0:
chance = random.randrange(1, 20)
if chance >= 10:
player.health -= enemy.dmg
else:
if enemy.health <= 0:
enemy.isAvile = False;
def testRoom():
if player.room.hasWeapon:
if player.room.isFirstVisit:
player.weapons.append(player.room.weapon)
if player.room.hasItem:
if player.room.isFirstVisit:
player.items.append(player.room.item)
if player.room.hasEnemy:
if player.room.isFirstVisit:
while player.room.enemy.health > 0:
fight(player.room.enemy)
player.room.isFirstVisit = False
while True:
command = input(">>")
if command in {"N", "S", "E", "W"}:
player.Move(command)
testRoom()
elif command == "look":
print(player.room.description)
print("Exits:", *','.join(list(player.room.exits.keys())))
elif command == "inv":
ShowInv()
elif command == "heal":
if testItems(HealthPot):
player.health += 10
if player.health > player.maxHealth:
player.health = player.maxHealth
else:
print("You don't have any", HealthPot.name, "\bs")
else:
print("Invalid Command")
And here is the problem:
Everything seems to work fine, until a couple moves in when it breaks and gives me a "KeyError: None" for the room I just walked in. I have no idea what could be causing this, and I am fairly new, so please simplify the explanations for me. I think it has something to do with the findExits() function and findRoom() function, but idk.
Here is the TraceBackError:
Traceback (most recent call last):
File "main.py", line 287, in <module>
player.Move(command)
File "main.py", line 26, in Move
self.room = world[newRoomName]
KeyError: None
I've tried fiddling with the function, but nothing i've tried worked. Here is the repl.it link:
https://replit.com/#samsonsbrother0/Dungeon-Crawler#main.py
your code is accessing a key before it exists, thus the error. to fix it, you need to assign the newroomname to the world dict as you move, like so:
print("Moving to", newRoomName)
world[newRoomName] = newRoomName
self.room = world[newRoomName]
Related
I'm making good progress on a basic turn-based RPG battle system in Python. I'm trying to create the program using object-oriented programming so I can easily add new classes, attacks, and enemies as needed. I've implemented most of the features I'd like to, but one goal I'm struggling with is the implementation of a cooldown system for certain attacks. Here is the code I've written:
import random
class Class:
def __init__(self, name, health, attacklist):
self.name = name
self.health = health
self.attacklist = attacklist
class Enemy:
def __init__(self, name, health, attacklist):
self.name = name
self.health = health
self.attacklist = attacklist
class Attack:
def __init__(self, name, base_damage, max_damage, healing, stun, chance, reduce_chance, cooldown, on_cooldown):
self.name = name
self.base_damage = base_damage
self.max_damage = max_damage
self.healing = healing
self.stun = stun
self.chance = chance
self.reduce_chance = reduce_chance
self.cooldown = cooldown
self.on_cooldown = on_cooldown
Punch = Attack("Punch", 50, 100, 0, "no_stun", 80, 0, 0, False)
Stunner = Attack("Stunner", 20, 30, 0, "stun", 70, 0, 0, False)
Bite = Attack("Bite", 30, 40, 0, "no_stun", 60, 0, 0, False)
Scratch = Attack("Scratch", 20, 30, 0, "no_stun", 70, 0, 0, False)
garbage_fling = Attack("Garbage Fling", 5, 10, 0, 0, 80, 20, 2, False)
fighter_attacklist = [Punch, Stunner]
vermen_dreg_attacklist = [Bite, Scratch]
vermen_scrounger_attacklist = [garbage_fling, Bite]
Fighter = Class("Fighter", 500, fighter_attacklist)
vermen_dreg = Enemy("Vermen Dreg", 100, vermen_dreg_attacklist)
vermen_scrounger = Enemy("Vermen Scrounger", 100, vermen_scrounger_attacklist)
enemy_list = [vermen_scrounger]
stun_cooldown = 0
enemy_cooldown = 0
while True:
print("Choose your class: Fighter (1)")
choice = input()
if choice == "1":
player_class = Fighter
print("You have chosen:", player_class.name)
enemy = random.choice(enemy_list)
enemy_attacks = enemy.attacklist
print("Your enemy is:", enemy.name)
else:
print("Error, invalid input!")
continue
while True:
cooldown_list = []
print(cooldown_list)
enemy_stunned = False
#Player Attack
print("Your health:", player_class.health)
print("Enemy health:", enemy.health)
print("Attacks:", player_class.attacklist[0].name, "(1)", player_class.attacklist[1].name, "(2)")
choice = input()
if choice == "1":
player_attack = player_class.attacklist[0]
elif choice == "2":
player_attack = player_class.attacklist[1]
else:
print("Please enter a valid number!")
continue
diceroll = random.randint(1, 100)
if diceroll <= player_attack.chance:
player_damage = random.randint(player_attack.base_damage, player_attack.max_damage)
if player_damage > 0:
enemy.health -= player_damage
print("You hit", enemy.name, "for", player_damage)
if player_attack.stun == "stun":
if stun_cooldown > 0:
print("The enemy resisted your stun attempt!")
if stun_cooldown == 0:
print("You stunned the enemy.")
enemy_stunned = True
stun_cooldown = 3
player_healing = player_attack.healing
player_class.health += player_healing
if player_healing > 0:
print("You healed for", player_healing)
elif diceroll > player_attack.chance:
print("You missed!")
# Enemy Turn
if enemy_stunned == False:
enemy_move = random.choice(enemy.attacklist)
diceroll = random.randint(1, 100)
if diceroll <= enemy_move.chance:
enemy_damage = random.randint(enemy_move.base_damage, enemy_move.max_damage)
if enemy_damage > 0:
player_class.health -= enemy_damage
print(enemy.name, "hit you with", enemy_move.name, "for", enemy_damage)
reduce_chance = enemy_move.reduce_chance
for Attack in player_class.attacklist:
player_class.attacklist[0 - 2].chance -= reduce_chance
if player_class.attacklist[0 - 2].chance < 50:
player_class.attacklist[0 - 2].chance = 50
if reduce_chance > 0:
print("Your chance was reduced by", enemy_move.reduce_chance)
if enemy_move.cooldown > 0:
enemy.attacklist.remove(enemy_move)
enemy_move = on_cooldown
elif diceroll > enemy_move.chance:
print("The enemy attack missed!")
elif enemy_stunned == True:
print("The enemy was stunned and could not attack.")
stun_cooldown -= 1
enemy_cooldown -= 1
if stun_cooldown < 0:
stun_cooldown = 0
My goal is to give the "Garbage Throw" attack for the "Vermen Scrounger" a cooldown so that the computer will not use it every single turn. I currently have the attack set to delete itself from the list of attacks after it is used, however, I don't have a clean solution for implementing it back into the enemy "Attack List" after 2 turns have passed. Preferably, I would like to have a function within the "Attack" class that initiates the cooldown for each iteration of my battle loop.
I tried to remove the attack from the enemy attack list and succeeded, however, I have no way of returning it to the attack list.
I tried to make a "typing game" and at first, it worked out pretty nice. But when I translated my code to English (variable names, class names, function names etc.) it gave me the warning "Object int is not callable". How can I solve this?
Here's my code:
import time
import random
import sys
class Player():
def __init__(self, name, health = 5, energy = 10):
self.name = name
self.health = health
self.energy = energy
self.hit = 0
def inf(self):
print("Health: ", self.health, "\nEnergy: ", self.energy, "\nName: ", self.name)
def attack(self, opponent):
print("Attacking")
time.sleep(.300)
for i in range(3):
print(".", end=" ", flush=True)
x = self.randomAttack()
if x == 0:
print("Nobody attacks.")
elif x == 1:
print("{} hits {} !".format(name, opponentName))
self.hit(opponent)
opponent.health -= 1
elif x == 2:
print("{} hits {}!".format(opponentName, name))
opponent.hit(self)
self.health -= 1
def randomAttack(self):
return random.randint(0, 2)
def hit(self, hit):
hit.hitVariable += 1
hit.energy -= 1
if (hit.hitVariable % 5) == 0:
hit.health -= 1
if hit.health < 1:
hit.energy = 0
print('{} won the game!'.format(self.name))
self.exit()
#classmethod
def exit(cls):
sys.exit()
def run(self):
print("Running...")
time.sleep(.300)
print("Opponent catch you!")
#######################################################
print("Welcome!\n----------")
name = input("What's your name?\n>>>")
opponentName = input("What's your opponent's name?\n>>>")
you = Player(name)
opponent = Player(opponentName)
print("Commands: \nAttack: a\nRun: r\nInformation: i\nExit: e")
while True:
x = input(">>>")
if x == "a":
you.attack(opponent)
elif x == "r":
you.run()
elif x == "i":
you.inf()
elif x == "e":
Player.exit()
break
else:
print("Command not found!")
continue
It gives me the error at line 24 (self.hit(opponent)).
Your hit function is the problem. You have member and a function with the same name. Change one of them.
Also rename the hit argument of the hit(). You call it via self.hit(opponent) so I would rename it to def hit(self, opponent):.
def __init__(self, name, health = 5, energy = 10):
self.hit = 0
def hit(self, hit):
hit.hitVariable += 1
hit.energy -= 1
if (hit.hitVariable % 5) == 0:
hit.health -= 1
if hit.health < 1:
hit.energy = 0
print('{} won the game!'.format(self.name))
self.exit()
The part with the goblin works but the part with the elf doesn't.
#importing the random module
import random
#creating the game object class
class GameObject:
class_name = ""
desc = ""
objects = {}
def __init__(self, name):
self.name = name
GameObject.objects[self.class_name] = self
#defining the description
def get_desc(self):
return self.class_name + "\n" + self.desc
#creating the goblin class
class Goblin(GameObject):
def __init__(self, name):
self.class_name = "goblin"
self.health = 3
self._desc = "A foul creature"
super().__init__(name)
#property
def desc(self):
if self.health >= 3:
return self._desc
elif self.health == 2:
x = random.randint(13, 35)
health_line = "You struck and dealt " + str(x) + " damage!"
elif self.health == 1:
y = 40 - random.randint(13, 35)
health_line = "You rushed and dealt " +str(y) + " damage! \n Goblin activated effect Rage!"
elif self.health <= 0:
health_line = "It is dead."
return self._desc + "\n" + health_line
#desc.setter
def desc(self, value):
self._desc = value
#creating the goblin object
goblin = Goblin("Gobbly")
#creating the elf class
class Elf(GameObject):
def __init__(self, name):
self.class_name = "Elf"
self.health = 5
self._desc = "A strong warlock"
super().__init__(name)
#property
def desc(self):
if self.health >= 5:
return self._desc
elif self.health == 4:
x = random.randint(20, 50)
health_line = " You struck and dealt " + str(x) + " damage!"
elif self.health == 3:
x = random.randint(20, 40)
health_line = " You countered and dealt " + str(x) + " damage!"
elif self.health == 2:
y = 40 - random.randint(20, 50)
health_line = "You rushed and dealt " +str(y) + " damage! \n Elf activated effect Sectum Sempra!!"
elif self.health == 1:
y = 40 - random.randint(20, 50)
health_line = " You struck and dealt " + str(x) + " damage!"
elif self.health <= 0:
health_line = "It is dead."
return self._desc + "\n" + health_line
#desc.setter
def desc(self, value):
self._desc = value
#creating an elf object
elf = Elf("Elfy")
#defining the hit verb
def hit(noun):
if noun in GameObject.objects:
thing = GameObject.objects[noun]
if type(thing) == Goblin:
thing.health -= 1
if thing.health <= 0:
msg = "You killed the goblin!"
else:
msg = "You hit the {}".format(thing.class_name)
elif type(thing) == Elf:
thing.health -= 1
if thing.health <= 0:
msg = "You killed the elf!"
else:
msg = "You hit the {}".format(thing.class_name)
else:
msg = "There is no {} here.".format(noun)
return msg
#defining the examine verb
def examine(noun):
if noun in GameObject.objects:
return GameObject.objects[noun].get_desc()
else:
return "There is no {} here.".format(noun)
#getting input
def get_input():
command = input(": ").split()
verb_word = command[0]
if verb_word in verb_dict:
verb = verb_dict[verb_word]
else:
print("Unknown verb {}".format(verb_word))
return
if len(command) >= 2:
noun_word = command[1]
print(verb(noun_word))
else:
print(verb("nothing"))
#defining the say verb
def say(noun):
return 'You said "{}"'.format(noun)
#the verbs
verb_dict = {
"say": say,
"examine": examine,
"hit": hit
}
while True:
get_input()
It's supposed to say |you hit the elf| when I type |hit elf| like how it says |you hit the goblin| when I type |hit goblin|
I just started learning oop in python and some parts are confusing. If anyone understands, please help me fix the code.
At first elif refers to else if , that simply means that if statement is activated then the elif statement gets skipped . So try replacing elif with if . If problem still continues , reply.
I don't see that you need to check the type of the object here:
def hit(noun):
if noun in GameObject.objects:
thing = GameObject.objects[noun]
thing.health -= 1
if thing.health <= 0:
msg = "You killed the {}!".format(thing.class_name.lower())
else:
msg = "You hit the {}".format(thing.class_name)
else:
msg = "There is no {} here.".format(noun)
return msg
I have the following code:
import options
import random
class Player():
def __init__(self):
self.name = None
self.gold = 100
self.maxhealth = 100
self.health = self.maxhealth
self.level = 1
self.exp = 0
self.levelUp = 50
self.gainedexp = self.levelUp - self.exp
def get_name(self):
self.name = input("Hey there, traveller! What's your name?\n~~>")
print("Since you are new around here, 100 gold doubloons have been given to you, {}!".format(self.name))
def gold_counter(self):
print("You currently have {} gold!".format(player.gold))
class Dragon():
def __init__(self):
self.name = "Dragon"
self.dropgold = random.randint(13,20)
self.minexp = int(15 * round(player.level * 1.5))
self.maxexp = int(30 * round(player.level * 1.5))
self.expgain = random.randint({}, {}.format(self.minexp, self.maxexp))
self.maxhealth = 80
self.health = self.maxhealth
def intro():
wrong_input = 0
nar_name = "Narrator"
print("{}: Uhhhm...".format(nar_name))
print("{}: Let me check my list...".format(nar_name))
print("{0}: Ah! Yes! {1}, that's right. I heard you were supposed to be arriving today.".format(nar_name, player.name))
I am also using two other modules, but I'm 99% sure they don't affect this. I get the following output:
Hey there, traveller! What's your name?
~~>Savage Potato
Since you are new around here, 100 gold doubloons have been given to you, Savage Potato!
Do you want to see your balance?
~~> Yes
You currently have 100 gold.
Narrator: Uhhhm...
Narrator: Let me check my list...
Narrator: Ah! Yes! None, that's right. I heard you were supposed to be arriving today.
In the last line, it is printing out the Narrator's name, but not the user's inputted name. I also looked at the python documents on their website, but I couldn't find a fix. Any ideas on how I could stop it from outputting None as the user's name?
EDIT #1: I have player = Player() written later in the module.
EDIT #2: This is all the code I used:
Module 1 (main.py)
import prints
import random
class Player():
def __init__(self):
self.name = None
self.gold = 100
self.maxhealth = 100
self.health = self.maxhealth
self.level = 1
self.exp = 0
self.levelUp = 50
self.gainedexp = self.levelUp - self.exp
def get_name(self):
self.name = input("Hey there, traveller! What's your name?\n~~>")
print("Since you are new around here, 100 gold doubloons have been given to you, {}!".format(self.name))
class Dragon():
def __init__(self):
self.name = "Dragon"
self.dropgold = random.randint(13,20)
self.minexp = int(15 * round(player.level * 1.5))
self.maxexp = int(30 * round(player.level * 1.5))
self.expgain = random.randint({}, {}.format(self.minexp, self.maxexp))
self.maxhealth = 80
self.health = self.maxhealth
#while player.exp >= player.levelUp:
#player.levelUp += 1
#player.exp = player.exp - player.levelUp
#player.levelUp = round(player.levelUp * 1.5)
#print("Congrats! You just levelled up to level {} by gaining {} experience!".format(player.level, player.gainedexp))
def start():
player.get_name()
prints.gold_counter()
prints.intro()
prints.encounter()
player = Player()
start()
Module 2 (prints.py)
import options
import random
class Player():
def __init__(self):
self.name = None
self.gold = 100
self.maxhealth = 100
self.health = self.maxhealth
self.level = 1
self.exp = 0
self.levelUp = 50
self.gainedexp = self.levelUp - self.exp
def get_name(self):
self.name = input("Hey there, traveller! What's your name?\n~~>")
print("Since you are new around here, 100 gold doubloons have been given to you, {}!".format(self.name))
def gold_counter(self):
print("You currently have {} gold!".format(player.gold))
class Dragon():
def __init__(self):
self.name = "Dragon"
self.dropgold = random.randint(13,20)
self.minexp = int(15 * round(player.level * 1.5))
self.maxexp = int(30 * round(player.level * 1.5))
self.expgain = random.randint({}, {}.format(self.minexp, self.maxexp))
self.maxhealth = 80
self.health = self.maxhealth
def intro():
wrong_input = 0
nar_name = "Narrator"
print("{}: Uhhhm...".format(nar_name))
print("{}: Let me check my list...".format(nar_name))
print("{0}: Ah! Yes! {1}, that's right. I heard you were supposed to be arriving today.".format(nar_name, player.name))
print("{}: Welcome to... THE DRAGON FIGHTER GAME!".format(nar_name))
print("{}: I know, it isn't the most imaginative name.".format(nar_name))
print("{}: Don't look at me like that, I tried my hardest!".format(nar_name))
print("{}: Anyhoo, let's carry on.".format(nar_name))
print("{}: For some stupid reason, the creator of this game didn't give me an actual name, so\nmy name is just \"Narrator\" or \"N\", but you can call me Larry.".format(nar_name))
while True:
option = input("Narrator: Actually, which name would you prefer to call me?\n").upper()
if option in options.nar_larry_opt:
nar_name = "Larry"
elif option in options.nar_narrator_opt:
nar_name = "Narrator"
while True:
ask = input("{}: Maybe \"N\" for short?".format(nar_name)).upper()
if ask in options.inp_yes_opt:
nar_name = "N"
elif ask in options.inp_no_opt:
break
else:
wrong_input += 1
if wrong_input == 1:
print("Please try again.")
elif wrong_input == 2:
print("Try to not put the same thing in next time.")
elif wrong_input == 3:
print("This isn't funny.")
elif wrong_input == 4:
print("Seriously.")
elif wrong_input == 5:
print("OKAY! THIS IS IT! GO BACK TO THE BEGINNING!")
intro()
continue
break
else:
print("Please try again.")
continue
break
print("{}: So, as I was saying, this game is basically just some dragon quest thingy.".format(nar_name))
print("{}: You'll probably get tips from me every now and again if I can be bothered.".format(nar_name))
print("{}: I'll get an test encounter ready.".format(nar_name))
def gold_counter():
while True:
option = input("Do you want to see your balance?\n~~> ").upper()
if option in options.inp_yes_opt:
print("You currently have {} gold.".format(player.gold))
elif option in options.inp_no_opt:
print("You can check your balance later in the game.")
else:
print("Please try again.")
continue
break
def encounter():
while True:
dragon_appear = random.randint(1,2)
if dragon_appear == 1:
print("What's that? Looks like a huge bir... \nA DRAGON! A MAJESTIC DRAGON JUST FLEW DOWN FROM THE SKY!")
else:
print("What's that? Looks like a huge bir... \n Yeah. Just a giganta-bird.")
while encounter().dragon_appear != 2:
print("So that's the message you'll get when a dragon appears.")
print("And you will be prompted whether you want to run or fight, like so:")
while True:
wrong_input = 0
ask = input("Run away like a coward, or fight the majestic beast?")
if ask in options.enc_run_opt:
escape = random.randint(1,2)
if escape == 1:
print("You managed to get away!")
else:
print("You didn't get away. Better luck next time!")
elif ask in options.enc_attack_opt:
pass
else:
wrong_input += 1
if wrong_input == 1:
print("Please try again.")
elif wrong_input == 2:
print("Try to not put the same thing in next time.")
elif wrong_input == 3:
print("This isn't funny.")
elif wrong_input == 4:
print("Seriously.")
continue
break
player = Player()
Module 3 (options.py)
inp_yes_opt = {"Y", "YE", "YES", "YEAH", "PLEASE", "YES PLEASE"}
inp_no_opt = {"N", "NO", "NOPE", "NAH"}
nar_larry_opt = {"LARRY", "LARR", "LAR", "LA", "L", "LARRY PLEASE"}
nar_narrator_opt = {"NARRATOR", "NARR", "N", "NAR", "NARRATE", "NOT LARRY"}
enc_run_opt = {"RUN", "RU", "R", "SCRAM", "RUN AWAY", "RUUUUN"}
enc_attack_opt = {"ATTACK", "ATTAK", "A", "FIGHT", "F", "ATTACK", ""}
If you want to print out the name of the player , you need to pass in the player object to the intro function as a parameter. That assumes intro is not capturing the player object and the player object is not global
At the moment , it seems there is no player object accessible to the scope of the function which is why it outputs None
I've got a piece of code I'm working on for a school project and the basic idea is that there's a battle between two characters where the user can input 2 attributes to each character: Strength and Skill. Now there are also modifiers for skill and strength which is the difference of the player's skill and strength attributes, divided by 5 and then rounded down respectively. Then each player has a dice roll, depending on who got the higher roll, that player gets the skill and strength modifiers added to their given attributes whilst the one that lost gets the modifiers deducted from their score. This then repeats until the strength attribute of one of them reaches 0 where that player then dies and the game ends.
In my code, the dice rolling function runs twice, and then crashes for an unknown reason I cannot identify.
import random
import time
import math
import sys
strength_mod = 0
skill_mod = 0
def delay_print(s):
for c in s:
sys.stdout.write( '%s' % c )
sys.stdout.flush()
time.sleep(0.05)
def str_mod(charone_str,chartwo_str):
if charone_str > chartwo_str:
top = charone_str
bottom = chartwo_str
calc = top - bottom
calc = calc / 5
calc = math.floor(calc)
return calc
elif chartwo_str > charone_str:
top = chartwo_str
bottom = charone_str
calc = top - bottom
calc = calc / 5
calc = math.floor(calc)
return calc
elif charone_str == chartwo_str:
top = charone_str
bottom = chartwo_str
calc = top - bottom
calc = calc / 5
calc = math.floor(calc)
return calc
def skl_mod(charone_skl, chartwo_skl):
if charone_skl > chartwo_skl:
top = charone_skl
bottom = chartwo_skl;
calc = top - bottom
calc = calc / 5
calc = math.floor(calc)
return calc
elif chartwo_skl > charone_skl:
top = chartwo_skl
bottom = charone_skl
calc = top - bottom
calc = calc / 5
calc = math.floor(calc)
return calc
elif charone_skl == chartwo_skl:
top = charone_skl
bottom = chartwo_skl
calc = top - bottom
calc = calc / 5
calc = math.floor(calc)
return calc
def mods():
global strength_mod
global skill_mod
strength_mod = str_mod(charone_strength, chartwo_strength)
skill_mod = skl_mod(charone_skill, chartwo_skill)
print "\nFor this battle, the strength modifier is:",strength_mod
time.sleep(0.20)
print "For this battle, the skill modifier is: ",skill_mod
time.sleep(0.20)
diceroll(charone, chartwo)
print "\n"+str(charone)+"'s","dice roll is:",player1
time.sleep(1)
print "\n"+str(chartwo)+"'s","dice roll is:",player2
def diceroll(charone, chartwo):
print "\n"+str(charone)+" will roll the 6 sided dice first!"
time.sleep(0.5)
global player1
player1 = random.randint(1,6)
delay_print("\nRolling dice!")
global player2
player2 = random.randint(1,6)
time.sleep(0.5)
print "\nNow",chartwo,"will roll the 6 sided dice!"
time.sleep(0.5)
delay_print("\nRolling dice!")
def battle(charone_str, chartwo_str, charone_skl, chartwo_skl, str_mod, skl_mod):
global charone_strength
global charone_skill
global chartwo_strength
global chartwo_skill
if player1 == player2:
print "\nThis round is a draw! No damage done"
elif player1 > player2:
charone_strength = charone_str + str_mod
charone_skill = charone_skl + skl_mod
chartwo_strength = charwo_skl - str_mod
chartwo_skill = chartwo_skl - skl_mod
print "\n"+charone+" won this round"
print "\n"+"Character 1:",charone
print "Strength:",charone_strength
print "Skill:",charone_skill
time.sleep(1)
print "\nCharacter 2:",chartwo
print "Strength:",chartwo_strength
print "Skill:",chartwo_skill
elif player2 > player1:
chartwo_strength = chartwo_str + str_mod
chartwo_skill = chartwo_skl + skl_mod
charone_strength = charone_str - str_mod
charone_skill = charone_skl - skl_mod
print "\n"+chartwo+" won this round"
print "\nCharacter 2:",chartwo
print "Strength:",chartwo_strength
print "Skill:",chartwo_skilll
time.sleep(1)
print "\n"+"Character 1:",charone
print "Strength:",charone_strength
print "Skill:",charone_skill
if charone_skill >= 0:
charone_skill = 0
elif chartwo_skill >= 0:
chartwo_skill = 0
if charone_strength <= 0:
print charone,"has died!",chartwo,"wins!"
elif chartwo_strength <= 0:
print chartwo,"has died!",charone,"wins!"
charone = raw_input("Enter the name of character one: ")
chartwo = raw_input("Enter the name of character two: ")
time.sleep(1.5)
print "\n",charone,"encounters",chartwo
delay_print("\nBattle Initiated!")
charone_strength = int(raw_input("\nEnter the strength score for "+str(charone)+" (between 50 and 100): "))
while charone_strength > 100 or charone_strength < 50:
print "That number is not between 50-100"
charone_strength = int(raw_input("\nEnter the strength score for "+str(charone)+" (between 50 and 100): "))
else:
pass
charone_skill = int(raw_input("Enter the skill score for "+str(charone)+" (between 50 and 100): "))
while charone_skill > 100 or charone_skill < 50:
print "That number is not between 50-100"
charone_skill = int(raw_input("Enter the skill score for "+str(charone)+" (between 50 and 100): "))
else:
pass
time.sleep(1.0)
chartwo_strength = int(raw_input("\nEnter the strength score for "+str(chartwo)+" (between 50 and 100): "))
while chartwo_strength > 100 or chartwo_strength < 50:
print "That number is not between 50-100"
chartwo_strength = int(raw_input("\n Enter the strength score for "+str(chartwo)+" (between 50 and 100): "))
else:
pass
chartwo_skill = int(raw_input("Enter the skill score for "+str(chartwo)+" (between 50 and 100): "))
while chartwo_skill > 100 or chartwo_skill < 50:
print "That number is not between 50-100"
chartwo_skill = int(raw_input("Enter the skill score for "+str(chartwo)+" (between 50 and 100): "))
else:
pass
time.sleep(2)
print "\nCharacter 1:",charone
print "Strength:",charone_strength
print "Skill:",charone_skill
time.sleep(1)
print "\nCharacter 2:",chartwo
print "Strength:",chartwo_strength
print "Skill:",chartwo_skill
time.sleep(1)
while charone_strength != 0 or chartwo_strength != 0:
ent = raw_input("Press Enter to roll! ")
mods()
diceroll(charone,chartwo)
battle(charone_strength, chartwo_strength, charone_skill, chartwo_skill, str_mod, skl_mod)
else:
play = raw_input("\nWould you like to play again?")
if play in ["yes","y","Yes","Y"]:
execfile("gcse.py")
else:
print "Goodbye"
This code is an excellent example of how not to program:
heavy use of global variables
multiple variables with very similar names (ie charone_strength, charone_str)
reuse of names in different contexts (in global scope, str_mod is a function, but in function battle it is supposed to be an integer
Your immediate problem: in line 182, you call
battle(charone_strength, chartwo_strength, charone_skill, chartwo_skill, str_mod, skl_mod)
which should be
battle(charone_strength, chartwo_strength, charone_skill, chartwo_skill, strength_mod, skill_mod)
but is confused because in the function strength_mod is referred to as str_mod.
Here is a greatly cleaned-up version. (Further suggestions for improvement are welcome).
from __future__ import division, print_function
from random import randint
import sys
from time import sleep
# Python 2/3 compatibility shim
if sys.hexversion < 0x3000000:
# Python 2.x
inp = raw_input
rng = xrange
else:
# Python 3.x
inp = input
rng = range
PRINT_DELAY = 0.02
PAUSE_DELAY = 0.2
TF_VALUES = {
'y': True, 'yes': True, 't': True, '': True,
'n': False, 'no': False, 'f': False
}
def get_int(prompt="Enter an integer: ", lo=None, hi=None):
while True:
try:
i = int(inp(prompt))
if (lo is None or lo <= i) and (hi is None or i <= hi):
return i
except ValueError:
pass
def get_tf(prompt="Yes or no? ", tf_values=TF_VALUES):
while True:
s = inp(prompt).strip().lower()
tf = tf_values.get(s, None)
if tf is not None:
return tf
def pause(delay=PAUSE_DELAY):
sleep(delay)
def roll(die_sides=6):
return randint(1, die_sides)
def slow_print(s, delay=PRINT_DELAY):
for ch in s:
print(ch, end='', flush=True)
sleep(delay)
print('') # end of line
def wait_for_enter(prompt):
inp(prompt)
class Fighter:
#classmethod
def get_fighter(cls, prompt):
print(prompt)
name = inp ("Name: ")
health = get_int("Health: (50-100) ", 50, 100)
skill = get_int("Skill: (50-100) ", 50, 100)
return cls(name, health, skill)
def __init__(self, name, health, skill):
self.name = name
self.health = health
self.skill = skill
def is_alive(self):
return self.health > 0
def health_mod(self, other_fighter):
delta = abs(self.health - other_fighter.health)
return int(delta / 5)
def skill_mod(self, other_fighter):
delta = abs(self.skill - other_fighter.skill)
return int(delta / 5)
def attack(self, other_fighter):
wait_for_enter("Hit Enter to fight!")
# figure out mod values
health_mod = self.health_mod(other_fighter)
skill_mod = self.skill_mod (other_fighter)
self_roll = roll()
other_roll = roll()
slow_print(
"Health mod: {} Skill mod: {} {} rolls {} {} rolls {}"
.format(
health_mod, skill_mod,
self.name, self_roll,
other_fighter.name, other_roll
)
)
# figure out who won this round
if self_roll == other_roll:
print("Draw! No damage done.")
else:
winner, loser = (self, other_fighter) if self_roll > other_roll else (other_fighter, self)
print("{} hits {}!".format(winner.name, loser.name))
winner.health += health_mod
winner.skill += skill_mod
loser.health -= health_mod
loser.skill -= skill_mod
# show results
print('')
print(self)
print(other_fighter)
print('')
def __str__(self):
return "{}: health {}, skill {}".format(self.name, max(self.health, 0), max(self.skill, 0))
def fight():
f1 = Fighter.get_fighter("\nFirst fighter:")
pause()
f2 = Fighter.get_fighter("\nSecond fighter:")
pause()
slow_print("\n{} encounters {}\nBattle Initiated!".format(f1.name, f2.name))
while f1.is_alive() and f2.is_alive():
f1.attack(f2)
winner, loser = (f1, f2) if f1.is_alive() else (f2, f1)
print("{} has died; {} wins!".format(loser.name, winner.name))
def main():
while True:
fight()
if not get_tf("Would you like to play again? (Y/n)"):
print("Goodbye!")
break
if __name__=="__main__":
main()