世界包含位于不同位置的代理,在任何位置只有一个代理.每个代理都知道他在哪里,但我还需要快速检查给定位置是否有代理.因此,我还保留了从地点到代理商的地图.我在决定一个问题,即该地图属于:class World,class Agent(作为一个阶级属性)或其他地方.
在下面我把查找表agent_locations放在class World.但现在代理商world.update_agent_location每次搬家都要打电话.这很烦人; 如果我稍后决定跟踪代理的其他事情,除了他们的位置之外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)
Run Code Online (Sandbox Code Playgroud)
我可以把agent_locations它class Agent作为一个类属性.但这只有在我有一个World对象时才有效.如果我后来决定实例化多个World对象,则查找表将需要特定于世界.
我相信有更好的解决方案......
编辑:我在代码中添加了几行来说明如何agent_locations使用.请注意,它仅用于内部Agent对象,但我不知道是否会永远保持这种情况.
它有助于 OOP 用is a和has a来谈论对象。AWorld 有一个列表Agents和 一个列表Locations。ALocation 有一个 Agent. AnAgent 有 a 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
Run Code Online (Sandbox Code Playgroud)
通过向 a 添加新属性Location(例如地形)的心理练习,很容易看出这种封装的好处。同样,向 中添加新的东西Agent,例如武器,只需要类似于 的特定于武器的函数move()。请注意,根本World不需要参与其中move()。移动在Agent和 之间严格处理Location。
| 归档时间: |
|
| 查看次数: |
598 次 |
| 最近记录: |