Text adventure in Python issue - python

I am working on a text adventure in Python. I'm very new to the concept of object oriented programming (and programming in general), so I'm not entirely sure what went wrong. Well, what I've done so far is made two methods; one that handles what the user types in, and one that dictates what will happen in the game, using other methods defining rooms that I will create in the future. One problem I have, though, is that I can't test the program by running it! When I run it, there is no prompt for user input - the program just ends without returning any error. There's not much code so maybe you could help me in determining the problem! I'm sure there's something really obvious in there I've forgotten...
class Main(object):
def handle_events(self, userinput, cmd):
self.userinput = userinput
self.cmd = cmd
userinput = raw_input('> ')
cmd = {'use' : use,'quit' : quit, 'help' : help}
if userinput[0] not in cmd:
print "Invalid command. Check [help] for assistance."
def main(self, handle_events):
print '''You are in a dark room filled with
strange and ominous objects.
After some feeling around, you think
you can make out a light switch.'''
self.userinput
if userinput[1] == 'switch':
print "You flicked the switch!"
Main().main

You are not calling your method. Main().main is just a reference to the method. To call it you need another set of parentheses: Main().main().

Related

Passing variables between functions in Python, then back to menu

Slowly progressing with my learning with Python and would love a little hand with some code I've tried to create.
I previously had this program running with Global Variables to get a proof of concept to learn about passing variables between functions. Fully worked fine. However, rather than running the function and returning to the menu, it will just stop where I return the value and not progress back to the main menu I created. It is at the point of "return AirportDetailsGlobal".
I'm sure its a simple one, and as said - still learning!
Really appreciate any help on this!
Full code is on pastebin for further reference - pastebin 89VqfwFV
print("\nEnter airport code for overseas")
osCode = input()
airports = airData
for line in airports:
if osCode in line:
print (osCode, "Found\n\n")
print("Airport Name:",line[1])
OverseaCodeGlobal = osCode
x = int(line[2])
AirDataGlobal = x #changed here
return AirportDetailsGlobal
break
else:
print('Incorrect Choice')
menu()
menu()
If you do a return then your code goes back to where it was called from. If it wasn't called from anywhere (ie. you just ran that script directly) then calling return is in most ways equivalent to calling sys.exit(), ie. the program terminates. It'll never hit your break, leave the loop, or hit your call to menu().
Also, your indentation as given there isn't right, the else is at the same level as the for, not the if. I don't think that's the problem but you might hit it next. ;-)

How do I run a function from an input before the code for the function has been read?

I am writing a game, similar to mastermind, and I want a choice bewteen an easy or hard version. I'm not sure how to do this as I need the question before the actual game starts but then there's an error because the function is being called to run before it has been assigned.
def difficulty():
difficulty = input("would you like to the easy or hard version?")
if difficulty == ("easy"):
easy()
elif difficulty == ("hard"):
hard()
difficulty()
This is the start then after is the function with the harder game code then the easier game code. I am trying to run the easy if they request easy and vice versa but the easy () and hard() don't run the code as it isn't assigned yet. I think this is because python reads the code from top to bottom and stops when it finds an error but not sure.
I have never used this before so I apologise if things are unclear or I have done some things wrong.
I am also relatively new to python.
If anybody could help me I would greatly apprectiate it.
Python is quite smart when it comes to identifying functions inside a module. For instance you could do this:
def x():
y()
def y():
print("Y")
x()
and it would execute correctly.
You are right about the execution of a code block that happens from top to bottom, as well as the definitions of those functions will also be constructed top to button, but executed afterwards.
I see some issues in your code.
you do difficulty = input("would you like to the easy or hard version?") but at the same time you have a function called def difficulty. There is a conflict there, try to rename that variable.
you don't need to do ("easy"), it's overkill, you can compare directly to "easy".

Python - Code ignores `if`-statement?

