I just started learning Python a couple days ago, and my main goal for now is a text-based game, in which the user inputs commands to interact with the virtual world. My problem thus far, however, has been splitting a string up so that I can detect what action the player wants to take, and what the target of that action is. (for example, in my source code below, the user first types an action, punch or kick, then its target, Bob or Alice) In one of the Basic Python tutorials on python.about.com, it mentioned string indexing, where you can call one character out of a string by treating it like a list. The code from the tutorial:

cat = 'dog' 
print cat[0] 
print cat[1] 
print cat[2] 


So I utilized this technique to detect the actions and targets within the command strings from the user. But my main question is: is this the best way of doing it? If you look in my source code, you'll see that it relies on literal values to look for the words in the string. It fails if there is any whitespace in the string, and while this really is the only problem I can forsee (no player should expect to get away with adding more characters in the command, I think), it still irks me to have to rely on those literal values.

Therefore I ask you: is there a better way of doing this, without relying on those hard-coded values?

(sorry I'm so verbose)

# text_adventure_si.py
# testing a method of detecting text commands
#                with string indexing methods

print "Bob and Alice stand in front of you."
print "You can either punch or kick them."
print "Type help for command help and quit to exit."

action = ""

while action.lower() != "quit":
    act_in = raw_input("> ")
    action = act_in.lower()
    if action[0:6] == "punch ":
        if action[6:9] == "bob":
            print "You punch Bob."
        elif action[6:11] == "alice":
            print "You punch Alice."
            print "You did something wrong."
    elif action[0:5] == "kick ":
        if action[5:8] == "bob":
            print "You kick Bob."
        elif action[5:10] == "alice":
            print "You kick Alice."
            print "You did something wrong."
    elif action == "help":
        print "Type 'punch' and either Bob or Alice to punch them."
        print "You can do the same thing with 'kick'"
        print "Type 'quit' to exit the game."
    elif action == "quit":
        print "Farewell."
        print "You did something wrong."

If you were to split the users input into a list you can use list indexing to call out each word individually. Here's an example:

>>> act_in = "punch Alice in the face"
>>> act_in_parts = act_in.split()
>>> action = act_in_parts[0]
>>> target = act_in_parts[1]
>>> action
>>> target

Thanks! But I have another question: is it possible to search the resulting list, in case there are extra words in between "punch" and "alice"? It would be especially useful if you could detect if "alice" is further back in the sentence than "punch".

You can use in to figure out if a list (or string for that matter) contains a particular element:

>>> act_in = "I would love to take alice and punch her in the mouth"
>>> action = act_in.lower().split()
>>> if 'alice' in action:
...     print('This action will be performed on Alice')
... elif 'bob' in action:
...     print('This action will be performed on Bob')
This action will be performed on Alice
>>> if 'punch' in action:
...     print('The target is getting punched')
... elif 'kick' in action:
...     print('The target is getting kicked')
The target is getting punched

I believe that in simply makes use of the list method index (or analogously string.find ), which returns the index of the element you're looking for, and -1 if it does not exist in the list (string). So in would be the true/false version of using list.index (or string.find ).

So in the above code, splitting the string into a list is unnecessary if you're not using indexing to access individual words. Leave the action as a string and you can just ask if the word you're looking for is in the string.

>>> act_in = 'Sometimes, I like to kick people in the teeth.  One of the people that I frequently kick is named Bob.  That Bob is such an idiot.'
>>> action = act_in.lower()
>>> 'bob' in action
>>> 'alice' in action
>>> 'punch' in action
>>> 'kick' in action

Wow, thanks! It looks like in is the best option. I'll be sure to switch over to it.

This question has already been answered. Start a new discussion instead.