Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Branch: master
Fetching contributors…

Cannot retrieve contributors at this time

255 lines (181 sloc) 6.36 KB
Goals in the context of a pyGOAP agent give the planner some direction when
planning. Goals are known to the agent and are constantly monitored and
evaluated. The agent will attempt to choose the most relevant goal for it's
state (determined by the blackboard) and then the planner will determine a
plan for the agent to follw that will (possibly) satisfy the chosen goal.
See the modules and to see how these are used.
The Goal class has a lot of uses in the engine, see the pirate's actions for
an idea of what they are used for. Not all of the goals here are used/tested.
test() should return a float from 0-1 on how successful the action would be
if carried out with the given state of the bb.
touch() should modify a bb in some meaningful way as if the action was
finished successfully.
from planning import GoalBase
from blackboard import Tag
import sys
class SimpleGoal(GoalBase):
Goal that uses a dict to match precepts stored on a bb.
def test(self, bb):
#f = [ k for (k, v) in if v == False]
for tag in
if tag ==
return 1.0
return 0.0
def touch(self, bb):**
def __repr__(self):
return "<{}=\"{}\">".format(self.__class__.__name__,
class EvalGoal(GoalBase):
uses what i think is a somewhat safe way of evaluating python statements.
feel free to contact me if you have a better way
def test(self, bb):
condition = self.args[0]
# this only works for simple expressions
cmpop = (">", "<", ">=", "<=", "==")
i = 0
index = 0
expr = condition.split()
while index == 0:
index = expr.index(cmpop[i])
i += 1
if i > 5: break
side0 = float(eval(" ".join(expr[:index]), bb))
side1 = float(eval(" ".join(expr[index+1:]), bb))
except NameError:
return 0.0
cmpop = cmpop[i]
if (cmpop == ">") or (cmpop == ">="):
if side0 == side1:
return 1.0
elif side0 > side1:
v = side0 / side1
elif side0 < side1:
if side0 == 0:
return 0.0
v = 1 - ((side1 - side0) / side1)
if v > 1: v = 1.0
if v < 0: v = 0.0
return v
def touch(self, bb):
def do_it(expr, d):
exec expr in d
except NameError as detail:
# get name of missing variable
name = detail[0].split()[1].strip('\'')
d[name] = 0
do_it(expr, d)
return d
d = {}
d['__builtins__'] = None
d = do_it(self.args[0], d)
# the bb was modified
return True
class AlwaysValidGoal(GoalBase):
Will always be valid.
def test(self, bb):
return 1.0
def touch(self, bb, tag):
class NeverValidGoal(GoalBase):
Will never be valid.
def test(self, bb):
return 0.0
def touch(self, bb, tag):
class PositionGoal(GoalBase):
This validator is for finding the position of objects.
def test(self, bb):
search memory for last known position of the target if target is not
in agent's memory return 0.0.
do pathfinding and determine if the target is accessable
- if not return 0.0
determine the distance required to travel to the target
return 1.0 if the target is reachable
target = None
target_position = None
tags ="position")
if DEBUG: print "[PositionGoal] testing {}".format(
for tag in tags:
target = tag['obj']
for k, v in
value = getattr(target, k)
except AttributeError:
if not v == value:
target_position = tag['position']
if target_position:
if DEBUG: print "[PositionGoal] {} {}".format(['owner'], target)
return 1.0
d = distance(position, target_position)
if d > self.dist:
return (float(self.dist / d)) * float(self.dist)
elif d <= self.dist:
return 1.0
return 0.0
def touch(self, bb):
# this needs to be the same as what handle_precept() of an agent
# would post if it had recv'd this from the environment
tag = Tag(['target'],['position'])
class HasItemGoal(GoalBase):
returns true if item is in inventory (according to bb)
when creating instance, 'owner' must be passed as a keyword.
its value can be any game object that is capable of holding an object
NOTE: testing can be true to many different objects,
but touching requires a specific object to function
any other keyword will be evaluated against tags in the bb passed.
def __init__(self, owner, target=None, **kwargs):
super(HasItemGoal, self).__init__(self)
self.owner = owner = None
if target: = target
try: = kwargs['target']
except KeyError:
if ( == None) and (kwargs == {}):
raise Exception, "HasItemGoal needs more information"
def test(self, bb):
for tag in"position"):
if (tag['position'][0] == self.owner) and \
tag['obj'] ==
return 1.0
return 0.0
def touch(self, bb):
# this has to be the same tag that the agent would add to its bb
tag = Tag(, position=(self.owner, 0))
if DEBUG: print "[HasItem] {} touch {}".format(self, tag), position=(self.owner, 0)))
Jump to Line
Something went wrong with that request. Please try again.