Python Classes (Basic) - python

Working code is here: http://codepad.org/L0OkeHlk
from sys import exit
class Map(object):
def __init__(self, start):
self.start = start
def play(self):
next = self.start
while True:
print "\n---------"
room = getattr(self,next)
next = room()
def death(self):
exit(1)
def redroom(self):
prompt = raw_input("> ")
if "white" in prompt:
return "whiteroom"
elif "blue" in prompt:
return "blueroom"
else:
print "DOES NOT COMPUTE (RED ROOM)"
return 'death'
def whiteroom(self):
prompt = raw_input("> ")
if "red" in prompt:
return "redroom"
elif "blue" in prompt:
return "blueroom"
else:
print "DOES NOT COMPUTE (WHITE ROOM)"
return 'death'
def blueroom(self):
prompt = raw_input("> ")
if "white" in prompt:
return "whiteroom"
elif "red" in prompt:
return "redroom"
else:
print "DOES NOT COMPUTE (BLUE ROOM)"
return 'death'
class Engine(object):
pass
x = Map("redroom")
x.play()
The above works. But only because I'm doing everything in one class. I want to take the play and death functions and put them in a class of their own.
My problem comes from two places. How do I get the Engine class to call the functions in the map class to make the game work? How do I know what to initialize in the Map/Engine class? I get that I'm supposed to initialize something but I have no idea how to come up with it. What should be my first thought when deciding what to initialize?
Non-functioning code (my best attempt): http://codepad.org/ELlaHQiB
from sys import exit
class Map(object):
def redroom(self):
prompt = raw_input("> ")
if "white" in prompt:
return "whiteroom"
elif "blue" in prompt:
return "blueroom"
else:
print "DOES NOT COMPUTE (RED ROOM)"
return 'death'
def whiteroom(self):
prompt = raw_input("> ")
if "red" in prompt:
return "redroom"
elif "blue" in prompt:
return "blueroom"
else:
print "DOES NOT COMPUTE (WHITE ROOM)"
return 'death'
def blueroom(self):
prompt = raw_input("> ")
if "white" in prompt:
return "whiteroom"
elif "red" in prompt:
return "redroom"
else:
print "DOES NOT COMPUTE (BLUE ROOM)"
return 'death'
class Engine(object):
def __init__(self, start):
self.start = start
def play(self):
next = self.start
while True:
print "\n---------"
room = getattr(self,next)
next = room()
def death(self):
exit(1)
x = Engine("redroom")
x.play()
Also, I'm unsure of the play function. It works but only because I got it from the tutorial I was reading. What is the purpose of the next variable becoming self.start and then becoming room() in the while loop?

This is what I would do.
class Engine(object):
def __init__(self,rooms):
self.rooms = rooms
self.current = 0
def next(self):
self.rooms[self.current]()
self.current += 1
if len(self.rooms) == self.current:
self.current = 0
# or whatever logic you want.
m = Map()
rooms = [m.redroom, m.whiteroom, m.blueroom]
e = Engines(rooms)
e.next() # should call redroom of class Map
e.next() # should call whiteroon etc

Related

method not working when i call it from another method for random name gen in python

I am creating a random name generator using OOP in python however i am very new to this concept which is why i am having so difficulties with accessing methods in other methods. I read a post on stack overflow which said to call a method inside another method in a class, you must add self.funcname(param) however i have already done this and it still does not work
class Rndm_nme_gen:
def __init__(self):
print("THE RANDOM NAME GENERATOR")
self.value = ""
self.range = 5
self.counter = 0
self.loop = True
self.names = []
self.loop2 = True
self.take_input()
def take_input(self):
while self.loop:
user_input = input("ENTER A NAME: ")
self.num_check(user_input)
if self.value == "true":
print("INVALID NAME")
loop = True
elif self.value == "false":
self.counter += 1
self.names.append(user_input)
if self.counter == 5:
self.loop = False
self.genname()
#i am trying to call this function but it is not working as i hoped it would
def num_check(self, string):
self.string = string
for char in self.string:
if char.isdigit():
self.value = "true"
else:
self.value = "false"
def genname(self):
while self.loop:
gen = input("TYPE ENTER TO GENERATE A NAME OR TYPE 'q' TO QUIT").strip().lower()
if gen == " " or gen == "":
num = random.randint(0, 5)
print("NAME : " + str(self.names[num]))
loop == True
elif gen == 'q':
quit()
else:
print("UNKNOWN COMMAND")
loop = True
user1 = Rndm_nme_gen()
In the initialisation method, i called the take_input function so it automatically runs and from that function, i attempted to run the code from the genname function however the program would simply end
If you would like to run the code to see how it works, feel free to do so
Expected output:
ENTER NAME FDSF
ENTER NAME dfsd
ENTER NAME sdfds
ENTER NAME sfdff
ENTER NAME sfdf
TYPE ENTER TO GENERATE A NAME OR TYPE 'q' TO QUIT
it does not say TYPE ENTER TO GENERATE A NAME OR TYPE 'q' TO QUIT when i run the program

