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
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: