Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grab user input asynchronously and pass to an Event loop in python

I am building a single player MUD, which is basically a text-based combat game. It is not networked.

I don't understand how to gather user commands and pass them into my event loop asynchronously. The player needs to be able to enter commands at any time as game events are firing. So pausing the process by using raw_input won't work. I think I need to do something like select.select and use threads.

In the example below, I have a mockup function of userInputListener() which is where I like to receive commands, and append them to the command Que if there is input.

If have an event loop such as:

from threading import Timer
import time

#Main game loop, runs and outputs continuously
def gameLoop(tickrate):

    #Asynchronously get some user input and add it to a command que 
    commandQue.append(userInputListener())
    curCommand = commandQue(0)
    commandQue.pop(0)

    #Evaluate input of current command with regular expressions
    if re.match('move *', curCommand):
        movePlayer(curCommand)
    elif re.match('attack *', curCommand):
        attackMonster(curCommand)
    elif re.match('quit', curCommand):
        runGame.stop()
    #... etc    

    #Run various game functions...
    doStuff()

    #All Done with loop, sleep
    time.sleep(tickrate)

#Thread that runs the game loop
runGame = Timer(0.1, gameLoop(1))
runGame.start()

How do I get my user input in there?

Or more simply, can anyone show me any example of storing user input while another loop is running at the same time? I can figure out the rest if we can get that far.

like image 966
msystems Avatar asked Jun 08 '12 00:06

msystems


1 Answers

You will indeed need two threads. One to be concerned with the main game loop and one to handle user input. The two would be communicating through a Queue.

You can have your main process start the game loop thread and then have it obtaining a line of text from the user and "puting" it to the queue (i.e following runGame.start()). This can be as simple as:

while not gameFinished:
    myQueue.put(raw_input()). 

The game loop thread will simply be "geting" a line of text from the queue, interpert and execute it.

Python has a thread-safe queue implementation which you can use (including a very basic example for multi-threaded usage that you can use as a guide).

There's also a simple command line interperter module (the cmd module and here for a good practical overview) which might also be useful for this kind of project.

like image 56
A_A Avatar answered Oct 04 '22 09:10

A_A