ERROR: EmptyRoom(), NameError: name 'EmptyRoom' is not defined

ERROR: Line 29, in Map 'empty_room' :
I have tried rewriting my classes and other small things and have not been able to come up with any solutions. My indentations are correct(or so they seem) on notepad++ they just didn't transfer over very well to SOF. Any troubleshooting is appreciated:) THANK YOU!!
P.S. I am learning on my own with the book 'Learn Python the Hard Way' and I am doing an exercise to make a game similar to zork. Hope this helps.
from sys import exit
class Scene(object):
def enter(self):
print "This scene is not configured"
exit(1)
class Engine(object):
##calling Engine(x) x is the mapScene
def __init__(self, mapScene):
self.mapScene = mapScene
def play(self):
currentScene = self.mapScene.openingScene()
while True:
print "\n-------------------"
nextSceneName = currentScene.enter()
currentScene = self.mapScene.nextScene(nextSceneName)
class Map(object):
scenes = {
'empty_room': EmptyRoom(),
'living_room': LivingRoom(),
'office': Office(),
'hallway': Hallway(),
'kitchen': Kitchen(),
'master_bedroom': MasterBedroom(),
'kids_bedroom': KidsBedroom(),
'attic': Attic()
}
##when calling Map(x) x is the startscene
def __init__(self, startScene):
self.startScene = startScene
##When calling nextScene(x) x is the sceneName
def nextScene(self, sceneName):
return Map.scenes.get(sceneName)
##????
def openingScene(self):
return self.nextScene(self.startScene)
class EmptyRoom(Scene):
def enter(self):
print ""
action = raw_input("> ")
if action == "open door":
return 'living_room'
class LivingRoom(Scene):
def enter(self):
print ""
action = raw_input("> ")
if action == "kitchen":
return 'kitchen'
elif action == "stairs" or "go upstairs":
print "The steps creek as you ascend to the unknown..."
print "Are you sure you want to go up here?"
action = raw_input("> ")
if action == "yes" or "kinda":
return 'hallway'
else:
return 'living_room'
elif action == "empty room":
return 'empty_room'
else:
return 'living_room'
class Kitchen(Scene):
def enter(self):
print ""
action = raw_input("> ")
if action == "office" or "go right":
return 'office'
elif action == "living room":
return 'living_room'
else:
return 'kitchen'
class Office(Scene):
def enter(self):
print ""
action = raw_input("> ")
if action == "kitchen":
return 'kitchen'
class MasterBedroom(Scene):
def enter(self):
print ""
action = raw_input("> ")
if action == "hallway":
return 'hallway'
class KidsBedroom(Scene):
def enter(self):
print ""
action = raw_input("> ")
if action == "hallway":
return 'hallway'
class Hallway(Scene):
def enter(self):
print ""
action = raw_input("> ")
if action == "downstairs" or "stairs" or "living room":
return 'living_room'
elif action == "bedroom" or "master bedroom" or "left":
return 'master_bedroom'
elif action == "kids room" or "kids bedroom" or "right":
return 'kids_bedroom'
elif action == "pull string":
print"You have just opened the attic staircase would you like to go up?"
action = raw_input("> ")
if action == "yes":
return 'attic'
elif action == "no" or "nope":
return 'hallway'
else:
print "I wouldn't have went either\n"
print "SMASH, the attic door springs shut\n"
return 'hallway'
else:
return 'hallway'
class Attic(Scene):
def enter(self):
print ""
action = raw_input("> ")
if action == "downstairs" or "hallway":
return 'hallway'
aMap = Map('empty_room')
aGame = Engine(aMap)
aGame.play()
The class definition should come first before it is used.
class EmptyRoom(Scene):
def enter(self):
print ""
action = raw_input("> ")
if action == "open door":
return 'living_room'
class Map(object):
scenes = {
'empty_room': EmptyRoom(),
...
}
Same for LivingRoom, Office, Hallway, Kitchen, MasterBedroom, KidsBedroom, Attic.
The definition of scenes inside Map is run when the class is being built, not when you later call the class to instantiate it. At that time, EmptyRoom doesn't exist yet - Python works from the top of your code down, so EmptyRoom only exists after it has reached the end of the indented block underneath class EmptyRoom:. So for this to work, Map needs to go after all of your other classes rather than before.

