Subversion Repositories programming

Rev

Rev 423 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#!/usr/bin/env python

__author__    = "Ira W. Snyder (devel@irasnyder.com)"
__copyright__ = "Copyright (c) 2006, Ira W. Snyder (devel@irasnyder.com)"
__license__   = "GNU GPL v2 (or, at your option, any later version)"

from PyCompat import *
from Actions import *
from Menu import Menu
import sys
import copy

(WALK, PUSH, CLIMB, GRAB) = ('Walk', 'Push', 'Climb', 'Grab')

def findNextMove (State):
        """Prioritized Search for the best next move"""

        monkeyPosition = Action(State).findMonkeyPosition ()
        boxPosition = Action(State).findBoxPosition ()

        # Try to Grab
        if Grab(State).meetsPreconditions():
                return (GRAB,)

        # Try to push box to middle
        if Push(State, boxPosition, Push.MIDDLE).meetsPreconditions():
                if boxPosition != Push.MIDDLE:
                        return (PUSH, boxPosition, Push.MIDDLE)

        # Try to walk to box
        if Walk(State, monkeyPosition, boxPosition).meetsPreconditions():
                if monkeyPosition != boxPosition:
                        return (WALK, monkeyPosition, boxPosition)

        # Try to climb the box
        if Climb(State, Climb.UP).meetsPreconditions():
                if not Action(State).monkeyOnBox ():
                        return (CLIMB, Climb.UP)

        # Try to climb down from the box
        if Climb(State, Climb.DOWN).meetsPreconditions():
                if Action(State).monkeyOnBox ():
                        return (CLIMB, Climb.DOWN)

def isValidInitialState (State):
        monkeyPos = Action(State).findMonkeyPosition()
        boxPos = Action(State).findBoxPosition()
        onBox = Action(State).monkeyOnBox()

        if onBox and (monkeyPos != boxPos):
                return False

        return True

def enter_initial_state ():
        State = set([])

        # Get Monkey Position
        m = Menu(autorun=True, name='Enter Monkey Position')
        m.add_entry ('1', 'Window', lambda: Walk.WINDOW)
        m.add_entry ('2', 'Door', lambda: Walk.DOOR)
        m.add_entry ('3', 'Middle', lambda: Walk.MIDDLE)
        m.add_entry ('Q', 'Quit', sys.exit)

        pos = m.run_menu()[1]
        State.add ('At(Monkey,%s)' % pos)

        # Get Box Position
        m = Menu(autorun=True, name='Enter Box Position')
        m.add_entry ('1', 'Window', lambda: Push.WINDOW)
        m.add_entry ('2', 'Door', lambda: Push.DOOR)
        m.add_entry ('3', 'Middle', lambda: Push.MIDDLE)
        m.add_entry ('Q', 'Quit', sys.exit)

        pos = m.run_menu()[1]
        State.add ('At(Box,%s)' % pos)

        # Get Monkey Status
        m = Menu(autorun=True, name='Enter Monkey Height Status')
        m.add_entry ('1', 'Monkey on Box', lambda: 'OnBox()')
        m.add_entry ('2', 'Monkey on Floor', lambda: 'OnFloor()')
        m.add_entry ('Q', 'Quit', sys.exit)

        State.add (m.run_menu()[1])

        # Get Banana Status
        m = Menu(autorun=True, name='Enter Banana Status')
        m.add_entry ('1', 'Monkey has Banana', lambda: 'HasBanana()')
        m.add_entry ('2', 'Monkey does not have Banana', lambda: 'NoBanana()')
        m.add_entry ('Q', 'Quit', sys.exit)

        State.add (m.run_menu()[1])

        return State

def find_plan (State):
        if not isValidInitialState (State):
                print 'Bad initial state\n'
                return

        if Action(State).isGoal():
                print 'Initial State is already a goal state\n'
                return

        print 'Plan:'
        while not Action(State).isGoal():

                next = findNextMove (State)
                action = next[0]

                if action == WALK:
                        print '%s from %s to %s' % next
                        State = Walk(State, next[1], next[2]).takeAction()
                elif action == PUSH:
                        print '%s Box from %s to %s' % next
                        State = Push(State, next[1], next[2]).takeAction()
                elif action == CLIMB:
                        print '%s %s' % next
                        State = Climb(State, next[1]).takeAction()
                elif action == GRAB:
                        print '%s Banana' % next
                        State = Grab(State).takeAction()
                else:
                        print 'BAD STATE'
                        return

        print


def main ():

        # Create the main menu
        m = Menu (name='Main Menu')
        m.add_entry ('1', 'Enter Initial State', enter_initial_state)
        m.add_entry ('2', 'Find Plan', find_plan)
        m.add_entry ('Q', 'Quit', sys.exit)
        m.hide_entry ('2')

        # Run the menu
        while True:
                (num, func) = m.run_menu ()

                if num == '1':
                        State = func()
                        m.unhide_entry ('2')
                elif num == '2':
                        func(copy.deepcopy(State))
                else:
                        func()

if __name__ == '__main__':
        main ()

# vim: set ts=4 sts=4 sw=4: