import random import sys import core.model from core.model import Sector, ToricEnvironment from core.model import DIRECTION_UP, DIRECTION_DOWN, DIRECTION_LEFT, DIRECTION_RIGHT, DIRECTION_UPLEFT, DIRECTION_UPRIGHT, DIRECTION_DOWNLEFT,DIRECTION_DOWNRIGHT from core.event import SimulationStartedEvent, AgentMoveRequest, AgentMovedEvent, AgentKillEvent, TickEvent, AgentAddEvent, EnvironmentBuiltEvent class Fish(core.model.Agent): def __init__(self, disp, breeding_age): core.model.Agent.__init__(self, disp) self.disp.unregister(self) self.breeding_age = breeding_age self.age = 0 disp.post(AgentAddEvent(self)) def move(self): possible_dirs = range(DIRECTION_UP, DIRECTION_DOWNRIGHT+1) # Try to reach one of the 8 possible directions while len(possible_dirs) != 0: choice = random.choice(possible_dirs) if self.sector.move_possible(choice): self.sector.occupant = None self.sector = self.sector.neighbors[choice] self.sector.occupant = self #self.disp.post(AgentMovedEvent(self)) return possible_dirs.remove(choice) def reproduce(self): possible_dirs = range(DIRECTION_UP, DIRECTION_DOWNRIGHT+1) # Try to find an available direction while len(possible_dirs) != 0: choice = random.choice(possible_dirs) if self.sector.move_possible(choice): f = Fish(self.disp, self.breeding_age) f.place(self.sector.neighbors[choice]) return possible_dirs.remove(choice) def update(self): # If we are dead, don't move if self.sector != None: if self.age != 0 and self.age % self.breeding_age == 0: self.reproduce() self.move() self.age += 1 def notify(self, e): if isinstance(e, SimulationStartedEvent): # Build list of free sectors and select one free_sectors = [] for l in e.sim.env.sectors: for c in l: if c.occupant == None: free_sectors.append(c) if len(free_sectors) == 0: print "Unable to place this agent, no free space!" sys.exit(1) self.place(random.choice(free_sectors)) elif isinstance(e, AgentMoveRequest): # If we are dead, don't move if self.sector != None: if self.age != 0 and self.age % self.breeding_age == 0: self.reproduce() self.move() self.age += 1 def __repr__(self): return "Fish" + str(self.sector) class Shark(core.model.Agent): def __init__(self, disp, breeding_age, starvation_time): core.model.Agent.__init__(self, disp) self.disp.unregister(self) self.breeding_age = breeding_age self.starvation_time = starvation_time self.starv_counter = self.starvation_time self.age = 0 disp.post(AgentAddEvent(self)) def move(self): possible_dirs = [] for i in range(DIRECTION_UP, DIRECTION_DOWNRIGHT+1): possible_dirs.append(i) random.shuffle(possible_dirs) # Try to find a fish to eat for i in possible_dirs: if not self.sector.move_possible(i): # If we haven't reached the limit of the grid if self.sector.neighbors[i] != None: # If it's a fish if isinstance(self.sector.neighbors[i].occupant, Fish): #print "miam", self.sector.neighbors[i].occupant self.disp.post(AgentKillEvent(self.sector.neighbors[i].occupant)) self.sector.occupant = None self.sector = self.sector.neighbors[i] self.sector.occupant = self self.starv_counter = self.starvation_time #self.disp.post(AgentMovedEvent(self)) return # Try to reach one of the 8 possible directions while len(possible_dirs) != 0: choice = random.choice(possible_dirs) if self.sector.move_possible(choice): self.sector.occupant = None self.sector = self.sector.neighbors[choice] self.sector.occupant = self self.disp.post(AgentMovedEvent(self)) break possible_dirs.remove(choice) def reproduce(self): possible_dirs = [] for i in range(DIRECTION_UP, DIRECTION_DOWNRIGHT+1): possible_dirs.append(i) # Try to find an available direction while len(possible_dirs) != 0: choice = random.choice(possible_dirs) if self.sector.move_possible(choice): s = Shark(self.disp, self.breeding_age, self.starvation_time) s.place(self.sector.neighbors[choice]) return possible_dirs.remove(choice) def notify(self, e): if isinstance(e, SimulationStartedEvent): # Build list of free sectors and select one free_sectors = [] for l in e.sim.env.sectors: for c in l: if c.occupant == None: free_sectors.append(c) if len(free_sectors) == 0: print "Unable to place this agent, no free space!" sys.exit(1) self.place(random.choice(free_sectors)) def update(self): # If we are dead, don't move if self.sector != None: if self.starv_counter == 0: self.disp.post(AgentKillEvent(self)) return self.starv_counter -= 1 if self.age != 0 and self.age % self.breeding_age == 0: self.reproduce() self.move() self.age += 1 def __repr__(self): return "Shark" + str(self.sector) class WatorSimulation(core.model.Simulation): def __init__(self, disp, env, fishes, sharks, fish_breeding_age, shark_breeding_age, shark_starvation_time): core.model.Simulation.__init__(self, disp, env) self.fishes = [] self.sharks = [] for i in range(fishes): Fish(disp, fish_breeding_age) for i in range(sharks): Shark(disp, shark_breeding_age, shark_starvation_time) def notify(self, e): core.model.Simulation.notify(self, e) if isinstance(e, TickEvent): print "fish count : %d, shark count : %d"%(len(self.fishes), len(self.sharks)) print "grid space : %d, agents : %d"%((self.env.h*self.env.w), (len(self.fishes) +len(self.sharks))) if isinstance(e, AgentAddEvent): if isinstance(e.agent, Fish): self.fishes.append(e.agent) elif isinstance(e.agent, Shark): self.sharks.append(e.agent) elif isinstance(e, AgentKillEvent): if isinstance(e.agent, Fish): e.agent.sector.occupant = None e.agent.sector = None self.fishes.remove(e.agent) elif isinstance(e.agent, Shark): e.agent.sector.occupant = None e.agent.sector = None self.sharks.remove(e.agent) elif isinstance(e, AgentMoveRequest): for f in self.fishes: f.update() for s in self.sharks: s.update() elif isinstance(e, SimulationStartedEvent): # Build list of free sectors and select one free_sectors = [] for l in e.sim.env.sectors: for c in l: if c.occupant == None: free_sectors.append(c) if len(free_sectors) == 0: print "Unable to place this agent, no free space!" sys.exit(1) for f in self.fishes: choice = random.choice(free_sectors) f.place(choice) free_sectors.remove(choice) for s in self.sharks: choice = random.choice(free_sectors) s.place(choice) free_sectors.remove(choice)