Simple Python Game (stuck on classes)

I'm really stuck on this simple user input game I created. It's an exercise from learn python the hard way. I've been trying for over a week to figure it out on my own and finally caved in to asking for help. I think the problem point in my code is the Engine() class. Anyway here's the code:
from sys import exit
from random import randint
class Island(object):
def enter(self):
pass
class Engine(object):
def __init__(self, island_map):
self.island_map = island_map
def play(self):
current_island = island_map.opening_island()
last_island = self.island_map.next_island('Tropical')
while current_island != last_island:
next_island_name = current_island.enter()
current_island = self.island_map.next_island(next_island_name)
current_island.enter()
class Loser(Island):
snippets = ["Welcome to loser Island",
"Can't win them all",
"There's always next time"]
def enter(self):
print "Game over"
print Loser.snippets[randint(0,len(self.snippets)-1)]
exit(1)
class Jungle(Island):
def enter(self):
print "Welcome to the Jungle!"
print "You must fight the monkey to pass!"
print "Choose your weapon..."
weapons = ['stick', 'fly swatter', 'banana']
print weapons
fighter_weapon = raw_input("Choose from a a weapon above...")
if fighter_weapon == 'stick':
print "Stick can't beat a monkey!"
print "Monkey wins"
return 'Loser'
elif fighter_weapon == 'fly swatter':
print "The monkey steals your fly swatter"
print "Monkey wins"
return 'Loser'
elif fighter_weapon == 'banana':
print "The monkey is hypnotized by the banana"
print "You continue to the next island..."
return 'Frozen'
else:
print "What? Doesn't make sense"
return 'Jungle'
class Frozen(Island):
#add green, blue circle, and black diamond
def enter(self):
print "This is snow land"
print "Here's your snowboard, choose your path"
print "([[[[[[[[[)"
runs = ["green", "blue", "black"]
print runs
run_choice = raw_input(" >")
if run_choice == 'green':
print "Easy way out?"
print "No good"
print "Wrong"
return 'Loser'
elif run_choice == 'blue':
print "okay, at least not the easiest way"
print "You have some guts, I'll let you choose one more time"
return 'Frozen'
elif run_choice == 'black':
print "I like your style"
print "Going for the hard choice shows courage"
print "Continue to the next island"
return 'Tropical'
else:
print "Say whaaat?!"
return 'Frozen'
class Tropical(Island):
def enter(self):
print "You made it to the final Island!"
print "Look here's the treasure chest!"
print " All that's left to do is guess the code on the chest"
print "Be smart, you only get five guesses..."
t_key = "1234"
chest_guess = raw_input("What do you think it is?")
guesses = 0
while chest_guess != t_key and guesses < 4:
print "Guess again"
guesses += 1
chest_guess = raw_input(" ?")
if chest_guess == t_key:
print "You guessed right!"
print "You won"
else:
print "Sorry"
return 'Loser'
class Map(object):
islands = {
'Loser': Loser(),
'Jungle': Jungle(),
'Frozen': Frozen(),
'Tropical': Tropical(),
}
def __init__(self, start_island):
self.start_island = start_island
def next_island(self, island):
val = Map.islands.get(island)
return val
def opening_island(self):
return self.next_island(self.start_island)
mj_map = Map('Jungle')
mj_game = Engine(mj_map)
mj_game.play()
Right now I'm stuck on an error that states "island_map" is not defined in my Engine class. Which I don't understand because to me it looks like it is defined. Any input would be appreciated.
def play(self):
current_island = island_map.opening_island()
needs to be changed to
def play(self):
current_island = self.island_map.opening_island()
as it is apart of that instance

Why does my python class method behave differently by itself than when I run the module?

