def printSimulation(self): # Loop through private organism set, calling their print methods def print_orgs(): for org in self.orgsList: org.printStatus() with_lock(self.orgsListMutex, print_orgs) print str(len(self.orgsList)) + " organisms alive"
def reportDeath(self, organism, reason): self.getSeaBlock(organism.location).removeOrganism(organism) def remove(): if organism in self.orgsList: self.orgsList.remove(organism) with_lock(self.orgsListMutex, remove) def printDeath(): name = type(organism).__name__.lower() print "A " + name + " died because: " + reason with_lock(self.stdoutLock, printDeath)
def startSimulation(self): self.simulationRunning = True self.__setBarrier() # start all organism threads def startOrganisms(): for org in self.orgsList: org.start() with_lock(self.orgsListMutex, startOrganisms) # Start infinite control loop self.__loop() sys.exit()
def beEaten(self): def getEaten(): if not self.wasEaten: # in case we've already been eaten self.wasEaten = random_pick([True, False], [1 - self.survivalProbability, self.survivalProbability]) return self.wasEaten else: # was eaten but whoever called beEaten wasn't the one who did it return False return with_lock(self.beEatenLock, getEaten)
def __loop(self): self.printDivider() while self.simulationRunning: # sleep for TICK_TIME, so entire simulation has a normal heartbeat time.sleep(TICK_TIME) # after phase1, orgs are done with actions, we can do maintenance self.barrier.phase1() self.printSimulation() graphic_output.graphicsOutput(self.orgsList, "frame" + str(self.globalTicks) +".jpg", self.hdim, self.vdim) self.__addAndStartNewborns() with_lock(self.orgsListMutex, self.endSimulationIfNoOrganisms) self.__setBarrier() self.globalTicks += 1 # Print world stats every 10 ticks if self.globalTicks % 10 == 0: self.printRealStats() # If exceed the number of ticks set by user, stop simulation if self.globalTicks >= self.maxSimTicks: self.simulationRunning = False if self.simulationRunning: self.printDivider() # reach barrier, allow everyone to go on to the next step self.barrier.phase2() self.printFinalStats() # End all remaining threads def endThreads(): for org in self.orgsList: org.join() with_lock(self.orgsListMutex, endThreads) return
def beEaten(self): def getEaten(): if not self.wasEaten: self.population -= 1 if self.population <= 0: self.wasEaten = True return True else: return False return with_lock(self.beEatenLock, getEaten)
def beEaten(self): def getEaten(): if not self.wasEaten: removed = self.population * 0.0015 self.population -= removed if self.population <= 0: self.wasEaten = True return removed else: return 0 return with_lock(self.beEatenLock, getEaten)
def __addAndStartNewborns(self): for newborn in self.newborns: self.addOrganism(newborn) self.__setBarrier() # so that new threads started immediately block excessThreads = [] def startThreadsUpToLimit(): for org in self.orgsList: if not org.isAlive(): try: org.start() except Exception as e: # we've reached the thread limit excessThreads.append(org) with_lock(self.orgsListMutex, startThreadsUpToLimit) # if we've reached the thread limit, some newborns don't get to live for thread in excessThreads: self.reportDeath(thread, 'too many threads') self.__setBarrier() # if there were excess threads, n is incorrect self.newborns = []
def getOrganisms(self): def getOrgs(): orgsAsList = list(self.__organisms) return orgsAsList[:] # return by value, not by reference return with_lock(self.__orgsLock, getOrgs)
def addOrganism(self, Creature): with_lock(self.__orgsLock, lambda: self.__organisms.add(Creature))
def removeOrganism(self, organism): def remove(): if organism in self.__organisms: self.__organisms.remove(organism) with_lock(self.__orgsLock, remove)
def __setBarrier(self): # + 1 because ecosystem itself is being counted numThreads = len(self.orgsList) + 1 with_lock(self.orgsListMutex, lambda : self.barrier.setN(numThreads))
def reportBirth(self, newborn): with_lock(self.newbornsMutex, lambda : self.newborns.append(newborn))
def addOrganism(self, org): self.getSeaBlock(org.location).addOrganism(org) with_lock(self.orgsListMutex, lambda : self.orgsList.add(org))