Skip to content

Commit

Permalink
added real-time pathfinding and agent mobility
Browse files Browse the repository at this point in the history
  • Loading branch information
bitcraft committed Jun 29, 2012
1 parent 46db4d7 commit a0effc5
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 21 deletions.
27 changes: 21 additions & 6 deletions npc/pirate/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,37 @@ def get_actions(self, caller, bb):
return a list of action that this caller is able to move with
"""

if not SimpleGoal(is_tired=True).test(bb):
pos = caller.environment.can_move_from(caller, dist=30)
return [ self.build_action(caller, p) for p in pos ]
else:
if SimpleGoal(is_tired=True).test(bb):
return []
else:
pos = caller.environment.can_move_from(caller, dist=100)
return [ self.build_action(caller, p) for p in pos ]


def build_action(self, caller, pos):
a = move_action(caller)
a.setEndpoint(pos[1])
a.effects.append(PositionGoal(target=caller, position=pos))
a.effects.append(SimpleGoal(is_tired=True))
return a



class move_action(CallableAction):
pass
def update(self, time):
super(move_action, self).update(time)
if self.caller.position[1] == self.endpoint:
self.finish()
else:
env = self.caller.environment
path = env.pathfind(self.caller.position[1], self.endpoint)
path.pop() # this will always the the starting position
env.move(self.caller, (env, path.pop()))

def setStartpoint(self, pos):
self.startpoint = pos

def setEndpoint(self, pos):
self.endpoint = pos

exported_actions.append(move)

Expand Down
20 changes: 14 additions & 6 deletions pygoap/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from actionstates import *


DEBUG = 0

NullAction = InstancedAction()


Expand Down Expand Up @@ -95,7 +97,7 @@ def handle_precept(self, pct):
# our filters may have caused us to ignore the precept
if pct == None: return None

print "[agent] {} recv'd pct {}".format(self, pct)
if DEBUG: print "[agent] {} recv'd pct {}".format(self, pct)

# this line has been added for debugging purposes
self.plan = []
Expand All @@ -115,7 +117,7 @@ def replan(self):
s = [ g for g in s if g[0] > 0 ]
s.sort(reverse=True)

print "[agent] goals {}".format(s)
if DEBUG: print "[agent] goals {}".format(s)

# starting for the most relevant goal, attempt to make a plan
for score, goal in s:
Expand All @@ -126,13 +128,15 @@ def replan(self):
self.bb,
goal)

if ok:
if ok and DEBUG:
print "[agent] {} has planned to {}".format(self, goal)
pretty = list(reversed(plan[:]))
print "[agent] {} has plan {}".format(self, pretty)
return plan
else:
elif DEBUG:
print "[agent] {} cannot {}".format(self, goal)
elif ok:
return plan

return []

Expand All @@ -143,7 +147,8 @@ def current_action(self):
return NullAction

def running_actions(self):
return self.current_action()
action = self.current_action()
return action

def next_action(self):
"""
Expand All @@ -157,7 +162,10 @@ def next_action(self):

# this action is done, so return the next one
if current_action.state == ACTIONSTATE_FINISHED:
return self.plan.pop()
if self.plan:
return self.plan.pop()
else:
return None

# this action failed somehow
elif current_action.state == ACTIONSTATE_FAILED:
Expand Down
11 changes: 6 additions & 5 deletions pygoap/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from itertools import chain, repeat, product, izip


DEBUG = 0

class ObjectBase(object):
"""
Expand Down Expand Up @@ -111,7 +112,7 @@ def add_thing(self, thing, position=None):
thing.position = position or self.default_position(thing)
self.things.append(thing)

print "[env] adding {}".format(thing)
if DEBUG: print "[env] adding {}".format(thing)

# add the agent
if isinstance(thing, GoapAgent):
Expand Down Expand Up @@ -144,13 +145,13 @@ def update(self, time_passed):
p = Precept(sense="time", time=self.time)
[ a.handle_precept(p) for a in self.agents ]

# get all the running actions for the agents
self.action_que = [ a.running_actions() for a in self.agents ]

# update all the actions that may be running
precepts = [ a.update(time_passed) for a in self.action_que ]
precepts = [ p for p in precepts if not p == None ]

# get all the running actions for the agents
self.action_que = chain([ a.running_actions() for a in self.agents ])


# start any actions that are not started
[ action.start() for action in self.action_que
if action.state == ACTIONSTATE_NOT_STARTED ]
Expand Down
11 changes: 11 additions & 0 deletions pygoap/environment2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from pygoap.agent import GoapAgent
from environment import Environment, Precept
from pathfinding.astar import search, Node
import random, math


Expand Down Expand Up @@ -46,6 +47,9 @@ def get_surrounding(self, position):
def calc_h(self, position1, position2):
return distance(position1, position2)

def factory(self, position):
return Node(position)


class XYEnvironment(Environment, Pathfinding2D):
"""
Expand Down Expand Up @@ -135,3 +139,10 @@ def can_move_from(self, agent, dist=100):
pos.append((self, (xx, yy)))

return pos

def pathfind(self, start, finish):
"""
return a path from start to finish
"""

return search(start, finish, self.factory)
7 changes: 6 additions & 1 deletion pygoap/planning.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from blackboard import Blackboard
from heapq import heappop, heappush, heappushpop
from actionstates import *
import sys


Expand Down Expand Up @@ -159,13 +160,17 @@ class InstancedAction(object):
builder = None

def __init__(self):
self.state = None
self.state = ACTIONSTATE_FINISHED

def update(self, time):
pass

def touch(self, bb):
if DEBUG: print "[debug] action {} has no touch method".format(self)

def test(self, bb):
if DEBUG: print "[debug] action {} has no test method".format(self)
return 1.0

def __repr__(self):
return self.__class__.__name__
Expand Down
2 changes: 1 addition & 1 deletion pygoap/tiledenvironment.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def render(self, surface):
for l in xrange(0, len(self.tiledmap.layers)):
for y in xrange(0, self.tiledmap.height):
for x in xrange(0, self.tiledmap.width):
tile = self.tiledmap.get_tile_image(x, y, l)
tile = self.tiledmap.getTileImage(x, y, l)
xx = x * self.tiledmap.tilewidth
yy = y * self.tiledmap.tileheight
if not tile == 0:
Expand Down
4 changes: 2 additions & 2 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def run_once():
formosa.add_thing(rum)

elif time == 5:
formosa.move(rum, pirate.position)
#formosa.move(rum, pirate.position)
pass

elif time == 6:
Expand Down Expand Up @@ -134,7 +134,7 @@ def run_once():
stdout.write("\n\n");
time += 1

if time == 8: run = False
if time == 32: run = False


if __name__ == "__main__":
Expand Down

0 comments on commit a0effc5

Please sign in to comment.