user2232076
user2232076

Reputation: 23

text based game in python

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.

Upvotes: 1

Views: 3711

Answers (4)

Vyktor
Vyktor

Reputation: 20997

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.

Upvotes: 2

Pythonidae
Pythonidae

Reputation: 106

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.

Upvotes: 0

user735977
user735977

Reputation:

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

Upvotes: 0

A human being
A human being

Reputation: 1220

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.

Upvotes: 0

Related Questions