I am making a small text game, and one of my methods is behaving unexpectedly, and I can't figure out why. If I import the module and run the method in python, it works fine. Some parts of the game aren't complete, but that parts that I need run fine.
With the module pasted below, choose method is changing a list into a string, but only when the module is run. I'm running this on 2.7.3, on a mac.
Edit: I figured it out. The program execution had continued, and I was confused by the choose call in the match method. The options parameter sent in match was a string, instead of the list it should have been, but that was simple to figure out why.
import fighters
import weapons
from random import randint
from sys import exit
class Hero(object):
weapons = ["spikeglove", "shortsword"]
hp = {"actual":50, "base":50}
score = 0
def attack(self, weapon, method):
return None
class Scene(object):
# Returns one or more items from the provided choices
def choose(self, options, max_choices, prompt):
chosen = []
while len(chosen) < max_choices and len(options) > 0:
print
print prompt
print options, chosen
for o in options:
print "- {}".format(o)
print type(options)
choice = raw_input("> ")
if choice in options:
chosen.append(choice)
options.remove(choice)
print options, chosen
else:
print "That is not one of the options!"
if len(chosen) == 1:
return chosen[0]
else:
return chosen
class Death(Scene):
def enter(self):
print "You are now dead"
return "menu"
class Exit(Scene):
def enter(self):
print "Thanks for playing!"
return exit(1)
class Menu(Scene):
def enter(self):
menu_options = ["play", "train", "exit"]
choice = self.choose(menu_options, 1, "Welcome to the Arena!")
return choice
class Level(Scene):
def __init__(self):
self.prologue = "Welcome to {}".format(self.__class__.__name__)
next_scene = "level1"
# A match is the fight between the Hero and a particular Enemy
# A Hero must defeat each Enemy via a match to win the tournament/level
def match(self, hp, weapons, enemy):
hero_hp = hp
enemy_hp = enemy.stats["hp"]
last_attack = ""
while hero_hp and enemy_hp:
weapon_choice = self.choose(weapons, 1, "> ")
attack_choice = self.choose(weapon_choice.available_attacks(last_attack), 1, "> ")
last_attack = attack_choice
hero_attack = hero.attack(attack_choice)
enemy_attack = enemy.attack()
print "Hero: {} {}: {}".format(hero_hp, enemy, enemy_hp)
if hero_hp:
return "victory", hero_hp
else:
return "defeat"
# The game cycles through the enemies that our hero has to face
# passing the setup to the "match" function for the fighting
def enter(self):
print
print
print self.prologue
start_hp = hero.hp['actual']
weapons = self.choose(hero.weapons, 2, "Choose a weapon")
while self.enemies:
enemy = fighters.roster[self.enemies.pop()]
match_outcome, finish_hp = self.match(start_hp, weapons, enemy)
if match_outcome == "defeat":
hero.hp['actual'] = hero.hp['base']
return "death"
# The Hero enters the next match with the current HP obtained from the previous match
start_hp = finish_hp
# Add our Hero's victory points, and get them some medical attention
# before heading back to the Barracks
points_award = 5
hero.points += points_award
hero.hp['actual'] = hero.hp['base']
new_weapon = "shortsword"
hero.add_weapon(new_weapon)
epilogue = """Congratulations!
You have gained {} points for a total score of {}.\n
You have unlocked the \"{}\" """.format(
points_award, hero.points, new_weapon)
return next_scene
class Train(Scene):
pass
class Level1(Level):
enemies = ["boxer", "boxer"]
next_scene = "level2"
class Level2(Level):
pass
class Level3(Level):
pass
class Level4(Level):
pass
class Level5(Level):
pass
class Engine(object):
def __init__(self, start_scene):
self.start_scene = start_scene
scenes = {
"menu": Menu(),
"death": Death(),
"exit": Exit(),
"play": Level1(),
"level2": Level2(),
"level3": Level3(),
"level4": Level4(),
"level5": Level5(),
}
def next_scene(self, scene_name):
return self.scenes[scene_name]
def play(self):
current_scene = self.scenes[self.start_scene]
while True:
next_scene = current_scene.enter()
current_scene = self.scenes[next_scene]
if __name__ == "__main__":
hero = Hero()
game = Engine("menu")
game.play()
Terminal output:
$ python arena.py
Welcome to the Arena!
['play', 'train', 'exit'] []
- play
- train
- exit
<type 'list'>
> play
['train', 'exit'] ['play']
Welcome to Level1
Choose a weapon
['spikeglove'] []
- spikeglove
<type 'list'>
> spikeglove
[] ['spikeglove']
>
spikeglove []
- s
- p
- i
- k
- e
- g
- l
- o
- v
- e
<type 'str'>
Yet when I run in python:
>>> import arena
>>> s = arena.Level1()
>>> s.choose(['shortsword', 'spikeglove'], 2, "Choose a weapon")
Choose a weapon
['shortsword', 'spikeglove'] []
- shortsword
- spikeglove
<type 'list'>
> shortsword
['spikeglove'] ['shortsword']
Choose a weapon
['spikeglove'] ['shortsword']
- spikeglove
<type 'list'>
> spikeglove
[] ['shortsword', 'spikeglove']
['shortsword', 'spikeglove']
The if __name__ == "__main__": means that the portion of code indented after that if-statement will be executed only when the script is executed, not when it is imported.

