def initAgent(self): # initialise agent - may throw BadAgentException try: dirname_agent = os.path.dirname(self.cfg.get("AGENT_FILE")) basename_agent = os.path.basename(self.cfg.get("AGENT_FILE")) if not dirname_agent: # if no directory is specified, assume ../maps/ dirname_agent = 'agents/' else: dirname_agent = dirname_agent + '/' agentfile = dirname_agent + basename_agent logging.info("Agent to be used: {}".format(agentfile)) self.loadAgent(agentfile) except: raise p4.BadAgentException()
def stepGenerator(self, current, target): """ Generator referenced by self.gen Passes mapref, currentpos, goal, timeremaining to Agent Retrieves and yields next step on search path. Note: gen maintains state for supplied coordinates but updates pathCost, pathSteps, pathTime and timeremaining. p4 uses this same generator for command line and GUI search. :param current: Current position. :type current: (int, int) :param target: Target position. :type target: (int,int) :rtype : (int,int) """ while True: target = self.cfg["GOAL"] if self.gotscript: if self.pathsteps in self.tc: terrain, topleft, botright = self.tc.get(self.pathsteps) pointlist = p4.getBlock(topleft, botright) # change logical map self.lmap.setPoints(terrain, pointlist) # change in gui, if running try: self.gui.clearPoints(pointlist) except: pass if self.pathsteps in self.gc: target = self.lmap.nearestPassable( self.gc.get(self.pathsteps)) self.setGoal(target) if self.pathsteps in self.ac: newpos = p4.addVectors(current, self.ac.get(self.pathsteps)) current = self.lmap.nearestPassable(newpos) yield newpos # scripted move is not costed or counted try: clockstart = timer() # start timer nextreturn = self.agent.getNext(self.lmap, current, target, self.timeremaining) logging.debug(nextreturn) clockend = timer() except: raise p4.BadAgentException() # Only time first step unless operating in 'realtime' mode. If this is realtime, and the step involved no reasoning (took less than FREE_TIME) do not count its time if ((not self.cfg.get("REALTIME") and self.pathtime) or ((clockend - clockstart) < self.cfg.get("FREE_TIME"))): steptime = 0 else: steptime = (clockend - clockstart) previous = current # Agent may have returned single step or step plus sets of coords and colors. # Try/except distinguishes between them try: x = nextreturn[1][0] # fails if nextreturn is coord only current, configsets = nextreturn except TypeError: current = nextreturn finally: self.pathsteps += 1 self.pathtime += steptime self.timeremaining -= steptime # We now consider every door open. In fact, we are just computing the final path cost, we are not # searching for it. So is reasonable to assume that I have all the keys along the path. allkeys = [k for k in self.lmap.key_and_doors.keys()] cost = self.lmap.getCost(current, previous, allkeys) # self.pathcost += self.lmap.getCost(current, previous, allkeys) if not self.lmap.isAdjacent(current, previous): cost = float('inf') # agent has made illegal move: if cost == float('inf'): self.updateStatus( "Illegal move at " + str(current) + ":" + str(self.lmap.getCost(current)), False) if self.cfg["STRICT"]: current = previous nextreturn = previous self.pathsteps -= 1 cost = 0 self.pathcost += cost yield nextreturn