Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Monday, September 12, 2016

Coding timed functions into text based game using Python

Coding timed functions into text based game using Python


I am writing a simple text based adventure game in Python. I would like to have certain processes occur periodically regardless of what the user does, approximately every 2 minutes. For instance: Have NPC's move around the rooms, have people get hungry and thirsty, have people heal, and during combat, have the battle proceed. Right now, I'm using 'raw_input' to get commands from the user, but this essentially pauses the code. How can I make the game proceed even if the user just sits there and doesn't type anything?

Answer by pydsigner for Coding timed functions into text based game using Python


The answer is -- don't write real time for a console! If you want to do this text-based, you may wish to switch to Tkinter. This will allow you to do these things separately -- and also display text during these periodic events, and use a simple .after() call to execute them.

Answer by Brian Cain for Coding timed functions into text based game using Python


  1. Sample the time after each input (up to you whether to do it only for successful commands or optionally include invalid ones).

  2. Compare this time to the prior sample and divide by some world tick interval.

  3. Iterate through the list of activities that happen per tick (for npc in npcs: npc.move_to_adjacent_posn(), e.g.).

Answer by Alden for Coding timed functions into text based game using Python


I think typically in this situation you wouldn't have a background process or thread doing calculations. Instead, when the user types in some response do a time delta and based off the elapsed time between inputs calculate how much a player would have healed and what the battle events would have been etc.. That is if you don't want console updates while game is waiting for the user to respond.

Edit: or try something like this:

import time  import sys    win32 = True  try:      from msvcrt import kbhit, getch      print "[+] Running on windows, using msvcrt."  except ImportError:      print "[+] Not running on windows, attempting unix-like."      win32 = False        import termios, fcntl, sys, os      import select      fd = sys.stdin.fileno()        oldterm = termios.tcgetattr(fd)      newattr = termios.tcgetattr(fd)      newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO      termios.tcsetattr(fd, termios.TCSANOW, newattr)        oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)      fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)      POLLTIME = 5  done = False  command = ""  while not done:        sys.stdout.write("\r")      print("Something happened (polling)%s" % (" " * command.__len__() ))      sys.stdout.write("Enter command: %s" % command)      sys.stdout.flush()        t = time.time()      if win32:          while time.time() - t < POLLTIME:              if kbhit():                  c = getch()                  if ord(c) < 127 and ord(c) > 31:                      command += c                      message = "\rEnter command: " + command                      sys.stdout.write("\r%s" % message)                  if "\r" == c:                      if "quit\r" == command:                          done = True                          break                      sys.stdout.write("\rThe command was: %s\n" % command)                      command = ""                      sys.stdout.write("\rEnter command: %s \b" %command)                  elif "\b" == c:                      command = command[:-1]                      sys.stdout.write("\rEnter command: %s \b" %command)                  sys.stdout.flush()      else:          while time.time() - t < POLLTIME:              try:                  c = '\0'                                  if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:                      c = sys.stdin.readline(1)                      if ord(c) < 127 and ord(c) > 31:                          command += c                          message = "\rEnter command: " + command                          sys.stdout.write("\r%s" % message)                  if c == "\n":                      if "quit" == command:                          done = True                          break                      print("\rThe command was: %s" % command)                      command = ""                      message = "\rEnter command: " + command                      sys.stdout.write("\r%s" % message)                  if 127 == ord(c):                      command = command[:-1]                      sys.stdout.write("\rEnter command: %s \b" % command)                  sys.stdout.flush()                except IOError:                      pass  

Answer by Eser Aygn for Coding timed functions into text based game using Python


There are ways to read user input without pausing the code. It's called "asynchronous I/O" or "non-blocking I/O". One way to do it is to create a separate thread to listen to the user's requests and queue them to process inside your game loop.

This question and its answers explain how to do non-blocking I/O in Python: Non-blocking read on a subprocess.PIPE in python

Answer by John for Coding timed functions into text based game using Python


I am not sure how you can do this without using a separate thread (and it is easy to use a separate thread).

But my point here will be: look like your text-based function is a event/command based application? i.e. the client state won't change if there is no further command/event from the user? Not sure what you are trying to monitor with a timed function, but if your application is not already event-based, i.e. aggregate the state from the set of event the user perform/send, then you might want to make your application to be event-based, then you can get rid of the timed function. hope that help.


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.