How do I create lists in Python while using object oriented programming? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I'm trying to create an initial attribute that also creates a list.
class Player(object):
"""A virtual player"""
def __init__(self, name, items, max_items = 5):
# still need to create item list
self._items = []
self.name = name
self.max_items = max_items
print "\nA new player named",self.name,"has been created.\n"
def inventory(self):
if len(self.items) > 1:
print "\nThe inventory is:"
print self.items
else:
print "Your inventory is empty"
def take(self, new_item):
if self.items <= self.max_items:
self.items.append(new_item)
else:
print "\nSorry, your inventory is completely full."
def drop(self, drop_item):
if drop_item not in self.items:
print "That item does not exist in your inventory."
else:
self.items.remove(drop_item)
def main():
player_name = raw_input("What name do you want to give the player?: ")
player = Player(player_name)
choice = None
while choice != 0:
print \
"""
Player Menu
0 - Quit
1 - Print inventory
2 - Add an item
3 - Drop an item
"""
try:
choice = int(raw_input("Choice: "))
except (ValueError):
print "Invalid number."
if choice == 0:
print "\nGoodbye\n"
elif choice == 1:
player.inventory()
elif choice == 2:
new_item = raw_input("What item do you wish to add to your inventory?: ")
new_item = new_item.lower()
player.take(new_item)
elif choice == 3:
drop_item = raw_input("What item do you want to drop?: ")
drop_item = drop_item.lower()
player.drop(drop_item)
# main
main()
raw_input("\nPress enter to exit.")
self._items = [] is absolutely correct.
But you have some logical errors in your code:
if len(self.items) > 1: should be if len(self.items) > 0: or even better if self.items: - you want to check if theres 1+ in the item, not if there's more than one item in the list.
try:
inp = raw_input # Python 2.x
except NameError:
inp = input # Python 3.x
def describe(lst):
if not lst:
return "nothing"
elif len(lst)==1:
return "a {0}".format(lst[0])
else:
return 'a {0}, and a {1}'.format(', a '.join(lst[:-1]), lst[-1])
class Player(object):
"""A virtual player"""
def __init__(self, name, items=None, max_items=5):
super(Player,self).__init__()
self.name = name
self.max_items = max_items
self.items = list(items)[:max_items] if items else []
print("A new player named {0} has been created.".format(self.name))
def inventory(self):
if self.items:
print("Your pockets contain: {0}.".format(describe(self.items)))
else:
print("Your pockets are empty.")
def take(self, new_item):
if len(self.items) < self.max_items:
self.items.append(new_item)
print("You take the {0}.".format(new_item))
return True
else:
print("Your pockets are too full.")
return False
def drop(self, drop_item):
try:
self.items.remove(drop_item)
print("You drop the {0}.".format(drop_item))
return True
except ValueError:
print("You have no {0}!".format(drop_item))
return False
def main():
print("Welcome, adventurer! What is your name?")
char = Player(inp(), ['string', 'blue key', 'pocketknife'])
commands = ['go', 'take', 'drop', 'inv', 'help', 'quit']
roomItems = ['ball', 'apple', 'dragon']
while True:
print("You are in the Baron's antechamber. You see {0}.".format(describe(roomItems)))
cmd = [i.lower() for i in inp('> ').strip().split()]
verb = cmd[0]
if verb in commands:
if verb=='go':
dir = ' '.join(cmd[1:])
print('You try to go {0}, but a giant kangaroo kicks you back into the antechamber.'.format(dir))
elif verb=='take':
item = ' '.join(cmd[1:])
if item in roomItems and char.take(item):
roomItems.remove(item)
elif verb=='drop':
item = ' '.join(cmd[1:])
if char.drop(item):
roomItems.append(item)
elif verb=='inv':
char.inventory()
elif verb=='help':
print("I know the words {0}.".format(', '.join(commands)))
elif verb=='quit':
break
else:
print("I don't know how to '{0}'.".format(verb))
print('The Baron has decided! There is a grating noise - the floor drops away like a trapdoor, and {0} plummets into darkness. THE END!'.format(char.name))
if __name__=="__main__":
main()
inp("Press enter to exit.")
You are calling the attibute self._items in the constructor but self.items else-where.
Maybe that is your problem, otherwise you need to explain what your problem is more clearly.

Categories