So, I have this input command that's supposed to give the user unprompted input and if it's an invalid command to output 'input' is an invalid command. However, go north, west, etc. is a valid command but the code does not recognize it as so. Pls help :)
btw, player is a module that has a class in it for moving the player's location.
Code:
import world, tiles
from player import Player
game = "play"
while game == "play":
x = input()
y = " is not a valid command"
string = x + y
if x == "go north":
Player.go_north
if x == "go south":
Player.go_south
if x == "go east":
Player.go_east
if x == "go west":
Player.go_west
if x == "pick up":
print("pick up what?")
else:
print(string)
There seems to be a couple of things wrong potentially. First, Player.go_* are being referenced as attributes, but I expect they should be functions if they do something? Technically I guess they could be properties, but this feels like the wrong way to use them.
Second, I think your if/else logic is not what you want. You check for each direction, but even if it suceeds, it drops down to the next if statement. So what happens is at the last check, if it's not "pick up", it will always print the invalid command string. You either want every conditional to be part of a if/elif/else so that once it hits one, it skips the others, or you need to have a continue after any successful check, since if you find a match, you just want to continue with the loop.
So something like:
import world, tiles
from player import Player
player = Player()
game = "play"
while game == "play":
x = input()
y = " is not a valid command"
string = x + y
if x == "go north":
player.go_north()
elif x == "go south":
player.go_south()
elif x == "go east":
player.go_east()
elif x == "go west":
player.go_west()
elif x == "pick up":
print("pick up what?")
else:
print(string)
Related
I'm creating a text adventure game, and want to make it so if the user types 'x' or 'examine', it prints the description for a room (which is stored in a string inside the a function)
This is the code:
def look(dsc):
print(dsc)
def usr_input(dsc):
a = input(">>> ")
if a == "examine" or a == "x":
look(dsc)
if a == "help":
print("north, n, east, e, south, s, west, w, up, u, down, d, inventory, i, examine, x")
if a == "north" or a == "n" or a == "forwards":
return "north"
if a == "east" or a == "e" or a == "right":
return "east"
if a == "south" or a == "s" or a == "backwards":
return "south"
if a == "west" or a == "w" or a == "left":
return "west"
if a == "up" or a == "u":
return "up"
if a == "down" or a == "d":
return "down"
else:
print("Sorry, I don't understand that. (Type 'help' for a list of commands")
usr_input()
return False
def room_00():
room_description = "Description goes here"
print(room_description)
usr_input(room_description)
room_00()
Basically, I need the function 'look' to print the description for that room whenever the user types x, but I can't get the functions to link.
Your code seems to run without any issue, ignore the guy above, Python 3 does need brackets for print calls.
It is returning a traceback though because on line 28, you're calling the usr_input() function without providing a parameter.
You can fix this by defining the function like so:
def look(dsc=''):
print(dsc)
This will pass an empty string to the function unless you pass it a string of your own.
The other issue is that you're using raw if statements. So that last evaluation here:
if a == "down" or a == "d":
return "down"
else:
print("Sorry, I don't understand that. (Type 'help' for a list of commands")
usr_input()
return False
goes to the else branch because x is neither "down" nor "a", you should replace all if statements below the first one with elif, and leave the last else in place
Try a = raw_input('>>> ') and then a = a.strip()
also
def look(dsc):
print dsc
You need a tab there and no need for ()
I think the right solution will be creating the class Room, instances of which would store room description and maybe something else, perhaps, a list of doors to other rooms (you are not going to have only one room, are you?)
And this class should also have look method doing you already know what.
I think you should store the current room in some global variable and when you need the current room's description, you just access that variable, get the Room object and call its look method.
As I know, accessing function local variable is impossible. If I am wrong, correct me please.
I get the following error on the code below, and have no idea what is going on. I'm very much a beginner and need some help. I am trying to make a very basic game of tic-tac-toe in the console, and am having trouble.
Traceback (most recent call last):
File "D:/Eric/Projects/Tic Tac Toe/Tic Tac Toe.py", line 68, in <module>
printboard()
File "D:/Eric/Projects/Tic Tac Toe/Tic Tac Toe.py", line 15, in printboard
print("",c[0],"|",c[1],"|",c[2],"\n-----------\n",c[3],"|",c[4],"|",c[5],"\n-----------\n",c[6],"|",c[7],"|",c[8])
TypeError: 'str' object is not callable
Code:
import random, time
#Variables
c = [str(i) for i in range(1,10)] #Cells
cpuletter = "string input"
coinoptions = ["heads", "tails"]
coinflip = random.choice(coinoptions)
play = ""
playercell = 0
#Functions
def printboard(): #Prints the gameboard with the cell variables in the spaces
print("",c[0],"|",c[1],"|",c[2],"\n-----------\n",c[3],"|",c[4],"|",c[5],"\n-----------\n",c[6],"|",c[7],"|",c[8])
return
#Introduction
print("Welcome to Tic Tac Toe. Below is the playing table.") #Welcome + Explanation
printboard()
print("The playing spaces are numbered 1 through 9.\nYou will use these numbers to refer to the places you would like to play your piece.\n")
#X or O?
playerletter = input("Would you like to be X's or O's?\n")
playerletter = playerletter.capitalize()
playerletter = playerletter[0]
while playerletter not in ["X", "O"]: #Confirm choice == "X" or "O." If not, ask again.
playerletter = input("""Sorry, that's not a valid option. Please choose "X" or "O."\n""")
playerletter = playerletter.capitalize()
playerletter = playerletter[0]
if playerletter == "X":
cpuletter = "O"
elif playerletter == "O":
cpuletter = "X"
#Who goes first?
playercoin = input("Randomizing who goes first:\nDo you choose heads or tails?\n") #Asking for "heads" or "tails"
playercoin = playercoin.lower()
while playercoin not in ["heads", "tails"]: #Confirm choice == "Heads" or "Tails." If not, ask again.
playercoin = input("""Sorry, that's not a valid option. Please choose "heads" or "tails."\n""")
playercoin = playercoin.lower()
print("...")
time.sleep(1) #Waits 1 seconds
if coinflip != playercoin: #Tells player who goes first
print("It landed " + coinflip + "! I will go first.")
play = 0
elif coinflip == playercoin:
print("It landed " + coinflip + "! You will go first.")
play = 1
#Game
input("""Ready to play? Press "Enter" to begin!\n""")
if play == 0:
random_index = random.randrange(9) #Randomly selects a cell to change to cpuletter
c[random_index] = cpuletter
print = ("Here is my move.")
printboard()
elif play == 1: #Allows player to choose cell to change to playerletter
printboard()
playercell = int(input("It's your turn. Type a cell number to choose where you play.\n"))
playercell = playercell - 1
c[playercell] = playerletter
printboard()
Edit: Forgot to say that this only happens when the computer goes first, and not the player. I fixed the print = ("Here is my move.") but am still having problems.
print = "Here is my move."
That line reassigns the builtin print function to a string. Don't do that.
Why make such a complex printing function? Format would come very handy right about now:
def printboard(): #Prints the gameboard with the cell variables in the spaces
table = \
'''
{} | {} | {}
----------
{} | {} | {}
----------
{} | {} |
'''
print(table.format(c[1],c[2],c[3],c[4],c[5],c[6],c[7],c[8]))
return
And finally to fix your error, change line 65:
move = ("Here is my move")
I ran your code, but I did not get any errors. This particular TypeError is usually caused by programmers mistakenly switching out square brackets with parentheses (therefore "calling" it as if the string was a function, which it's not.). Please check and run your code again.
EDIT: Solution: Change the variable name of print = "Here is my move." on line 65 to something else, like movePrint = "Here is my move".
I need to debug a program where all the variables have been replaced by different names. The game is the minesweesper.
Can someone help me just to identify what the variable pikantny is?
The code:
def startGame():
board = reset()
board.start()
pikantny = True
while ((pikantny) and (board.mines < 10)):
board.printGrid()
answer = validateOption("Do you want to check a square ('c') or plant/remove a flag ('f')? ", ["c", "f"])
x = validateCoordinate("Enter the X coordinate:", 0, 9)
y = validateCoordinate("Enter the Y coordinate:", 0, 9)
if answer == "f":
if board.mines + board.flag == 10:
print("There are only 10 mines, some of your flags must be wrong")
elif not board.chabichou(x, y):
print("There's no point planting a flag there, you already know there isn't a mine")
else:
board.hirtenkase(x, y)
else:
if not board.chabichou(x, y):
print("You have already checked that square")
elif board.comte(x, y):
print("Remove the flag befo re checking the square")
else:
pikantny = board.checkSquare(x, y)
if not pikantny:
print("**** BOOM ****")
board.printGrid(True)
print("You found", board.mines, "mines")
print(board.flag, "of your flags were wrong")
pikantny is initially set to True, the game only runs as long as it is True, and if the value is set to False (by board.checkSquare(x, y)), the game prints the message "**** BOOM ****". I'd say it represents whether a bomb has been clicked (False) or not (True).
(It seems to translate from Polish as "spicy" or "racy", which is not as illuminating as I thought it might be when I first tried to translate it.)
It's a flag that indicates if you're still alive. It gets set to false, when you hit a mine.
I'm writing a text-based game where I ask the user the turn different directions in python. I'm wanting to set it up so synonyms/variations of the option can be used (such as "Right", or "right", or "r", or "R") but don't want to have to run that in every if/else statement. I've tried making each possible option a variable:
left = "Left" or "left" or "l" or "L"
right = "Right" or "right" or "r" or "R"
forward = "Forward" or "forward" "f" or "F"
axe = "Axe" or "axe" or "a" or "A"
sword = "Sword" or "sword"
slingshot = "Slingshot" or "slingshot"
yes = "Yes" or "yes" or "y" or "Y"
no = "No" or "no" or "n" or "N"
Then I tried calling it when I put in an if/else statement after an input:
def section1():
#If the person does want to go forward
def confirm():
con = input("Are you absolutely sure you want to go this way? ")
if con == no:
print("You have gone back")
time.sleep(0.75)
section1()
elif con == yes:
section1b()
else:
print("Sorry I didn't get that")
time.sleep(0.75)
confirm()
direction = input('What way would you like to go? Right, or forward? ')
if direction == forward:
print("WARNING! This direction is well known for the great danger that make await where death is inevitable!")
confirm()
elif direction == right:
print("You begin your journey down the creepy corners and dark alleys.")
time.sleep(1)
section2()
else:
print("That's not an option")
section1()
direction = input('What way would you like to go? Right, or forward? ')
if direction == forward:
print("WARNING! This direction is well known for the great danger that make await where death is inevitable!")
confirm()
elif direction == right:
print("You begin your journey down the creepy corners and dark alleys.")
time.sleep(1)
section2()
else:
print("That's not an option")
section1()
Though when I run the code and input "right" or "forward" it goes to the else statement and prints "That's not an option" then loops back. Is there another method to me getting the synonyms (I've tried the same with making the synonyms a list), or is my syntax just not right?
Python does not work like that. When Python executes the line -
left = "Left" or "left" or "l" or "L"
It executes the boolean expression "Left" or "left" or "l" or "L" and stores its result in left , the result of that boolean expression would be Left , so left then points to the string "Left". It does not delay the evaluation of the boolean expression. Example to show you that -
>>> left = "Left" or "left" or "l" or "L"
>>> left
'Left'
You should create a set (since you would be searching those sets all the time, and set provide constant time searching ( O(1) )) for each of the left ,right , etc and use that instead. Example -
left = set(["Left","left","l","L"])
right = set(["Right","right","r","R"])
Use it using in operator -
if direction in forward:
and
elif direction in right:
heres my code
direction = 0
while direction != ("quit"):
direction = input("> ")
if direction[0:4] != "quit" and direction != "go north" and direction != "go south" and direction != "go east" and direction != "go west" and direction != "go up" and direction != "go down" and direction[0:4] != "look":
if direction[0:2] == "go" and direction[3:] == (""):
print("please tell me more")
else:
print("huh?")
elif direction[0:1] == "go" and direction != "north" and direction != "south" and direction != "east" and direction != "west" and direction != "up" and direction != "down":
print ("please tell me more")
elif direction[0:4] == "quit":
print ("OK ... but a small part of you may never leave until you have personally saved Muirfieland from the clutches of evil .. Bwahahahahahah (sinister laugh).")
elif direction[0:4] == "look":
print ("You see nothing but endless void stretching off in all directions ...")
else:
print ("You wander of in the direction of " + direction)
im trying to add this into my code
if the first word is recognised but the second is not, it will respond with :
"sorry, im afraid i cant do that"
im just having troubles getting that one bit into my code, any help will be appreciated thanks.
So quick analysis... You're making text parser which works as following:
Get first word of "command", if we don't know word user used invalid input -> inform and restart
If user used known "command", parse its arguments (like: go north, go south) and let "nested" function take care of argument
Note that "main parsing function" doesn't need to know whether arguments for go() are valid, it just delegates responsibility for validation to go().
So I think you should build code (class) like this:
class Game:
# Initialize internal variables, method automatically called on g = Game()
def __init__(self):
self._exit = False
# Array of known commands, used in run, basically maps commands
# to function and it says: if will get 'go' execute self._go
self._commands = {
'go': self._go,
'quit': self._quit
}
# Array of go sub commands, used by _go
self._commands_go = {
'north': self._go_north
# ...
}
# Mathod for parsing command, if it gets "comamnd" returns ("command",None)
# if "command arg1 arg2" returns ("command", "arg1 arg2")
#staticmethod
def parse_command(string):
string = str(string)
index = string.find(' ')
if index < 0:
return (string, None)
return (string[:index], string[index+1:])
# This is main method; the only one which should be called from outside
# It will just read data from input in never ending loop and parse commands
def run(self):
while not self._exit:
src = input('> ')
(command,args) = Game.parse_command( src)
# Do we have this command, execute it
if command in self._commands:
self._commands[command](args)
else:
print( 'I\'m sorry I don\'t known command {}, try one of these:'.format(command))
print( '\n'.join( self._commands.keys()))
#######################################################
# All game commands go here
#######################################################
def _quit(self,args):
self._exit = True
print( 'Bye bye')
# Movement handling, will get executed when user types 'go ...' nad '...' will be in arg
def _go(self,args):
# No argument
if args is None:
print( 'Go excepts one of these:', '; '.join( self._commands_go.keys()))
return False
# Split sub command anr arguments
(command,args) = Game.parse_command(args)
if command not in self._commands_go:
print( 'Go excepts one of these:', '; '.join( self._commands_go.keys()))
return False
if args is not None:
print( 'Too many arguments for go')
return False
self._commands_go[command](args)
return True
# Go north
def _go_north(self, args):
print( 'Going north')
game = Game()
game.run()
Which would allow you to:
build complex nested commands
build nice and readable commands hierarchy (inventory item 123 update use potion 345) instead of hardly readable set of complex conditions
build function aliases go north can be aliased as gn by adding 'gn': self._go_north to _commands
build reusable arguments parsing (item_id, action, args) = self._parse_item_action(args)
take advantages of object oriented programming (no global variables, everything will be class attribute, lower risk of accidental variables overwriting)
And if you need to parse goasdf as go you can just simply:
for i in self._commands:
if input.startswirh( i):
return self._commands[i](...)
print('Invalid command')
return False
Note: I haven't tested the code, it's just out of my head.
Your code looks quite confusing to me, here is just a simpler version of your code:
flag = 0
count = 0
direction = 0
while direction != ("quit"):
direction = input("> ")
count += 1
if recognised and count == 1: # word is recognised
flag = 1
print "whatever you want..."
elif (not recognised) and count == 2 and flag == 1:
flag = 0
print "sorry, im afraid i cant do that"
else:
flag = 1
print "second is recognised or whatever you want..."
In my code, I've set a flag if first guess is recognised and incremented the count also. On second guess, I'm just checking the flag and count's value.
Not very relative with your code but, When you could instead get the user input, split it so it turns into a list and compare the first word then the second so it could be something like
user = user_input("> ")
user = user.split()
if user[0] == "look"
if user[1] == "left"
do something
if user[1] == "right"
do something
else
print ("sorry, im afraid i cant do that")
Not sure if this is what your looking for though
Simply, I think you need to learn more code to make things a lot easier for yourself here, though maybe classes are a bit much, and I don't mean this in an insulting way.
As a simple start, I'd suggest using the in keyword rather than ==.
For example:
if "north" in direction:
do something
This will "do something" if the input is North, NORTH, go North, go north please and so on.
To solve your issue therefore your code could use something like this:
input = ("> ")
if "go" in input and not ("north" in input and "south" in input...):
print "That is not a direction you can go in."
And so on. The "and not (...)" section can be rewritten much neater but I wrote it as-is to show what is happening easier.
truthcase = None
directions = ["north", "south", ...]
for i in directions:
if i not in input:
continue
else:
truthcase = True
truthcase = False
if "go" in input and not truthcase:
print something
Hopefully this helps.