My game gets caught in a loop and doesn't continue after the last self.custom_input in def __init__(self):. Why does it restart from the beginning instead of calling game()?
class game(object):
def __init__(self):
self.Continue = None
self.game = None
self.score = score()
while self.Continue == None:
self.Continue = raw_input("Question")
print "Good Luck...."
while self.game not in ("no", "quit", "leave", "n"):
self.rounds = self.custom_input("How many rounds would you like? ", self.games)
game()
def game(self):
while self.score.rounds != self.rounds:
self.score.rounds += 1
self.user_choice = custom_input("question",self.plays)
self.computer_choice = computer_choice()
result = evaluate()
if result == "win":
print "statement" %(self.user_choice.capitalize(), self.computer_choice)
self.score.wins += 1
elif result == "loss":
print "statement" %(self.computer_choice.capitalize(), self.user_choice)
self.score.losses += 1
else:
print "statement" %(self.user_choice.capitalize())
self.draws += 1
self.score.rounds += 1
finals()
You've named the game.game function with the same name as the game class, as well as the self.game attribute, and the interpreter is assuming that you're trying to create a new instance of the game class. To fix this, try renaming the game function to play_game, and then do this:
self.play_game()
Related
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
I am fairly new to coding on Python. In my code, I am trying to change the myPlayer.hp and myPlayer.sp values based on what the myPlayer.job is. But, for some reason, regardless of job, the HP and SP values are still 0 when I check them in the program. If you know how to change them, please let me know and thank you.
Here is the code that deals with my question:
class player:
def __init__(self):
self.name = ''
self.job = ''
self.hp = 0
self.sp = 0
self.pwr = 0
self.res = 0
self.agi = 0
self.smr = 0
self.wll = 0
self.status_effects = []
self.location = 'b2'
self.game_over = False
myPlayer = player()
def main_game_loop():
while myPlayer.game_over is False:
prompt()
def setup_game():
os.system('cls')
question1 = "Hello, what's your name?\n"
for character in question1:
sys.stdout.write(character)
sys.stdout.flush()
time.sleep(0.05)
player_name = input("> ")
myPlayer.name = player_name
question2 = "Hello, what role do you want to play?\n"
question2added = "(You can play as a warrior, mage, or priest)\n"
for character in question2:
sys.stdout.write(character)
sys.stdout.flush()
time.sleep(0.05)
for character in question2added:
sys.stdout.write(character)
sys.stdout.flush()
time.sleep(0.01)
player_job = input("> ")
valid_jobs = ['warrior', 'mage', 'priest']
if player_job.lower() in valid_jobs:
myPlayer.job = player_job
print("You are now a " + player_job + "!\n")
while player_job.lower() not in valid_jobs:
player_job = input("> ")
if player_job.lower() in valid_jobs:
myPlayer.job = player_job
print("You are now a " + player_job + "!\n")
if myPlayer.job == 'warrior':
myPlayer.hp = 25
myPlayer.sp = 0
elif myPlayer.job == 'mage':
myPlayer.hp = 15
myPlayer.sp = 20
elif myPlayer.job == 'priest':
myPlayer.hp = 20
myPlayer.sp = 15
Your code isn't necessarily incorrect, but there is a good chance for an error when the player enters their job.
You have the following code:
if player_job.lower() in valid_jobs:
That means that if the player enters Warrior you understand that they meant warrior. That is good. But when you assign the player's job you do the following:
myPlayer.job = player_job
That can cause a problem, since you aren't calling lower() on the job.
Instead, you likely want:
myPlayer.job = player_job.lower()
That way, when you look at the player's job to assign sp and hp it will match the lowercase strings you are comparing it to.
This is what I have so far. I have created this class:
class VotingMachine :
def __init__(self):
self._voteCount = 0
self._totalVote = 0
def DemVote(self, vote):
self._voteDemCount = self._voteDemCount + 1
self._totalDemVote = self._totalDemVote + vote
def RepVote(self, vote):
self._voteRepCount = self._voteRepCount + 1
self._totalRepVote = self._totalRepVote + 1
def getDemTally(self):
return self._totalDemVote
def getRepTally(self):
return self._totalRepVote
def clear(self):
self._voteCount = 0
self._totalVote = 0
and this is what I have so far for the demo program.
from votingmachine import VotingMachine
print("Presidential Election")
print("---------------------")
print("R -- Republican")
print("D -- Democrat")
print("X -- Stop")
userInput = input("Enter your vote (R/D/X): ")
My instructions for this are as follows-
Create a voteDemo program that will create one object from the VotingMachine class. The voteDemo program should display a menu, allow the user to enter multiple votes until an X is entered, then show the tally of the Democratic and Republican votes, and also show which candidate won the election.
Make sure to consider that the election could end in a tie.
I know I have probably missed something really simple, but I am a complete beginner at this and do not understand how to go about calling the methods to be able to display a menu, etc. I would really appreciate it if someone would take the time to explain what I need to do to finish this up.
To complete this assignment you need to know how to:
Compare strings
first = "a"
second = "b"
third = "b"
print(first == second) # prints False
print(second == third) # prints True
Use a while loop. For example:
looping = True
while looping:
userInput = input("Press X to leave the loop")
if userInput == "X":
looping = False
print("Left the while loop")
Call methods
class Animal:
def __init__(self):
print("Creating animal")
def make_sound(self, sound):
print("Making a sound...")
print(sound)
# Create an instance of the Animal class.
animal = Animal()
# Call a method. The self parameter implicitly refers to the instance, animal.
animal.make_sound("meow")
You can solve the problem by combining these tools.
Here's a simple loop to do what you want:
userInput = ''
voting_machine = VotingMachine()
while userInput != 'x':
userInput = input("Enter your vote (R/D/X): ").lower()
if userInput == 'd':
pass
elif userInput == 'r':
pass
elif userInput == 'x':
break
else:
print("Wrong input! Try again!")
print(voting_machine.getDemTally())
print(voting_machine.getRepTally())
print("Bye!")
Actually, the definition of your class, has some errors, you didn't define attributes like _voteRepCount before using them.
You can instantiate (create a instance of) a class in python with the following code: machine = VotingMachine().
You might also want to check the code in your DemVote and RepVote methods. self._voteDemCount and self._voteRepCount need to be initialized in your __init__ function and the methods do different things with vote.
Instantiate a voting machine: machine = VotingMachine().
Then run a loop, asking for a vote, feeding it to the machine, and showing the tallies in each iteration.
class VotingMachine:
def __init__(self):
self._totalVote = 0
self._voteDemCount = 0
self._voteRepCount = 0
def demVote(self):
self._voteDemCount += 1
self._totalVote += 1
def repVote(self):
self._voteRepCount += 1
self._totalVote += 1
def getDemTally(self):
return self._voteDemCount
def getRepTally(self):
return self._voteRepCount
def getTally(self):
return self._totalVote
def clear(self):
self._totalVote = 0
voteDemo
from VotingMachine import *
election = VotingMachine()
print("Presidential Election")
vote = ''
while vote != 'X':
print("---------------------")
print("R -- Republican")
print("D -- Democrat")
print("X -- Stop")
vote = input("Enter your vote (R/D/X): ")
if vote == 'X':
print("Tally votes: "+str(election.getTally()))
if election.getDemTally() > election.getRepTally():
print("Democrat WIN")
elif election.getDemTally() < election.getRepTally():
print("Republican WIN")
else:
print("Draw")
print("(D:"+str(election.getDemTally())+" , R:"+str(election.getRepTally())+")")
elif vote == 'R':
election.repVote()
elif vote == 'D':
election.demVote()
else:
print("Vote invalid!")
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.
EDIT: I am using python 3.2! rest of post below...
I am finishing my text based RPG in python, and I need some help. I need to make a save/load game system. I read that I can use pickle a few other methods but thats not entirely what I want. Basically, I want to be able to save my variables into a text file. If the file exists, load the variables, and skip over the introduction where it asks the player for a name. I will give the pickle method and others try and see how they work. If someone would be kind enough to show me how I would do this with .txt files, I would be very grateful! I will continue digging and post my solution once I have found it.
EDIT:
I have removed the irrelevant parts of my original post. The following code is the WORKING game.py file. I no longer use a separate class module. Topic solved, now I can work on a storyline! :D
#A text based RPG
#Import required modules
import jsonpickle
import os
import sys
import time
from random import randint
#main game
#Variables
go = True
IsShopLocked = False
IsDaggerEquipped = False
IsSwordEquipped = False
IsLeatherHideEquipped = False
SAVEGAME_FILENAME = 'savegame.json'
game_state = dict()
### Classes ###
class Human(object):
#Represents the human player in the game
def __init__(self, name, health, strength, gold):
self.name = name
self.health = health
self.strength = strength
self.gold = gold
class AI(object):
#Represents the enemy player in the game
def __init__(self, name, health, strength):
self.name = name
self.health = health
self.strength = strength
class Item(object):
#represents any item in the game
def __init__(self, name, hvalue, strvalue):
self.name = name
self.hvalue = hvalue
self.strvalue = strvalue
###end classess###
###functions for loading, saving, and initializing the game###
def load_game():
"""Load game state from a predefined savegame location and return the
game state contained in that savegame.
"""
with open(SAVEGAME_FILENAME, 'r') as savegame:
state = jsonpickle.decode(savegame.read())
return state
def save_game():
"""Save the current game state to a savegame in a predefined location.
"""
global game_state
with open(SAVEGAME_FILENAME, 'w') as savegame:
savegame.write(jsonpickle.encode(game_state))
def initialize_game():
"""If no savegame exists, initialize the game state with some
default values.
"""
global game_state
player = Human('Fred', 100, 10, 1000)
enemy = AI('Imp', 50, 20)
state = dict()
state['players'] = [player]
state['npcs'] = [enemy]
return state
###End functions for loading, saving, and initalizing the game###
###Main game functions###
#Function for the shop
def Shop():
global game_state
player = game_state['players'][0]
dagger = Item('Dagger', 0, 5)
sword = Item('Sword', 0, 10)
leather_hide = Item('Leather Hide', 5, 0)
if IsShopLocked == True:
print("The shop is locked!\nPlease go back and continue your adventure!")
else:
print()
print("Welcome to the Larkville shop! What would you like to buy?\n1. Weapons\n2. armor\n3. Go back")
selection = int(input("Enter a value: "))
if selection == 1:
if player.gold >= 50:
print("Weapons shop")
print("1. Bronze Dagger: $20\n2. Bronze Sword: $50")
wpnselection = int(input("Enter a value: "))
if wpnselection == 1:
global IsDaggerEquipped
global IsSwordEquipped
if IsDaggerEquipped == True or IsSwordEquipped == True:
print("You already have this or another weapon equipped...")
Game_Loop()
else:
dagger = Item('Dagger', 0, 5)
IsDaggerEquipped = True
player.strength += dagger.strvalue
player.gold -= 20
print("strength increased to: {}".format(player.strength))
Game_Loop()
elif wpnselection == 2:
if IsDaggerEquipped == True or IsSwordEquipped == True:
print("You already have this or another weapon equipped...")
Game_Loop()
else:
sword = Item('Sword', 0, 10)
IsSwordEquipped = True
player.strength += sword.strvalue
player.gold -= 50
print("strength increased to: {}".format(player.strength))
Game_Loop()
elif wpnselection == 3:
Game_Loop()
elif selection == 2:
if player.gold >= 20:
print ("Armor Shop")
print ("1. Leather hide\n2. Go back")
armselection = int(input("enter a value: "))
if armselection == 1:
global IsLeatherHideEquipped
if IsLeatherHideEquipped == True:
print("You are already wearing armor!")
Game_Loop()
else:
leather_hide = Item('Leather Hide', 5, 0)
IsLeatherHideEquipped = True
player.health += leather_hide.hvalue
player.gold -= 20
print("Health increased to: {}".format(player.health))
Game_Loop()
elif armselection == 2:
Game_Loop()
elif selection == 3:
Game_Loop()
#Function for combat
def Combat():
global game_state
player = game_state['players'][0]
enemy = game_state['npcs'][0]
global go
while go == True:
dmg = randint (0, player.strength)
edmg = randint (0, enemy.strength)
enemy.health -= dmg
if player.health <= 0:
os.system('cls')
print()
print("You have been slain by the enemy {}...".format(enemy.name))
go = False
leave = input("press enter to exit")
elif enemy.health <= 0:
os.system('cls')
print()
print("You have slain the enemy {}!".format(enemy.name))
go = False
leave = input("press any key to exit")
else:
os.system('cls')
with open("test.txt", "r") as in_file:
text = in_file.read()
print(text)
player.health -= edmg
print()
print("You attack the enemy {} for {} damage!".format(enemy.name, dmg))
print("The enemy has {} health left!".format(enemy.health))
print()
print("The enemy {} attacked you for {} damage!".format(enemy.name, edmg))
print("You have {} health left!".format(player.health))
time.sleep(3)
#The main game loop
def Game_Loop():
global game_state
while True:
print()
print("You are currently in your home town of Larkville!")
print("What would you like to do?")
print("1. Shop\n2. Begin/continue your adventure\n3. View player statistics\n4. save game")
print()
try:
selection = int(input("Enter a value: "))
except ValueError:
print()
print("You can only use the numbers 1, 2, or 3.")
print()
Game_Loop()
if selection == 1:
Shop()
elif selection == 2:
Combat()
elif selection == 3:
player = game_state['players'][0]
print()
print("Your players stats:\nHealth: {}\nStrength: {}\nGold: {}".format(player.health, player.strength, player.gold))
if IsDaggerEquipped == True:
print("You have a dagger equipped")
elif IsSwordEquipped == True:
print ("You have a sword equipped")
elif IsLeatherHideEquipped == True:
print("You are wearing a leather hide")
elif selection == 4:
game_state = save_game()
else:
print()
print("Oops! Not a valid input")
print()
###End main game functions###
###The "main" function, not to be confused with anything to do with main above it###
def main():
"""Main function. Check if a savegame exists, and if so, load it. Otherwise
initialize the game state with defaults. Finally, start the game.
"""
global game_state
if not os.path.isfile(SAVEGAME_FILENAME):
game_state = initialize_game()
else:
game_state = load_game()
Game_Loop()
if __name__ == '__main__':
main()
###end main function###
You can use jsonpickle to serialize your object graph to JSON. jsonpickle is not part of the standard library, so you'll have to install it first, for example by doing easy_install jsonpickle.
You could also achieve the same using the standard library json module, but then you'd have to implement your own JSONEncoder to deal with your custom objects. Which isn't hard, but not as easy as just letting jsonpickle do it for you.
I used simplified examples of your player classes to demonstrate how you could implement load and save functionality for the objects that constitute your game state (completely ignoring any story line):
import jsonpickle
import os
import sys
SAVEGAME_FILENAME = 'savegame.json'
game_state = dict()
class Human(object):
"""The human player
"""
def __init__(self, name, health, gold):
self.name = name
self.health = health
self.gold = gold
class Monster(object):
"""A hostile NPC.
"""
def __init__(self, name, health):
self.name = name
self.health = health
def load_game():
"""Load game state from a predefined savegame location and return the
game state contained in that savegame.
"""
with open(SAVEGAME_FILENAME, 'r') as savegame:
state = jsonpickle.decode(savegame.read())
return state
def save_game():
"""Save the current game state to a savegame in a predefined location.
"""
global game_state
with open(SAVEGAME_FILENAME, 'w') as savegame:
savegame.write(jsonpickle.encode(game_state))
def initialize_game():
"""If no savegame exists, initialize the game state with some
default values.
"""
player = Human('Fred', 100, 10)
imp = Monster('Imp', 50)
state = dict()
state['players'] = [player]
state['npcs'] = [imp]
return state
def attack():
"""Toy function to demonstrate attacking an NPC.
"""
global game_state
imp = game_state['npcs'][0]
imp.health -= 3
print "You attacked the imp for 3 dmg. The imp is now at %s HP." % imp.health
def spend_money(amount):
"""Toy function to demonstrate spending money.
"""
global game_state
player = game_state['players'][0]
player.gold -= amount
print "You just spent %s gold. You now have %s gold." % (amount, player.gold)
def game_loop():
"""Main game loop.
This loop will run until the player exits the game.
"""
global game_state
while True:
print "What do you want to do?"
choice = int(raw_input("[1] Save game [2] Spend money "
"[3] Attack that Imp! [4] Load game "
"[5] Exit game\n"))
if choice == 1:
save_game()
elif choice == 2:
spend_money(5)
elif choice == 3:
attack()
elif choice == 4:
game_state = load_game()
else:
print "Goodbye!"
sys.exit(0)
def main():
"""Main function. Check if a savegame exists, and if so, load it. Otherwise
initialize the game state with defaults. Finally, start the game.
"""
global game_state
if not os.path.isfile(SAVEGAME_FILENAME):
game_state = initialize_game()
else:
game_state = load_game()
game_loop()
if __name__ == '__main__':
main()
Note the global game_state variable. You need something like that to keep track of all the objects that define your game state and keep them together for easy serialization / deserialization. (It doesn't necessarily have to be global, but it's definitely easier, and a game state like this is one of the few cases where it actually makes sense to use globals).
Saving the game using this code will result in a savegame.json that looks like this:
{
"npcs": [
{
"health": 41,
"name": "Imp",
"py/object": "__main__.Monster"
}
],
"players": [
{
"gold": 5,
"health": 100,
"name": "Fred",
"py/object": "__main__.Human"
}
]
}