UserPreferences

FSMGeneratorProgram


  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
 79 
 80 
 81 
 82 
 83 
 84 
 85 

"""
An advance FSM Brain architecture for allowing a true GOSUB which
saves the state of the State, and returns to continue where it left
off. Takes advantage of the new "yield" command in Python.

All states are generators. Control is handled by using "yield". Yield
passes back:

"continue" - let others have a turn, and continue
"goto"     - continue processing in another state
"gosub"    - go do another state as a function
"quit"     - system will stop

TODO: allow system to be in multiple states simultaneously.
"""

import random, time

def process(control, level=0):
    """ This function processes the states. """
    command = "goto"
    state = None
    arg = None
    while command not in ["return", "quit"]:
        print "at level", level
        for stepResults in control: # this is where the call is
            if type(stepResults) == type(""):
                command, state, arg = stepResults, None, None
            else:
                command, state, arg = stepResults
            # -----------------------------
            if command == "goto" or command == "quit":
                break
            elif command == "gosub":
                command = process(state(*arg), level+1) # recursive
                if command == "quit":
                    break
            elif command == "return":
                break
            time.sleep(.001)
        print "Ending level", level
        if command == "goto":
            control = state(*arg)
    return command

def State1(*args):
    """ Sample state """
    print "Computing in State1"
    for i in range(100):
        yield "continue"
    print
    r = random.random()
    if r < .33:
        print "   pre-goto..."
        yield "goto", State2, (11,)
        print "   ERROR post-goto..." # never gets here
    elif r < .66:
        print "   pre-gosub..."
        yield "gosub", State2, (12,)
        print "   post-gosub..."
    print "end loop..."
    yield "return" # only do this when done, otherwise will loop

def State2(*args):
    print "Computing in State2"
    for i in range(100):
        yield "continue"
    print
    r = random.random()
    if r < .33:
        print "   pre-goto..."
        yield "goto", State1, (11,)
        print "   ERROR post-goto..." # never gets here
    elif r < .66:
        print "   pre-gosub..."
        yield "gosub", State1, (12,)
        print "   post-gosub..."
    print "end loop..."
    yield "return" # only do this when done, otherwise will loop

# Get the process running:
retval = None
while retval != "quit":
    retval = process(State1())