def handle_sim_start(self, simulation): self._set_belief("id", simulation.get("id")) self._set_belief("map", simulation.get("map")) self._set_belief("seedCapital", int(simulation.get("seedCapital"))) self._set_belief("steps", int(simulation.get("steps"))) self._set_belief("team", simulation.get("team")) role = simulation.find("role") self._set_belief( "role", pyson.Literal(role.get("name").lower()), int(role.get("speed")), int(role.get("load")), int(role.get("battery")), tuple(tool.get("name") for tool in role.findall("./tool"))) # Update item beliefs. item_beliefs = [] for item in simulation.findall("./item"): tools = tuple(tool.get("name") for tool in item.findall("./tool")) parts = tuple( pyson.Literal("parts", (part.get("name"), int(part.get("amount")))) for part in item.findall("./item")) item_beliefs.append( pyson.Literal( "item", (item.get("name"), int(item.get("volume")), tools, parts), PERCEPT_TAG)) self._replace_beliefs(("item", 4), item_beliefs)
def _broadcast(agent, term, intention): # Illocutionary force. ilf = pyson.grounded(term.args[0], intention.scope) if not pyson.is_atom(ilf): return if ilf.functor == "tell": goal_type = pyson.GoalType.belief elif ilf.functor == "achieve": goal_type = pyson.GoalType.achievement else: raise pyson.PysonError("unknown illocutionary force: %s" % ilf) # Prepare message. message = pyson.freeze(term.args[1], intention.scope, {}) tagged_message = message.with_annotation( pyson.Literal("source", (pyson.Literal(agent.name), ))) # Broadcast. for receiver in agent.env.agents.values(): if receiver == agent: continue receiver.call(pyson.Trigger.addition, goal_type, tagged_message, pyson.runtime.Intention()) yield
def execute(): print "execute" # Here we are adding the "execute" literal to the belief base of the agents term = pyson.Literal("execute", (1, 1)) intention = pyson.runtime.Intention() deliveryAgent1.call(pyson.Trigger.addition, pyson.GoalType.belief, term, intention) env.run() term = pyson.Literal("execute", (5, 6)) intention = pyson.runtime.Intention() deliveryAgent2.call(pyson.Trigger.addition, pyson.GoalType.belief, term, intention) env.run()
def _send(agent, recipient, ils, term): group = ils.literal_group() if group == ("tell", 0): frozen = pyson.grounded(term, {}).with_annotation(pyson.Literal("source", (agent.name, ))) agent.emit(recipient, functools.partial(pyson.runtime.add_belief, frozen)) elif group == ("achieve", 0): frozen = term.with_annotation(pyson.Literal("source", (agent.name, ))) agent.emit(recipient, functools.partial(pyson.runtime.call, pyson.Trigger.addition, pyson.GoalType.achievement, frozen)) else: raise pyson.PysonError("unsupported illocutionary force: %s/%d" % (group[0], group[1])) return True
def bridgeStatus(self, term, intention): node1 = pyson.grounded(term.args[0], intention.scope) node2 = pyson.grounded(term.args[1], intention.scope) result = G.get_edge_data(node1, node2)["bridge"]["open"] if pyson.unify(term.args[2], pyson.Literal("open", (result, )), intention.scope, intention.stack): yield
def check_for_garbage(agent, term, intention): (x, y) = locations[agent] for (gx, gy) in garbage: if garbage[(gx, gy)] > 0 and abs(x - gx) <= 1 and abs(y - gy) <= 1: l = pyson.Literal("garbage", (gx, gy)) pyson.runtime.add_belief(l, agent, intention) yield
def test_request_action(self): agent = pyson.mapc2017.Agent() with open(os.path.join(os.path.dirname(__file__), "request-action.xml")) as xml: agent.message_received(etree.parse(xml).getroot()) term = pyson.Literal("money", (50000, )) intention = pyson.runtime.Intention() self.assertTrue(agent.test_belief(term, intention)) term = pyson.Literal("shop", ("shop1", 48.8217, 2.33207, 4, pyson.Var())) intention = pyson.runtime.Intention() self.assertTrue(agent.test_belief(term, intention)) agent.dump()
def connection_lost(self, exc): LOGGER.warning("socket connection lost (reason: %s)", exc) self.call(pyson.Trigger.removal, pyson.GoalType.belief, pyson.Literal("connected", (self.name, )), pyson.runtime.Intention()) self.env.run()
def test_unifies_annotated(self): X = pyson.Var() Y = pyson.Var() foo_a = pyson.Literal("foo", (), ("a", )) foo_ab = pyson.Literal("foo", (), ("a", "b")) foo_XY = pyson.Literal("foo", (), (X, Y)) foo_XX = pyson.Literal("foo", (), (X, X)) self.assertTrue(pyson.unifies_annotated(foo_a, foo_ab)) self.assertTrue(pyson.unifies_annotated(foo_a, foo_XY)) self.assertTrue(pyson.unifies_annotated(foo_a, foo_XX)) self.assertTrue(pyson.unifies_annotated(foo_ab, foo_XY)) self.assertTrue(pyson.unifies_annotated(foo_XY, foo_ab)) self.assertTrue(pyson.unifies_annotated(foo_XX, foo_ab)) self.assertTrue(pyson.unifies_annotated(foo_XX, foo_ab)) self.assertFalse(pyson.unifies_annotated(foo_ab, foo_XX)) self.assertFalse(pyson.unifies_annotated(foo_XY, foo_a))
def pickup(agent, term, intention): if locations[agent] in garbage and garbage[ locations[agent]] > 0 and holding[agent] < 2: holding[agent] += 1 garbage[locations[agent]] -= 1 (x, y) = locations[agent] l = pyson.Literal("garbage", (x, y)) pyson.runtime.remove_belief(l, agent, intention) yield
def test_concat_lists(self): env = pyson.runtime.Environment() agent = pyson.runtime.Agent(env, "agent") intention = pyson.runtime.Intention() X = pyson.Var() term = pyson.Literal(".concat", ((1, 2), (3, ), X)) next(pyson.stdlib._concat(agent, term, intention)) self.assertEqual(X.grounded(intention.scope), (1, 2, 3))
def test_concat_strings(self): env = pyson.runtime.Environment() agent = pyson.runtime.Agent(env, "agent") intention = pyson.runtime.Intention() X = pyson.Var() term = pyson.Literal(".concat", ("hello", " ", "world", X)) next(pyson.stdlib._concat(agent, term, intention)) self.assertEqual(X.grounded(intention.scope), "hello world")
def _send(agent, term, intention): # Find the receivers: By a string, atom or list of strings or atoms. receivers = pyson.grounded(term.args[0], intention.scope) if not pyson.is_list(receivers): receivers = [receivers] receiving_agents = [] for receiver in receivers: if pyson.is_atom(receiver): receiving_agents.append(agent.env.agents[receiver.functor]) else: receiving_agents.append(agent.env.agents[receiver]) # Illocutionary force. ilf = pyson.grounded(term.args[1], intention.scope) if not pyson.is_atom(ilf): return if ilf.functor == "tell": goal_type = pyson.GoalType.belief trigger = pyson.Trigger.addition elif ilf.functor == "untell": goal_type = pyson.GoalType.belief trigger = pyson.Trigger.removal elif ilf.functor == "achieve": goal_type = pyson.GoalType.achievement trigger = pyson.Trigger.addition else: raise pyson.PysonError("unknown illocutionary force: %s" % ilf) # TODO: unachieve, askOne, askAll, tellHow, untellHow, askHow # Prepare message. message = pyson.freeze(term.args[2], intention.scope, {}) tagged_message = message.with_annotation( pyson.Literal("source", (pyson.Literal(agent.name), ))) # Broadcast. for receiver in receiving_agents: receiver.call(trigger, goal_type, tagged_message, pyson.runtime.Intention()) yield
def do_some_work(): for developer in developers: if developer.active: if isinstance(developer, pyson.runtime.Agent): developer.call(pyson.Trigger.addition, pyson.GoalType.achievement, pyson.Literal("tick"), pyson.runtime.Intention()) env.run_agent(developer) else: developer.do_some_work()
def callback(data): posX = data.pose.pose.position.x posY = data.pose.pose.position.y Point = collections.namedtuple('Position', ['x', 'y']) position = Point(posX, posY) #print position # Here we are adding the "execute" literal to the belief base of the agents term = pyson.Literal("execute", (position.x, position.y)) intention = pyson.runtime.Intention() deliveryAgent1.call(pyson.Trigger.addition, pyson.GoalType.belief, term, intention) env.run() time.sleep(3)
def _set_belief(self, name, *args): term = pyson.Literal(name, tuple(args), PERCEPT_TAG) found = False for belief in list(self.beliefs[term.literal_group()]): if pyson.unifies(term, belief): found = True else: self.call(pyson.Trigger.removal, pyson.GoalType.belief, belief, pyson.runtime.Intention()) if not found: self.call(pyson.Trigger.addition, pyson.GoalType.belief, term, pyson.runtime.Intention())
def nextSteps(self, term, intention): position = pyson.grounded(term.args[0], intention.scope) destination = pyson.grounded(term.args[1], intention.scope) results = [] resetWeights() for edge in G.edges(position): road = G[edge[0]][edge[1]] road["w"] = 1000 for neighbor in G.neighbors(position): path_length = nx.shortest_path_length(G, neighbor, destination, "w") + G.get_edge_data( position, neighbor)["length"] results.append(pyson.Literal("road", (neighbor, path_length))) results.sort(key=lambda x: x.args[1]) if pyson.unify(term.args[2], tuple(results), intention.scope, intention.stack): yield
def createAgents(G, number): with open(os.path.join(os.path.dirname(__file__), "car.asl")) as source: agents = env.build_agents(source, number, actions) nodes = list(G.nodes()) positions = simConf["agents"]["positions"] if simConf.get( "agents") else nodes destinations = simConf["agents"]["destinations"] if simConf.get( "agents") else nodes for agent in agents: beliefs = [pyson.Literal("name", (agent.name, ))] state = { "node": random.choice(positions), "road": None, "roadProgress": 0, "destination": random.choice(destinations), "traffic": {} } state["path"] = [state["node"]] agentStates[agent.name] = state # generate traits/preferences: beliefs.append( pyson.Literal("minRoadQuality", (random.randint(0, 3), ))) if random.random() < 0.5: beliefs.append(pyson.Literal("waitForBridges")) # add general beliefs beliefs.append( pyson.Literal("destination", (state["destination"], ))) for node in G.nodes(): beliefs.append(pyson.Literal("node", (node, ))) for node1, node2, data in G.edges(data=True): beliefs.append( pyson.Literal( "edge", (node1, node2, data["length"], data["quality"]))) # beliefs.append(pyson.Literal("edge", (node2, node1, data["length"], data["quality"]))) for (n1, n2, data) in G.edges(data=True): if data["bridge"]: beliefs.append(pyson.Literal("bridge", (n1, n2))) # beliefs.append(pyson.Literal("bridge", (n2, n1))) for belief in beliefs: addBelief(agent, belief)
def test_unifies(self): self.assertFalse(pyson.unifies(True, 1)) self.assertTrue(pyson.unifies(3, 3.0)) self.assertTrue(pyson.unifies(True, True)) self.assertTrue(pyson.unifies(5, pyson.Wildcard())) self.assertTrue(pyson.unifies((1, 2), (1, pyson.Wildcard()))) self.assertTrue(pyson.unifies(("hello", 2), ("hello", pyson.Var()))) self.assertTrue(pyson.unifies(pyson.Var(), pyson.Literal("beep"))) self.assertTrue(pyson.unifies(pyson.Literal("boop"), pyson.Var())) X = pyson.Var() self.assertTrue( pyson.unifies(pyson.Literal("foo", (X, X)), pyson.Literal("foo", (1, 1)))) self.assertFalse( pyson.unifies(pyson.Literal("bar", (X, X)), pyson.Literal("bar", (1, 2))))
with open(os.path.join(os.path.dirname(__file__), "rescue_point.asl")) as source: rescuePoint2 = env.build_agent(source, pyson.stdlib.actions, name="rescuePoint2") with open(os.path.join(os.path.dirname(__file__), "rescue_point.asl")) as source: rescuePoint3 = env.build_agent(source, pyson.stdlib.actions, name="rescuePoint3") with open(os.path.join(os.path.dirname(__file__), "rescue_point.asl")) as source: rescuePoint4 = env.build_agent(source, pyson.stdlib.actions, name="rescuePoint4") # Here are examples to provide the initial positions to the building agents # To provide the initial position to the agents, we need to instantiate a new intention. intention = pyson.runtime.Intention() # After we need to instantiate a new literal called "pose". In this example, the agent will receive a new literal called "pose(5,6)" term = pyson.Literal("pose", (5, 6)) # # Here we will add the "pose" belief to the agent belief base. pyson.runtime.add_belief(term, collectPoint1, intention) term = pyson.Literal("pose", (7, 8)) pyson.runtime.add_belief(term, collectPoint2, intention) term = pyson.Literal("pose", (10, 11)) pyson.runtime.add_belief(term, rescuePoint1, intention) term = pyson.Literal("pose", (12, 13)) pyson.runtime.add_belief(term, rescuePoint2, intention) term = pyson.Literal("pose", (14, 15)) pyson.runtime.add_belief(term, rescuePoint3, intention)
for i in range(0, int(grid_size**2 / 10)): garbage[(random.randint(1, grid_size - 1), random.randint(1, grid_size - 1))] += 1 holding = {} incin = None with open(os.path.join(os.path.dirname(__file__), "fourcleaners.asl")) as source: agent = env.build_agents(source, num_agents, actions) for i in range(len(agent)): locations[agent[i]] = (random.randint(1, grid_size), random.randint(1, grid_size)) holding[agent[i]] = 0 l = pyson.Literal("holding", (0, )) pyson.runtime.add_belief(l, agent[i], pyson.runtime.Intention()) (x, y) = locations[agent[i]] l = pyson.Literal("at", (x, y)) pyson.runtime.add_belief(l, agent[i], pyson.runtime.Intention()) l = pyson.Literal("visited", (x, y)) pyson.runtime.add_belief(l, agent[i], pyson.runtime.Intention()) l = pyson.Literal("num_moves", (0, )) pyson.runtime.add_belief(l, agent[i], pyson.runtime.Intention()) (b, t, s) = (grid_size + 1, laliste[i], laliste[i + 1]) l = pyson.Literal("bornes", (b, t, s)) pyson.runtime.add_belief(l, agent[i], pyson.runtime.Intention()) with open(os.path.join(os.path.dirname(__file__), "incinerator.asl")) as source: incin = env.build_agent(source, actions)
def handle_request_action(self, message): req = message[0] if self.action_id is not None: LOGGER.warning("%s: action id %d was not used", self.name, self.action_id) self.action_id = int(req.get("id")) self_data = req.find("self") self._set_belief("charge", int(self_data.get("charge"))) self._set_belief("load", int(self_data.get("load"))) self._set_belief("lat", float(self_data.get("lat"))) self._set_belief("lon", float(self_data.get("lon"))) self._set_belief("routeLength", int(self_data.get("routeLength", 0))) route = [] for wp in self_data.findall("./route"): route.append( pyson.Literal("wp", (int(wp.get("i")), float( wp.get("lat")), float(wp.get("lon")), PERCEPT_TAG))) self._set_belief("route", tuple(route)) self._set_belief("money", int(req.find("team").get("money"))) action = self_data.find("action") if action is not None: self._set_belief("lastAction", pyson.Literal(action.get("type"))) self._set_belief("lastActionResult", pyson.Literal(action.get("result"))) # TODO: Action parameters else: self._replace_beliefs(("lastAction", 1), []) self._replace_beliefs(("lastActionResult", 1), []) # Update carried items. carried_items = [] for item in self_data.findall("./items"): carried_items.append( pyson.Literal("item", (item.get("name"), int(item.get("amount"))), PERCEPT_TAG)) self._replace_beliefs(("item", 2), carried_items) # Update entities. entities = [] for entity in req.findall("entity"): entities.append( pyson.Literal( "entity", (pyson.Literal(entity.get("name")), entity.get("team"), float(entity.get("lat")), float(entity.get("lon")), pyson.Literal(entity.get("role").lower())), PERCEPT_TAG)) self._replace_beliefs(("entity", 5), entities) # Update charging station pecepts charging_stations = [] for station in req.findall("chargingStation"): charging_stations.append( pyson.Literal( "chargingStation", (station.get("name"), float(station.get("lat")), float(station.get("lon")), int(station.get("rate"))), PERCEPT_TAG)) self._replace_beliefs(("chargingStation", 4), charging_stations) # Update dumps. dumps = [] for dump in req.findall("dump"): dumps.append( pyson.Literal("dump", (dump.get("name"), float( dump.get("lat")), float(dump.get("lon"))), PERCEPT_TAG)) self._replace_beliefs(("dump", 4), dumps) # Update shops. shops = [] for shop in req.findall("shop"): shop_items = [] for item in shop.findall("item"): shop_items.append( pyson.Literal("item", (item.get("name"), int(item.get("price")), int(item.get("amount"))))) shops.append( pyson.Literal("shop", (shop.get("name"), float(shop.get("lat")), float(shop.get("lon")), int( shop.get("restock")), tuple(shop_items)), PERCEPT_TAG)) self._replace_beliefs(("shop", 5), shops) # Update storage percepts. storages = [] for storage in req.findall("storage"): storage_items = [] for item in storage.findall("item"): storage_items.append( pyson.Literal("item", (item.get("name"), int(item.get("stored")), int(item.get("delivered"))))) storages.append( pyson.Literal( "storage", (storage.get("name"), float( storage.get("lat")), float(storage.get("lon")), int(storage.get("totalCapacity")), int(storage.get("usedCapacity")), tuple(storage_items)), PERCEPT_TAG)) self._replace_beliefs(("storage", 6), storages) # Update workshops. workshops = [] for workshop in req.findall("workshop"): workshops.append( pyson.Literal( "workshop", (workshop.get("name"), float(workshop.get("lat")), float(workshop.get("lon"))), PERCEPT_TAG)) self._replace_beliefs(("workshop", 3), workshops) # Update resource nodes. resource_nodes = [] for node in req.findall("resourceNode"): resource_nodes.append( pyson.Literal("resourceNode", (node.get("name"), float(node.get("lat")), float(node.get("lon")), node.get("resource")), PERCEPT_TAG)) self._replace_beliefs(("resourceNode", 4), resource_nodes) # Update job percepts. jobs = [] auctions = [] missions = [] posteds = [] for job in req.findall("job"): required = tuple( pyson.Literal("required", (item.get("name"), int(item.get("amount")))) for item in job.findall("required")) jobs.append( pyson.Literal( "job", (job.get("id"), job.get("storage"), int(job.get("reward")), int(job.get("start")), int(job.get("end")), required), PERCEPT_TAG)) for auction in req.findall("auction"): required = tuple( pyson.Literal("required", (item.get("name"), int(item.get("amount")))) for item in auction.findall("required")) reward = int(auction.get("reward")) auctions.append( pyson.Literal( "auction", (auction.get("id"), auction.get("storage"), reward, int(auction.get("start")), int( auction.get("end")), int(auction.get("fine")), int(auction.get("lowestBid", str(reward + 1))), int(auction.get("auctionTime")), required), PERCEPT_TAG)) for mission in req.findall("mission"): required = tuple( pyson.Literal("required", (item.get("name"), int(item.get("amount")))) for item in mission.findall("required")) missions.append( pyson.Literal( "mission", (mission.get("id"), mission.get("storage"), int(mission.get("reward")), int(mission.get("start")), int(mission.get("end")), int(mission.get("fine")), int(mission.get("lowestBid")), 0, required), PERCEPT_TAG)) for posted in req.findall("posted"): required = tuple( pyson.Literal("required", (item.get("name"), int(item.get("amount")))) for item in posted.findall("required")) posteds.append( pyson.Literal( "job", (posted.get("id"), posted.get("storage"), int(posted.get("reward")), int(posted.get("start")), int(posted.get("end")), required), PERCEPT_TAG)) self._replace_beliefs(("job", 5), jobs) self._replace_beliefs(("auction", 9), auctions) self._replace_beliefs(("mission", 9), missions) self._replace_beliefs(("posted", 5), posteds) # Update step. self._set_belief("timestamp", int(message.get("timestamp"))) self._set_belief("deadline", int(req.get("deadline"))) self.simulation_step = int(req.find("simulation").get("step")) self._set_belief("step", self.simulation_step)
import logging from lxml import etree from heapq import heapify, heappop import pyson import pyson.runtime import pyson.ext_stdlib LOGGER = pyson.get_logger(__name__) actions = pyson.Actions(pyson.ext_stdlib.actions) PERCEPT_TAG = frozenset( [pyson.Literal("source", (pyson.Literal("percept"), ))]) class Environment(pyson.runtime.Environment): def time(self): return asyncio.get_event_loop().time() def run(self): super(Environment, self).run() self.dispatch_wait_until() def dispatch_wait_until(self): earliest = None for agent in self.agents.values(): for intention_stack in agent.intentions: wait = intention_stack[-1].wait_until
def as_term(self): return pyson.Literal( "issue", (pyson.Literal(self.type), self.patch, self.priority), ())
pyson.stdlib.actions, name="rescuePoint3") with open(os.path.join(os.path.dirname(__file__), "rescue_point.asl")) as source: rescuePoint4 = env.build_agent(source, pyson.stdlib.actions, name="rescuePoint4") # Here are examples to provide the initial positions to the building agents # To provide the initial position to the agents, we need to instantiate a new intention. intention = pyson.runtime.Intention() # After we need to instantiate a new literal called "pose". In this example, the agent will receive a new literal called "pose(5,6)" term = pyson.Literal("pose", (5, 6)) # # Here we will add the "pose" belief to the agent belief base. pyson.runtime.add_belief(term, collectPoint1, intention) term = pyson.Literal("pose", (7, 8)) pyson.runtime.add_belief(term, collectPoint2, intention) term = pyson.Literal("pose", (10, 11)) pyson.runtime.add_belief(term, rescuePoint1, intention) term = pyson.Literal("pose", (12, 13)) pyson.runtime.add_belief(term, rescuePoint2, intention) term = pyson.Literal("pose", (14, 15)) pyson.runtime.add_belief(term, rescuePoint3, intention)
# agent = env.build_agents(source,1,actions) # locations[agent[0]]=(random.randint(1,10),random.randint(1,10)) # holding[agent[0]]=0 # (x,y)=locations[agent[0]] # l=pyson.Literal("at",(x,y)) # pyson.runtime.add_belief(l,agent[0],pyson.runtime.Intention()) # # with open(os.path.join(os.path.dirname(__file__),"sweep.asl")) as source: # agent = env.build_agents(source,1,actions) # locations[agent[0]]=(random.randint(1,10),random.randint(1,10)) # holding[agent[0]]=0 # (x,y)=locations[agent[0]] # l=pyson.Literal("at",(x,y)) # pyson.runtime.add_belief(l,agent[0],pyson.runtime.Intention()) # with open(os.path.join(os.path.dirname(__file__), "Remover.asl")) as source: agent = env.build_agents(source, 1, actions) locations[agent[0]] = (random.randint(1, 10), random.randint(1, 10)) holding[agent[0]] = 0 (x, y) = locations[agent[0]] l = pyson.Literal("at", (x, y)) pyson.runtime.add_belief(l, agent[0], pyson.runtime.Intention()) with open(os.path.join(os.path.dirname(__file__), "incinerator.asl")) as source: incin = env.build_agent(source, actions) agent.append(incin) if __name__ == "__main__": env.run()
more_work = False for agent in agents: more_work |= agent.step(env) result_file = open("result.csv", "w") plot = "--plot" in sys.argv if plot: plt.ion() fig = plt.figure() plt.axis([0, 5 * 365, 0, 600]) for day in range(5 * 365): term = pyson.Literal("day", (day, )) print(term) for agent in agents: agent.call(pyson.Trigger.addition, pyson.GoalType.achievement, env, term, {}, delayed=True) run() print(len(files)) if plot: import matplotlib.pyplot as plt
def visit_literal(self, ast_literal): return pyson.Literal(ast_literal.functor, (t.accept(self) for t in ast_literal.terms), (t.accept(self) for t in ast_literal.annotations))
trafficData = defaultdict(int) # run simulation for step in range(simConf["steps"]): unfinished = list( filter(lambda x: x["node"] != x["destination"], agentStates.values())) if len(unfinished) == 0: print("SIMULATION FINISHED") break print("SIMULATION AT STEP {}".format(step)) stepSimulation() createAgents(G, simConf["agentsPerStep"]) handlePercepts() for agent in sorted(env.agents.values(), key=lambda ag: ag.name): addBelief(agent, pyson.Literal("beforeStep")) env.run_agent(agent) state = agentStates[agent.name] pos = state["node"] if state["node"] != None else state["road"] addBelief(agent, pyson.Literal("position", (pos, ))) addBelief(agent, pyson.Literal("step")) env.run_agent(agent) # simulation results # print("\nTrace of agent 'car':") # for t in traces["car"]: # print(t) # print(traces) print("\nTraces of other cars ... ") for n in env.agents: