def test_monopoly(self): agentFactory = GHAgentFactory() encounter = GoldHunterEncounter() goldResource = GoldResource(1000) diggers = agentFactory.copyAgents(agentFactory.buildDiggers(9)) totalDiggingPower = 0 for digger in diggers: totalDiggingPower += digger.getDiggingRate() encounter.monopoly(passiveAgents=diggers, goldResource=goldResource) assert goldResource.getQuantity() == 1000 - totalDiggingPower goldResource = GoldResource(1) for digger in diggers: digger.setGold(0) diggers[0].strength = 10000000 encounter.monopoly(passiveAgents=diggers, goldResource=goldResource) self.assertEqual(1, diggers[0].getGold())
def test_intimidation(self): agentFactory = GHAgentFactory() encounter = GoldHunterEncounter() diggers = agentFactory.copyAgents(agentFactory.buildDiggers(4)) robbers = agentFactory.copyAgents(agentFactory.buildRobbers(4)) totalDiggerStrength = encounter.getTotalStrength(diggers) totalRobberStrength = encounter.getTotalStrength(robbers) oldRobberGold = {} for robber in robbers: robber.addGold(100) oldRobberGold[robber] = robber.getGold() oldDiggerGold = {} for digger in diggers: digger.addGold(100) oldDiggerGold[digger] = digger.getGold() encounter.intimidation(aggressiveAgents=robbers, passiveAgents=diggers) if totalRobberStrength >= 2 * totalDiggerStrength: pass # TODO continue making the test pass
def test_competition(self): agentFactory = GHAgentFactory() encounter = GoldHunterEncounter() goldResource = GoldResource(1000) diggers = agentFactory.copyAgents(agentFactory.buildDiggers(9)) totalDiggingPower = 0 for digger in diggers: totalDiggingPower += digger.getDiggingRate() encounter.competition(passiveAgents=diggers, goldResource=goldResource) assert goldResource.getQuantity() == 1000 - totalDiggingPower goldResource = GoldResource(100) oldGoldValues = {} for digger in diggers: oldGoldValues[digger] = digger.getGold() encounter.competition(passiveAgents=diggers, goldResource=goldResource) for digger in oldGoldValues.keys(): oldGoldValue = oldGoldValues[digger] assert digger.getGold() - oldGoldValue <= digger.getMaxGoldPerTurn( )
def __init__(self, actionsHandler=None, agentFactory=None): if actionsHandler is None: print("Warning: creating the default actionsHandler") # raise Exception("GHAgentFactory needs an actionsHandler.") self.actionsHandler = GHAgentActions() else: self.actionsHandler = actionsHandler if agentFactory is None: print("Warning: creating the default agentFactory") # raise Exception("GHAgentFactory needs an agentFactory.") self.agentFactory = GHAgentFactory() else: self.agentFactory = agentFactory self.passiveEncounters = [ self.collaboration, self.philanthropy, self.competition, self.monopoly, ] self.robbingEncounters = [self.intimidation, self.heist, self.raid] self.aggressiveEncounters = [self.sabotage, self.combat]
def test_getStrongestAgent(self): agentFactory = GHAgentFactory() encounterEngine = GoldHunterEncounter() agents = agentFactory.copyAgents(agentFactory.buildRobbers(9)) agents[0].strength = 1000000 strongestAgent = encounterEngine.getStrongestAgent(agents) actualStrongestAgent = agents[0] assert actualStrongestAgent == strongestAgent
def test_getTotalMaxGoldPerTurn(self): agentFactory = GHAgentFactory() encounter = GoldHunterEncounter() diggers = agentFactory.copyAgents(agentFactory.buildDiggers(9)) actualMaxGold = 0 for digger in diggers: actualMaxGold += digger.getMaxGoldPerTurn() testMaxGold = encounter.getTotalMaxGoldPerTurn(diggers) assert actualMaxGold == testMaxGold
def test_getTotalGoldOwned(self): agentFactory = GHAgentFactory() encounter = GoldHunterEncounter() diggers = agentFactory.copyAgents(agentFactory.buildDiggers(9)) actualTotalGold = 90 for digger in diggers: digger.addGold(10) testTotalGold = encounter.getTotalGoldOwned(diggers) assert actualTotalGold == testTotalGold
def test_getTotalStrength(self): agentFactory = GHAgentFactory() encounter = GoldHunterEncounter() diggers = agentFactory.copyAgents(agentFactory.buildDiggers(9)) actualTotalStrength = 0 for digger in diggers: actualTotalStrength += digger.getStrength() testTotalStrength = encounter.getTotalStrength(diggers) assert actualTotalStrength == testTotalStrength
def test_philanthropy(self): agentFactory = GHAgentFactory() encounter = GoldHunterEncounter() goldResource = GoldResource(1000) diggers = agentFactory.copyAgents(agentFactory.buildDiggers(9)) totalDiggingPower = 0 for digger in diggers: totalDiggingPower += digger.getDiggingRate() encounter.philanthropy(passiveAgents=diggers, goldResource=goldResource) assert goldResource.getQuantity() == 1000 - totalDiggingPower
def test_collaboration(self): agentFactory = GHAgentFactory() encounter = GoldHunterEncounter() goldResource = GoldResource(1000) diggers = agentFactory.copyAgents(agentFactory.buildDiggers(9)) totalDiggingPower = 0 for digger in diggers: totalDiggingPower += digger.getDiggingRate() encounter.collaboration(passiveAgents=diggers, goldResource=goldResource) print(f"current in resource: {goldResource.getQuantity()}") print(f"total lost: {totalDiggingPower}") assert goldResource.getQuantity() == 1000 - totalDiggingPower
def test_priorityDigging(self): agentFactory = GHAgentFactory() encounter = GoldHunterEncounter() goldResource = GoldResource(1000) diggers = agentFactory.copyAgents(agentFactory.buildDiggers(9)) totalDiggingPower = 0 for digger in diggers: totalDiggingPower += digger.getDiggingRate() totalAmountCollected = encounter.priorityDigging(diggers, goldResource) assert goldResource.getQuantity( ) == 1000 - totalDiggingPower or goldResource.getQuantity() == 0 assert totalAmountCollected < totalDiggingPower goldResource = GoldResource(1) diggers = agentFactory.copyAgents(agentFactory.buildDiggers(100)) lastAgent = diggers[len(diggers) - 1] originalLastAgentGold = lastAgent.getGold() encounter.priorityDigging(diggers, goldResource) totalDiggingPower = 0 for digger in diggers: totalDiggingPower += digger.getDiggingRate() assert goldResource.getQuantity() == 0 assert lastAgent.getGold() == originalLastAgentGold
def test_collectiveDigging(self): agentFactory = GHAgentFactory() encounter = GoldHunterEncounter() goldResource = GoldResource(1000) diggers = agentFactory.copyAgents(agentFactory.buildDiggers(9)) totalDiggingPower = 0 for digger in diggers: totalDiggingPower += digger.getDiggingRate() _ = encounter.collectiveDigging(diggers, goldResource) assert goldResource.getQuantity() == 1000 - totalDiggingPower goldResource = GoldResource(1) diggers = agentFactory.copyAgents(agentFactory.buildDiggers(9)) encounter.priorityDigging(diggers, goldResource) totalDiggingPower = 0 for digger in diggers: totalDiggingPower += digger.getDiggingRate() assert goldResource.getQuantity() == 0
def test_simulateMultipleEncounters(self): # TODO continue agentFactory = GHAgentFactory() encounter = GoldHunterEncounter() originalGoldQuantity = 1000 goldResource = GoldResource(originalGoldQuantity) diggers = agentFactory.buildDiggers(5) robbers = agentFactory.buildRobbers(4) # single passive encounter allEncounterResults = encounter.simulateMultipleEncounters( [encounter.collaboration], passiveAgents=diggers, goldResource=goldResource) for encounterResults in allEncounterResults: self.assertIsNotNone(encounterResults.get(goldResource)) for digger in diggers: self.assertIsNotNone(encounterResults.get(digger)) self.assertEqual(originalGoldQuantity, goldResource.getQuantity()) # all passive encounters allEncounterResults = encounter.simulateMultipleEncounters( encounter.passiveEncounters, passiveAgents=diggers, goldResource=goldResource) for encounterResults in allEncounterResults: self.assertIsNotNone(encounterResults.get(goldResource)) for digger in diggers: self.assertIsNotNone(encounterResults.get(digger)) self.assertEqual(originalGoldQuantity, goldResource.getQuantity()) # single robbing encounter allEncounterResults = encounter.simulateMultipleEncounters( [encounter.intimidation], passiveAgents=diggers, aggressiveAgents=robbers) for encounterResults in allEncounterResults: for digger in diggers: self.assertIsNotNone(encounterResults.get(digger)) for robber in robbers: self.assertIsNotNone(encounterResults.get(robber)) # all robbing encounters allEncounterResults = encounter.simulateMultipleEncounters( encounter.robbingEncounters, passiveAgents=diggers, aggressiveAgents=robbers) for encounterResults in allEncounterResults: for digger in diggers: self.assertIsNotNone(encounterResults.get(digger)) for robber in robbers: self.assertIsNotNone(encounterResults.get(robber)) # single aggressive encounter allEncounterResults = encounter.simulateMultipleEncounters( [encounter.combat], aggressiveAgents=robbers) for encounterResults in allEncounterResults: for robber in robbers: self.assertIsNotNone(encounterResults.get(robber)) # all aggressive encounters allEncounterResults = encounter.simulateMultipleEncounters( encounter.aggressiveEncounters, aggressiveAgents=robbers) for encounterResults in allEncounterResults: for robber in robbers: self.assertIsNotNone(encounterResults.get(robber)) pass
def test_init(self): agentFactory = GHAgentFactory(actionsHandler=GHAgentActions()) agent = agentFactory.buildDigger()
def createAgents(self): factory = GHAgentFactory() self.agents = [factory.buildDigger(), factory.buildRobber()] # self.agents = factory.buildDiggers(2) pass
def setUpClass(cls): cls.actionsHandler = GHAgentActions() cls.agentFactory = GHAgentFactory(actionsHandler=cls.actionsHandler) cls.game = GoldHunters(worldSize=(10, 10)) cls.world = GridWorld(size=(10, 10)) pass
class GoldHunterEncounter(Encounter): def __init__(self, actionsHandler=None, agentFactory=None): if actionsHandler is None: print("Warning: creating the default actionsHandler") # raise Exception("GHAgentFactory needs an actionsHandler.") self.actionsHandler = GHAgentActions() else: self.actionsHandler = actionsHandler if agentFactory is None: print("Warning: creating the default agentFactory") # raise Exception("GHAgentFactory needs an agentFactory.") self.agentFactory = GHAgentFactory() else: self.agentFactory = agentFactory self.passiveEncounters = [ self.collaboration, self.philanthropy, self.competition, self.monopoly, ] self.robbingEncounters = [self.intimidation, self.heist, self.raid] self.aggressiveEncounters = [self.sabotage, self.combat] def simulateAllPassiveEncounters(self, agents, goldResource): return self.simulateMultipleEncounters(self.passiveEncounters, passiveAgents=agents, goldResource=goldResource) def simulateAllAggressiveEncounters(self, agents): return self.simulateMultipleEncounters(self.aggressiveEncounters, aggressiveAgents=agents) def simulateAllRobbingEncounters(self, passiveAgents, aggressiveAgents): return self.simulateMultipleEncounters( self.robbingEncounters, passiveAgents=passiveAgents, aggressiveAgents=aggressiveAgents) def simulateMultipleEncounters(self, encounters, goldResource=None, **kwargs): ''' kwargs: passiveAgents, aggressiveAgents, goldResource ''' allChanges = [] for encounter in encounters: allRealAgents = [] allSimulatedAgents = [] kwargsForEncounter = {} goldResourceCopy = None if goldResource != None: goldResourceCopy = copy.deepcopy(goldResource) allRealAgents.append(goldResource) allSimulatedAgents.append(goldResourceCopy) for agentType, agents in kwargs.items(): allRealAgents.extend(agents) simulatedAgents = self.agentFactory.copyAgents(agents) kwargsForEncounter[agentType] = simulatedAgents allSimulatedAgents.extend(simulatedAgents) changes = {} encounter(goldResource=goldResourceCopy, **kwargsForEncounter) for i in range(len(allRealAgents)): realAgent = allRealAgents[i] simulatedAgent = allSimulatedAgents[i] changes[realAgent] = simulatedAgent allChanges.append(changes) return allChanges def getEncounterResults(self, agents, goldResource=None): """ Simulates the event in which these agents meet at a single location. Returns the encounter results as a dictionary with original agents/resources as its keys and changed agents/resources as its value. """ passiveAgents = [] aggressiveAgents = [] for agent in agents: if agent.type == GHAgentType.DIGGER: passiveAgents.append(agent) elif agent.type == GHAgentType.ROBBER: aggressiveAgents.append(agent) allEncounterResults = [] if len(passiveAgents) > 0 and len(aggressiveAgents) > 0: allEncounterResults = self.simulateAllRobbingEncounters( passiveAgents, aggressiveAgents) elif len(passiveAgents) > 0 and goldResource != None: allEncounterResults = self.simulateAllPassiveEncounters( passiveAgents, goldResource) elif len(aggressiveAgents) > 0: allEncounterResults = self.simulateAllAggressiveEncounters( aggressiveAgents) strongestAgent = self.getStrongestAgent(agents) return self.getHighestPayoffEncounter(strongestAgent, allEncounterResults) def predictEncounterPayoff(self, agent, nextAction, gridWorld): '''Predicts the agent's payoff if the agent takes a certain action''' if self.predictPossibleEncounter(agent, nextAction, gridWorld): # currentLocation = agent.getLocation() targetLocation = agent.actionsHandler.locationByAction( agent, nextAction, gridWorld) potentialAgents = self.getPotentialEncounterParticipants( targetLocation, gridWorld) goldResource = self.getGoldResourceAtLocation( targetLocation, gridWorld) encounterResults = self.getEncounterResults( potentialAgents, goldResource) return self.getPayoffFromEncounterResults(agent, encounterResults) return 0 def predictPossibleEncounter(self, agent, nextAction, gridWorld): """Return whether an agent's action could result in an encounter.""" targetLocation = agent.actionsHandler.locationByAction( agent, nextAction, gridWorld) potentialParticipants = self.getPotentialEncounterParticipants( targetLocation, gridWorld) return len(potentialParticipants) > 1 def getPossibleNearbyLocations(self, locationOfEncounter, gridWorld): locations = [] for xd in range(-1, 2): for yd in range(-1, 2): inspectingLocation = self.addTuples(locationOfEncounter, (xd, yd)) if gridWorld.hasLocation(inspectingLocation): locations.append(inspectingLocation) return locations def getPotentialEncounterParticipants(self, locationOfEncounter, gridWorld): """Returns potential agents that could be involved in an encounter at any location.""" potentialAgents = [] possibleNearbyLocations = self.getPossibleNearbyLocations( locationOfEncounter, gridWorld) for inspectingLocation in possibleNearbyLocations: potentialAgents.extend( gridWorld.getAgentsAtLocation(inspectingLocation)) return potentialAgents def getGoldResourceAtLocation(self, location, gridWorld): resourceList = gridWorld.getResourcesAtLocation(location) if len(resourceList) > 0: return resourceList[0] else: return None def getHighestPayoffEncounter(self, decidingAgent, allEncounterResults): bestChanges = {} highestGoldDifference = -1 * math.inf for encounterResults in allEncounterResults: goldDifference = self.getPayoffFromEncounterResults( decidingAgent, encounterResults) if goldDifference > highestGoldDifference: bestChanges = encounterResults highestGoldDifference = goldDifference return bestChanges def getPayoffFromEncounterResults(self, agent, encounterResults): newGold = encounterResults[agent].getGold() return newGold - agent.getGold() # ENCOUNTERS START HERE # def collaboration(self, goldResource, **kwargs): """All agents attempt to dig their max amount and distribute the gold evenly.""" agents = kwargs.get('passiveAgents') totalAmountCollected = self.collectiveDigging(agents, goldResource) goldPerAgent = math.ceil(totalAmountCollected / len(agents)) for agent in agents: agent.addGold(goldPerAgent) pass def philanthropy(self, goldResource, **kwargs): """Agents with less gold dig from the resource first""" agents = kwargs.get('passiveAgents') agents = sorted(agents, reverse=False, key=self.keyToSortByGold) self.priorityDigging(agents, goldResource) def competition(self, goldResource, **kwargs): """Agents gain gold based on their digging rate""" agents = kwargs.get('passiveAgents') totalMaxGold = self.getTotalMaxGoldPerTurn(agents) totalAmountCollected = self.collectiveDigging(agents, goldResource) for agent in agents: agent.addGold( math.ceil(agent.getMaxGoldPerTurn() * totalAmountCollected / totalMaxGold)) pass def monopoly(self, goldResource, **kwargs): """Agents with more strength dig from the resource first""" agents = kwargs.get('passiveAgents') agents = sorted(agents, reverse=True, key=self.keyToSortByStrength) self.priorityDigging(agents, goldResource) def intimidation(self, **kwargs): """Aggressive agents threaten passive agents into giving the gold over.""" passiveAgents = kwargs.get('passiveAgents') aggressiveAgents = kwargs.get('aggressiveAgents') totalAggressiveStrength = self.getTotalStrength(aggressiveAgents) totalPassiveStrength = self.getTotalStrength(passiveAgents) if totalAggressiveStrength >= totalPassiveStrength * 2: totalGoldStolen = 0 for agent in passiveAgents: goldStolen = agent.getGold() agent.removeGold(goldStolen) totalGoldStolen += goldStolen for agent in aggressiveAgents: goldEarned = math.ceil( totalGoldStolen * (agent.getStrength() / totalAggressiveStrength)) agent.addGold(goldEarned) else: penaltyPerAgent = math.ceil(totalPassiveStrength / len(aggressiveAgents)) for agent in aggressiveAgents: agent.removeGold(penaltyPerAgent) pass def raid(self, **kwargs): """Aggressive agents take turns stealing from passive agents""" passiveAgents = kwargs.get('passiveAgents') aggressiveAgents = kwargs.get('aggressiveAgents') unrobbedAgents = passiveAgents for robber in aggressiveAgents: if len(unrobbedAgents) > 0: victim = unrobbedAgents[0] unrobbedAgents.remove(victim) self.actionsHandler.rob(robber, victim) else: break pass def heist(self, **kwargs): """Aggressive agents work together to steal from passive agents""" passiveAgents = kwargs.get('passiveAgents') aggressiveAgents = kwargs.get('aggressiveAgents') totalAggressiveStrength = self.getTotalStrength(aggressiveAgents) totalPassiveStrength = self.getTotalStrength(passiveAgents) totalGoldOwned = self.getTotalGoldOwned(passiveAgents) totalGoldStolen = totalAggressiveStrength - totalPassiveStrength if totalGoldStolen > 0 and totalGoldOwned > 0: for agent in passiveAgents: goldLost = math.ceil(totalGoldStolen * (agent.getGold() / totalGoldOwned)) agent.removeGold(goldLost) for agent in aggressiveAgents: goldStolen = math.ceil( totalGoldStolen * (agent.getStrength() / totalAggressiveStrength)) agent.addGold(goldStolen) for agent in aggressiveAgents: robbingPenalty = math.ceil( (1 - (agent.getStrength() / totalAggressiveStrength)) * totalPassiveStrength) agent.removeGold(robbingPenalty) pass def sabotage(self, **kwargs): """Agents attempt to rob each other""" agents = kwargs.get('aggressiveAgents') for i in range(len(agents)): robbingAgent = agents[i] victimAgent = agents[0] if i < len(agents) - 1: victimAgent = agents[i + 1] self.actionsHandler.rob(robbingAgent, victimAgent) pass def combat(self, **kwargs): """Agents fight each other to get gold, strongest agent gets half of everyone's gold""" agents = kwargs.get('aggressiveAgents') strongestAgent = self.getStrongestAgent(agents) agents.remove(strongestAgent) goldPrize = 0 for agent in agents: goldLost = math.ceil(agent.getGold() / 2) fightingPenalty = math.ceil(strongestAgent.getStrength() / 2) agent.removeGold(goldLost + fightingPenalty) goldPrize += goldLost winnerFightingPenalty = math.ceil(self.getAverageStrength(agents) / 3) strongestAgent.addGold(goldPrize) strongestAgent.removeGold(winnerFightingPenalty) # ENCOUNTERS END HERE # def priorityDigging(self, agents, goldResource): """Diggers dig once in a set order.""" totalAmountCollected = 0 for agent in agents: amountCollected = self.triggerDigInteraction(agent, goldResource) agent.addGold(amountCollected) totalAmountCollected += amountCollected return totalAmountCollected def collectiveDigging(self, agents, goldResource): """All diggers pool their collections for future distribution.""" totalAmountCollected = 0 for agent in agents: amountCollected = self.triggerDigInteraction(agent, goldResource) totalAmountCollected = totalAmountCollected + amountCollected return totalAmountCollected def triggerDigInteraction(self, diggingAgent, goldResource): return self.actionsHandler.dig(diggingAgent, goldResource) def getTotalMaxGoldPerTurn(self, agents): totalMaxGold = 0 for agent in agents: totalMaxGold += agent.getMaxGoldPerTurn() return totalMaxGold def getTotalStrength(self, agents): totalStrength = 0 for agent in agents: totalStrength += agent.getStrength() return totalStrength def getAverageStrength(self, agents): totalStrength = self.getTotalStrength(agents) avgStrength = totalStrength / len(agents) return avgStrength def getTotalGoldOwned(self, agents): totalGold = 0 for agent in agents: totalGold += agent.getGold() return totalGold def keyToSortByGold(self, agent): return agent.getGold() def keyToSortByStrength(self, agent): return agent.getStrength() def getStrongestAgent(self, agents): agents = sorted(agents, reverse=True, key=self.keyToSortByStrength) return agents[0] def addTuples(self, tuple1, tuple2): return tuple(numpy.add(tuple1, tuple2)) def getAllEncounters(self): return self.passiveEncounters + self.robbingEncounters + self.aggressiveEncounters