Which class should store the lookup table?

The world contains agents in different places with a single agent anywhere. Each agent knows where he is, but I also need to quickly check if there is an agent in a specific place. Consequently, I also save the map from locations to agents. I have a problem deciding where this map belongs : class World, class Agent(as a class attribute) or elsewhere.

The following table of the lookup table agent_locationsplaces the table class World. But now agents have to call world.update_agent_locationevery time they move. This is very annoying; what if I later decide to track other things about agents besides their locations, will I need to add callbacks to the world object throughout the tag Agent?

class World:
  def __init__(self, n_agents):
    # ...
    self.agents = []
    self.agent_locations = {}
    for id in range(n_agents):
      x, y = self.find_location()
      agent = Agent(self,x,y)
      self.agents.append(agent)
      self.agent_locations[x,y] = agent
  def update_agent_location(self, agent, x, y):
    del self.agent_locations[agent.x, agent.y]
    self.agent_locations[x, y] = agent
  def update(self): # next step in the simulation
    for agent in self.agents:
      agent.update() # next step for this agent
  # ...

class Agent:
  def __init__(self, world, x, y):
    self.world = world
    self.x, self.y = x, y
  def move(self, x1, y1):
    self.world.update_agent_location(self, x1, y1)
    self.x, self.y = x1, y1
  def update():
    # find a good location that is not occupied and move there
    for x, y in self.valid_locations():
      if not self.location_is_good(x, y):
        continue
      if self.world.agent_locations[x, y]: # location occupied
        continue
      self.move(x, y)

agent_locations class Agent . , World. World, .

, ...

EDIT: , , agent_locations. , Agent, , .

+5
3

a a. A World Agents Locations. A Location Agent. Agent Location a World.

class Agent:
    def __init__(self, world):
        self.location = None
        self.world = world

    def move(self, new_location):
        if self.location is not None:
            self.location.agent = None
        new_location.agent = self
        self.location = new_location

    def update(self):
        for new_location in self.world.locations:
            if self.location_is_good(new_location):
                self.move(new_location)

    def location_is_good(self, location):
        if location.agent is not None:
            return False

class Location:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.agent = None

Location, , , . , Agent, , , move(). , World move(). Agent Location.

+1

, , , , , , " " ( ).

, agent_locations World.

. , World , . World , , ( ), . , self.location_is_good self.world.is_location_available(x, y) [1]

, . , World , , . , ? -. , - (x, y) . "" .

: ([(agent.x, agent.y) for agent in self.agents] [2]). agent_locations dict , World.

World... , , Agent. update_agent_location(self, agent, x, y) , x == agent.x; y == agent.y ( , ). World, update_agent_state(self, agent), World . ( eveytime).

class World(object):
  # ...
  def update_agent_state(self, agent, state_change=None):
    # Update properties based on what changed, or
    # drop state_change param and update everything everytime
    if state_change == Agent.LOCATION_CHANGE:
      self.agent_locations[agent.x, agent.y] = agent
    elif state_change == Agent.WHATEVER:
      pass

class Agent(object):
  LOCATION_CHANGE = 1

  def update(self):
    for x, y in self.valid_locations():
      if not self.can_move_to(x, y)
        continue

      self.move(x, y)

  def can_move_to(self, x, y):
    """Determines if x, y is a location where we can move."""
    if not self.world.is_location_available(x, y):
      return False
    if not self.has_money_to_travel_to(x, y):
      return False

    return True

  def move(self, x, y):
    """Moves to x, y and notifies world of state change."""
    self.x = x
    self.y = y

    self.world.update_agent_state(self, Agent.LOCATION_CHANGE)

- ( ).

[1] , , "" , . . (x, y), 1) , 2) 1000 $ , Agent.can_move_to(x, y), .

[2] , self.agents = {} , append dict. ([])?

+2

, . " , , , " "". , 0 1 . , Location .

locn = self.where_to_move()
if locn.agent is None:
    self.move(locn)
elif locn.agent is self:
    raise ConfusedAgentError()
else:
    self.execute_plan_B()
0

All Articles