I just got into Python (Jython) coding a few hours ago and I'm trying to automate Kik messenger (using an Android emulator) using Sikuli IDE.
I am trying to make a region observer that scans for changes, if a change is made, it will check if any commands are found. I am not really sure what I'm doing, but this is the code I got with some help all around the web and documentations:
cmdScanLoc = Region(Region(65,762,167,59))
def cmdHelp():
type("Help")
type(Key.ENTER)
cmdScanLoc.stopObserver()
def cmdPing():
type("Pong.")
type(Key.ENTER)
cmdScanLoc.stopObserver()
def changeDetected(event):
print("Change")
if cmdScanLoc.exists("1440090739688.png"):
cmdHelp()
elif cmdScanLoc.exists("1440090725124.png"):
cmdPing()
else:
print("No Command Found")
def startObserver():
cmdScanLoc.onChange(50,changeDetected)
cmdScanLoc.observe(10,background=False)
Settings.ObserveScanRate = 10
startObserver()
Here is the log, after typing !ping:
Change
!help
[log] TYPE "Help"
[log] TYPE "#ENTER."
It seems to go to cmdHelp(), even though I typed !ping. How is that possible? It just completely ignores the if-statement.
And here is an image of the region I'm scanning:
http://i.imgur.com/QAP9OnV.png
And an image of the images I'm scanning for:
http://i.imgur.com/wXxphQN.png (code in this image is no longer accurate as you can see)
I would greatly appreciate it if someone could guide me in the right direction with this "command scanner" where if a certain command is detected, the appropiate function is called.
Thanks a lot in advance and sorry if this is a really nooby question, I've just been trying for hours and hours, looking up documentation of Sikuli and Python and I just can't get it to work...
It's much smarter and much faster to do this kind of thing with the region observer than with an if-statement. Example code:
def cmd1(event):
print("Command One")
event.cmdRegion.stopObserver()
waitCmdAppear()
def cmd2(event):
print("Command Two")
event.cmdRegion.stopObserver()
waitCmdAppear()
def cmd3(event):
print("Command Three")
event.cmdRegion.stopObserver()
waitCmdAppear()
def waitCmdAppear():
cmdRegion.onAppear(Pattern("1.png").exact(), cmd1)
cmdRegion.onAppear(Pattern("2.png").exact(), cmd2)
cmdRegion.onAppear(Pattern("3.png").exact(), cmd3)
cmdRegion.observe(FOREVER)
waitCmdAppear()
Things to not forget:
The (event) part when defining a function that's going to be called by the region observer.
Stopping the Observer in the event, even if you are going to need it again. Just restart it.
In the onAppear, (region.onAppear([PS], [handler])) type the handler (ex. cmd3) not the function (ex. cmd3())
I hope this will help other people. :)

Python text adventure - how to create HINT and SAVE in every prompt

So, finally I'm getting to the end of LPTHW, and I'm creating my own text adventure type of game.
I want to incorporate a save function to the game (probably by using file write). Also, the game can give you hints based on your location in the game. What I basically need is following:
There will be lots of prompts for user input (raw_input) in while loops. I want to be able to type SAVE or HINT any time to trigger a function. How do I do this so I don't have to create the same conditional every time? (for example elif action == "HINT": print "...")
Is there a way to create some global expressions so that every time they're typed in the prompt, I can act on them? I will create a module with a dictionary that will reference a certain hint when the player is present in a certain location. I just want to avoid putting the same conditionals all over the place.
If you separate the input into a function, you can pass a hint and access save easily:
def user_input(prompt, hint):
while True:
ui = raw_input(prompt)
if ui.lower() == "hint":
print hint
elif ui.lower() == "save":
save()
else:
return ui
You could also add checking here that the user stays within specific choices (an additional argument), deal with any errors and only ever return valid input.
you should probably use a dictionary
def do_save(*args,**kwargs):
print "SAVE!"
def do_hint(*args,**kwargs):
print "HINT!"
def do_quit(*args,**kwargs):
print "OK EXIT!"
global_actions = {'SAVE':do_save,
'HINT':do_hint,
'QUIT':do_quit}
def go_north(*args,**kwargs):
print "You Go North"
def go_east(*args,**kwargs):
print "you go east"
def make_choice(prompt="ENTER COMMAND:",actions={},context_info={}):
choice = raw_input(prompt)
fn = actions.get(choice.upper(),lambda *a,**kw:sys.stdout.write("UNKOWN CHOICE!"))
return fn(some_context=context_info)
local_actions = {"NORTH":go_north,"EAST":go_east}
player_actions = dict(global_actions.items() + local_actions.items())
print "From Here You Can Go [North] or [East]"
result = make_choice(actions=player_actions,
context_info={"location":"narnia","player_level":5})
I don't know about the save feature but for hint you could just have;
If raw_input == hint:
print "whatever you want here"
Or if you need the hint to be different depending on your position you could have a variable for what the hint for that room is and have it update each time you enter a new room then have:
if raw_input == "hint":
print hintvariable
If this doesn't work then sorry, I'm new.

validating correct answer with loops in python

Sorry for the non descriptive question I had no idea how to word it.
I'm trying to write a program (GUI) where I ask the users questions and then in return they answer and see if they are correct however when I enter the correct answer it's still showing as being incorrect.
My code looks something like this.
prompt for question 1
txtQuestion = Text(Point(5,8), "Question 1")
txtQuestion.setTextColor("red")
txtQuestion.setSize(16)
txtQuestion.setStyle("bold")
txtQuestion.draw(win)
txtAnswer = Text(Point(1.5,4), "Answer 1: ")
txtAnswer.setTextColor(color_rgb(255,127,80))
txtAnswer.setSize(14)
txtAnswer.setStyle("bold")
txtAnswer.draw(win)
txtAnswer2 = Text(Point(1.5,3), "Answer 2: ")
txtAnswer2.setTextColor(color_rgb(255,127,80))
txtAnswer2.setSize(14)
txtAnswer2.setStyle("bold")
txtAnswer2.draw(win)
txtAnswer3 = Text(Point(1.5,2), "Answer 3: ")
txtAnswer3.setTextColor(color_rgb(255,127,80))
txtAnswer3.setSize(14)
txtAnswer3.setStyle("bold")
txtAnswer3.draw(win)
txtAnswer4 = Text(Point(1.5,1), "Answer 4: ")
txtAnswer4.setTextColor(color_rgb(255,127,80))
txtAnswer4.setSize(14)
txtAnswer4.setStyle("bold")
txtAnswer4.draw(win)
txtEnterAn = Text(Point(8,3), "Enter your answer below: ")
txtEnterAn.setTextColor("black")
txtEnterAn.draw(win)
entAnswer = Entry(Point(8,2), 3)
entAnswer.draw(win)
Answer1 = entAnswer.getText()
win.getMouse()
#loop for answer
if Answer1 == "A":
txtCorrect = Text(Point(5,9), "Correct!")
txtCorrect.setTextColor("black")
txtCorrect.draw(win)
else:
txtCorrect = Text(Point(5,9), "Inorrect!")
txtCorrect.setTextColor("black")
txtCorrect.draw(win)
Now I'm not sure why every time I enter "A" it still shows as incorrect I know in another program I had to float the entAnswer variable but I figured this time I wouldn't have to since it's a string.
I must be overlooking the situation but I can't lay my finger down on it, any help would be appreciated, thanks!
p.s. I didn't put it in with the code but I do have the variables up top initialized such as Answer1 = " " and so forth
The problem here seems to be that you're misunderstanding how GUIs work. It's not like the sequential print/read code that most programming instruction starts with. The GUI widgets only create themselves, draw to the screen and wait for events.
This line:
Answer1 = entAnswer.getText()
will end up setting Answer1 to an empty string, because at that point, the user hasn't entered anything in the text box. Instead, you have to create a callback function that will be called by the GUI when the user hits a button to score the answer. Then in that function you will be able to read the user's answer and mark it correct or incorrect.
I recommend going through your GUI library's tutorial again to get a feel for the event-driven style of GUI programming.
I'd recommend that you abstract that user interface detail away from the problem of showing questions, obtaining answers, and determining correctness. You can sort all of that out with nothing more than a command line, text based user interface. Once you have that, then you can proceed with the user interface design with confidence, knowing that the logic behind the questionnaire is sound.
This idea goes by several names: layering, MVC, etc. I'd recommend it for this problem, because it'll help you learn the idea for those more difficult problems to come where it'll be indispensable.
i don't see a reason the logic would fail, but are you sure you are pressing "A" and not "a" .
I can't say anything about this particular problem, but I would do a
print "'" + answer + "'"
print answer.__class__
I have encountered wrapper classes (in OTHER situations) which behave like strings
but are not actually strings. Furthermore spaces and newlines can be added everywhere :)

Categories