def __init__(self, chronicles): WorldInfo.__init__(self) self.roundNr = -1 self.agents = [] self.anonymized = [] # randomly ordered list of agents self.__anonymizedIndices = {} self.SI = SanctioningInstitution() self.SFI = SanctionFreeInstitution() self.chronicles = chronicles
class World(WorldInfo): """The world object ties the other objects (agents, institutions, game) together and runs the simulation. Variables: agents - list of AgentBase objects: the agents in the game. these can be either humans or different computer strategies anonymized - list of AgentBase objects: the same agents as in the 'agents' list, but in randomly sorted order. The order of the 'anonymized' list is re-shuffled before every new round of the game __anonymizedIndices - dictionary agent->int: a dictionary that tells the index of an agent in the 'anonymized' list SI - SanctioningInstitution object: the sanctioning institution SFI - SanctionFreeInstitution object: the sanctioning free institution chronicles - ChroniclesInterface object: writing of the simulation history and evaluating of the simulation data """ def __init__(self, chronicles): WorldInfo.__init__(self) self.roundNr = -1 self.agents = [] self.anonymized = [] # randomly ordered list of agents self.__anonymizedIndices = {} self.SI = SanctioningInstitution() self.SFI = SanctionFreeInstitution() self.chronicles = chronicles def setup(self, agents, game, maxRounds, contribTokens, sanctionTokens): """Sets the simulation up.""" assert self.roundNr < 0, "Simulation has already started!" assert maxRounds >= 1 assert contribTokens >= 1 assert sanctionTokens >= 1 assert len(agents) >= 2, "need at least two agents!" self.game = game self.agents = agents self.anonymized = agents[:] # shallow copy of agents for agent in self.agents: agent.connect(self) self.SI.connect(self) self.SFI.connect(self) self.numAgents = len(self.agents) self.maxRounds = maxRounds self.roundNr = -1 self.contribTokens = contribTokens self.sanctionTokens = sanctionTokens self.chronicles.setupComplete(self) def run(self): """Runs the simulation.""" assert self.roundNr < 0 , "Simulation is already running, " \ + "already finished or was never set up properly!" self.roundNr = 0 while self.roundNr < self.maxRounds: self.nextRound() def nextRound(self): """Runs one complete round of the simulation and increses the round counter A full round includes all three stages: institution choice, voluntary contribution and stanctioning.""" assert self.roundNr < self.maxRounds random.shuffle(self.anonymized) for i, agent in enumerate(self.anonymized): self.__anonymizedIndices[agent] = i self.anonymizedInfos = tuple(PublicInfo(agent) for agent in self.anonymized) self.statistics = RoundStatistics(self.anonymizedInfos, self.roundNr-1) self.institutionChoiceStage() self.contributionStage() self.sanctioningStage() # notify agents that the round is completed for agent in self.agents: agent.roundComplete() self.chronicles.roundComplete() self.roundNr += 1 def institutionChoiceStage(self): """Performs the institution choice stage: Agents are asked to choose either the sanctioning or the sanction free institution and are added into the respective lists.""" self.SI.members = [] self.SFI.members = [] for agent in self.agents: institution = agent.chooseInstitution() if institution == SI: self.SI.members.append(agent) agent.allegiance = SI elif institution == SFI: self.SFI.members.append(agent) agent.allegiance = SFI else: raise ValueError def contributionStage(self): """Performs the contribution stage: Agents are asked to make a contribution. """ self.SI.contributionStage() self.SFI.contributionStage() def sanctioningStage(self): """Performs the sanctioning stage. """ self.SI.sanctioningStage() self.SFI.sanctioningStage() def anonymizedIndex(self, agent): """Returns the index of the 'agent' in the anonymized list for this round. """ return self.__anonymizedIndices[agent]