I have a Mesa model which represents the Prisoners dilemma. I want the agents to make a decision about their own move based on the moves of their neighbors in the previous step.
But I can't figure out how to access the moves of the neighbors in the previous step. I tried something with self.model.schedule.time, but I can't figure out how to use that properly. This is the code for the agent model i have right now:
class PDAgent(Agent):
def __init__(self, pos, model, starting_move=None):
"""
Create a new Prisoner's Dilemma agent.
pos: (x, y) tuple of the agent's position.
model: model
move: C(cooperating) or D(defecting)
score: score of the agent
"""
super().__init__(pos, model)
self.pos = pos
self.score = 0
if starting_move:
self.move = starting_move
else:
self.move = self.random.choice(["C", "D"])
self.memory = []
def step(self):
"""Get the best neighbor's move, and change own move accordingly
if better than own score."""
neighbors = self.model.grid.get_neighbors(self.pos, True, include_center=True)
best_neighbors = []
if self.model.schedule.time == 0:
self.memory.append(self.move)
self.score += self.increment_score()
return
if self.model.schedule.time >= 1:
for neighbor in neighbors:
if neighbor.memory[self.model.schedule.time-1] == "C":
best_neighbors.append(neighbor)
if not best_neighbors:
self.move = self.move
best_neighbor = max(best_neighbors, key=lambda a: a.score)
if best_neighbor.score == self.score: # if not higher than own score, stick to agents' own move
self.move = self.move
else:
self.move = best_neighbor.move
def increment_score(self):
neighbors = self.model.grid.get_neighbors(self.pos, True)
moves = [neighbor.move for neighbor in neighbors]
return sum(self.model.payoff[(self.move, move)] for move in moves) # payoff is defined in the Model class
The error that occurs is: "max() arg is an empty sequence". I believe this means, that the best_neighbors list is empty, which tells me that no neighbors are being added to the list. I want all the cooperating neighbors (so not the defecting ones) to be put into a list, so the agent can base his own move on only the cooperating neighbors and ignore the defecting neighbors.
I am not completely sure what the Mesa model is, I can figure out that the
best_neighborslist would be empty if at time 0, the move is notC.Basically, the problem is in this
ifcondition:If the move appended to
self.memoryatself.model.schedule.timeis not"C", then thebest_neighborslist will be empty.You should handle this corner case as well - what gets appended if the first move is not
C.