コード例 #1
0
ファイル: cells.py プロジェクト: matthewrobertharris/cells
    def __init__(self, bounds, mind_list, symmetric, max_time, headless=False):
        self.size = self.width, self.height = (bounds, bounds)
        self.mind_list = mind_list
        self.messages = [MessageQueue() for x in mind_list]
        self.headless = headless
        if not self.headless:
            self.disp = Display(self.size, scale=2)
        self.time = 0
        self.clock = pygame.time.Clock()
        self.max_time = max_time
        self.tic = time.time()
        self.terr = ScalarMapLayer(self.size)
        self.terr.set_perlin(10, symmetric)
        self.minds = [m[1].AgentMind for m in mind_list]

        self.show_energy = True
        self.show_agents = True

        self.energy_map = ScalarMapLayer(self.size)
        self.energy_map.set_streak(SCATTERED_ENERGY, symmetric)

        self.plant_map = ObjectMapLayer(self.size)
        self.plant_population = []

        self.agent_map = ObjectMapLayer(self.size)
        self.agent_population = []
        self.winner = None
        if symmetric:
            self.n_plants = 7
        else:
            self.n_plants = 14

        # Add some randomly placed plants to the map. 
        for x in range(self.n_plants):
            mx = random.randrange(1, self.width - 1)
            my = random.randrange(1, self.height - 1)
            eff = random.randrange(PLANT_MIN_OUTPUT, PLANT_MAX_OUTPUT)
            p = Plant(mx, my, eff)
            self.plant_population.append(p)
            if symmetric:
                p = Plant(my, mx, eff)
                self.plant_population.append(p)
        self.plant_map.lock()
        self.plant_map.insert(self.plant_population)
        self.plant_map.unlock()

        # Create an agent for each mind and place on map at a different plant.
        self.agent_map.lock()
        for idx in range(len(self.minds)):
            # BUG: Number of minds could exceed number of plants?
            (mx, my) = self.plant_population[idx].get_pos()
            fuzzed_x = mx
            fuzzed_y = my
            while fuzzed_x == mx and fuzzed_y == my:
                fuzzed_x = mx + random.randrange(-1, 2)
                fuzzed_y = my + random.randrange(-1, 2)
            self.agent_population.append(Agent(fuzzed_x, fuzzed_y, STARTING_ENERGY, idx,
                                               self.minds[idx], None))
            self.agent_map.insert(self.agent_population)
        self.agent_map.unlock()
コード例 #2
0
    def __init__(self, bounds, mind_list, symmetric, max_time, headless=False):
        self.size = self.width, self.height = (bounds, bounds)
        self.mind_list = mind_list
        self.messages = [MessageQueue() for x in mind_list]
        self.headless = headless
        if not self.headless:
            self.disp = Display(self.size, scale=2)
        self.time = 0
        self.clock = pygame.time.Clock()
        self.max_time = max_time
        self.tic = time.time()
        self.terr = ScalarMapLayer(self.size)
        self.terr.set_perlin(10, symmetric)
        self.minds = [m[1].AgentMind for m in mind_list]

        self.show_energy = True
        self.show_agents = True

        self.energy_map = ScalarMapLayer(self.size)
        self.energy_map.set_streak(SCATTERED_ENERGY, symmetric)

        self.plant_map = ObjectMapLayer(self.size)
        self.plant_population = []

        self.agent_map = ObjectMapLayer(self.size)
        self.agent_population = []
        self.winner = None
        if symmetric:
            self.n_plants = 7
        else:
            self.n_plants = 14

        # Add some randomly placed plants to the map.
        for x in range(self.n_plants):
            mx = random.randrange(1, self.width - 1)
            my = random.randrange(1, self.height - 1)
            eff = random.randrange(PLANT_MIN_OUTPUT, PLANT_MAX_OUTPUT)
            p = Plant(mx, my, eff)
            self.plant_population.append(p)
            if symmetric:
                p = Plant(my, mx, eff)
                self.plant_population.append(p)
        self.plant_map.lock()
        self.plant_map.insert(self.plant_population)
        self.plant_map.unlock()

        # Create an agent for each mind and place on map at a different plant.
        self.agent_map.lock()
        for idx in range(len(self.minds)):
            # BUG: Number of minds could exceed number of plants?
            (mx, my) = self.plant_population[idx].get_pos()
            fuzzed_x = mx
            fuzzed_y = my
            while fuzzed_x == mx and fuzzed_y == my:
                fuzzed_x = mx + random.randrange(-1, 2)
                fuzzed_y = my + random.randrange(-1, 2)
            self.agent_population.append(
                Agent(fuzzed_x, fuzzed_y, STARTING_ENERGY, idx,
                      self.minds[idx], None))
            self.agent_map.insert(self.agent_population)
        self.agent_map.unlock()
コード例 #3
0
ファイル: cells.py プロジェクト: matthewrobertharris/cells
class Game(object):
    # Represents a game between different minds.
    def __init__(self, bounds, mind_list, symmetric, max_time, headless=False):
        self.size = self.width, self.height = (bounds, bounds)
        self.mind_list = mind_list
        self.messages = [MessageQueue() for x in mind_list]
        self.headless = headless
        if not self.headless:
            self.disp = Display(self.size, scale=2)
        self.time = 0
        self.clock = pygame.time.Clock()
        self.max_time = max_time
        self.tic = time.time()
        self.terr = ScalarMapLayer(self.size)
        self.terr.set_perlin(10, symmetric)
        self.minds = [m[1].AgentMind for m in mind_list]

        self.show_energy = True
        self.show_agents = True

        self.energy_map = ScalarMapLayer(self.size)
        self.energy_map.set_streak(SCATTERED_ENERGY, symmetric)

        self.plant_map = ObjectMapLayer(self.size)
        self.plant_population = []

        self.agent_map = ObjectMapLayer(self.size)
        self.agent_population = []
        self.winner = None
        if symmetric:
            self.n_plants = 7
        else:
            self.n_plants = 14

        # Add some randomly placed plants to the map. 
        for x in range(self.n_plants):
            mx = random.randrange(1, self.width - 1)
            my = random.randrange(1, self.height - 1)
            eff = random.randrange(PLANT_MIN_OUTPUT, PLANT_MAX_OUTPUT)
            p = Plant(mx, my, eff)
            self.plant_population.append(p)
            if symmetric:
                p = Plant(my, mx, eff)
                self.plant_population.append(p)
        self.plant_map.lock()
        self.plant_map.insert(self.plant_population)
        self.plant_map.unlock()

        # Create an agent for each mind and place on map at a different plant.
        self.agent_map.lock()
        for idx in range(len(self.minds)):
            # BUG: Number of minds could exceed number of plants?
            (mx, my) = self.plant_population[idx].get_pos()
            fuzzed_x = mx
            fuzzed_y = my
            while fuzzed_x == mx and fuzzed_y == my:
                fuzzed_x = mx + random.randrange(-1, 2)
                fuzzed_y = my + random.randrange(-1, 2)
            self.agent_population.append(Agent(fuzzed_x, fuzzed_y, STARTING_ENERGY, idx,
                                               self.minds[idx], None))
            self.agent_map.insert(self.agent_population)
        self.agent_map.unlock()

    def run_plants(self):
        # Increases energy at and around (adjacent position) for each plant.
        # Increase in energy is equal to the eff(?) value of each the plant.
        for p in self.plant_population:
            (x, y) = p.get_pos()
            for dx in (-1, 0, 1):
                for dy in (-1, 0, 1):
                    adj_x = x + dx
                    adj_y = y + dy
                    if self.energy_map.in_range(adj_x, adj_y):
                        self.energy_map.change(adj_x, adj_y, p.get_eff())

    def add_agent(self, a):
        # Adds an agent to the game.
        self.agent_population.append(a)
        self.agent_map.set(a.x, a.y, a)

    def del_agent(self, a):
        # Kills the agent (if not already dead), removes them from the game and
        # drops any load they were carrying in there previously occupied position.
        self.agent_population.remove(a)
        self.agent_map.set(a.x, a.y, None)
        a.alive = False
        if a.loaded:
            a.loaded = False
            self.terr.change(a.x, a.y, 1)

    def move_agent(self, a, x, y):
        # Moves agent, a, to new position (x,y) unless difference in terrain levels between
        # its current position and new position is greater than 4.
        if abs(self.terr.get(x, y) - self.terr.get(a.x, a.y)) <= HEIGHT_DIFF:
            self.agent_map.set(a.x, a.y, None)
            self.agent_map.set(x, y, a)
            a.x = x
            a.y = y

    def run_agents(self):
        # Create a list containing the view for each agent in the population.
        views = []
        agent_map_get_small_view_fast = self.agent_map.get_small_view_fast
        plant_map_get_small_view_fast = self.plant_map.get_small_view_fast
        energy_map = self.energy_map
        terr_map = self.terr
        wv = WorldView
        views_append = views.append
        for a in self.agent_population:
            x = a.x
            y = a.y
            agent_view = agent_map_get_small_view_fast(x, y)
            plant_view = plant_map_get_small_view_fast(x, y)
            world_view = wv(a, agent_view, plant_view, terr_map, energy_map)
            views_append((a, world_view))

        # Create a list containing the action for each agent, where each agent
        # determines its actions based on its view of the world and messages 
        # from its team.
        messages = self.messages
        actions = [(a, a.act(v, messages[a.team])) for (a, v) in views]
        actions_dict = dict(actions)
        random.shuffle(actions)

        self.agent_map.lock()
        # Apply the action for each agent - in doing so agent uses up 1 energy unit.
        for (agent, action) in actions:
            # This is the cost of mere survival
            agent.energy -= SUSTAIN_COST

            if action.type == ACT_MOVE:  # Changes position of agent.
                act_x, act_y = action.get_data()
                (new_x, new_y) = get_next_move(agent.x, agent.y,
                                               act_x, act_y)
                # Move to the new position if it is in range and it's not 
                # currently occupied by another agent.
                if (self.agent_map.in_range(new_x, new_y) and
                        not self.agent_map.get(new_x, new_y)):
                    self.move_agent(agent, new_x, new_y)
                    agent.energy -= MOVE_COST
            elif action.type == ACT_SPAWN:  # Creates new agents.py and uses additional 50 energy units.
                act_x, act_y = action.get_data()[:2]
                (new_x, new_y) = get_next_move(agent.x, agent.y,
                                               act_x, act_y)
                if (self.agent_map.in_range(new_x, new_y) and
                        not self.agent_map.get(new_x, new_y) and
                        agent.energy >= SPAWN_TOTAL_ENERGY):
                    agent.energy -= SPAWN_TOTAL_ENERGY
                    agent.energy /= 2
                    a = Agent(new_x, new_y, agent.energy, agent.get_team(),
                              self.minds[agent.get_team()],
                              action.get_data()[2:])
                    self.add_agent(a)
            elif action.type == ACT_EAT:
                # Eat only as much as possible.
                intake = min(self.energy_map.get(agent.x, agent.y),
                             ENERGY_CAP - agent.energy)
                agent.energy += intake
                self.energy_map.change(agent.x, agent.y, -intake)
            elif action.type == ACT_RELEASE:
                # Dump some energy onto an adjacent field
                # No Seppuku
                output = action.get_data()[2]
                output = min(agent.energy - 1, output)
                act_x, act_y = action.get_data()[:2]
                # Use get_next_move to simplyfy things if you know
                # where the energy is supposed to end up.
                (out_x, out_y) = get_next_move(agent.x, agent.y,
                                               act_x, act_y)
                if self.agent_map.in_range(out_x, out_y) and agent.energy >= 1:
                    agent.energy -= output
                    self.energy_map.change(out_x, out_y, output)
            elif action.type == ACT_ATTACK:
                # Make sure agent is attacking an adjacent field.
                act_x, act_y = act_data = action.get_data()
                next_pos = get_next_move(agent.x, agent.y, act_x, act_y)
                # new_x, new_y = next_pos
                victim = self.agent_map.get(act_x, act_y)
                terr_delta = (self.terr.get(agent.x, agent.y) - self.terr.get(act_x, act_y))
                if victim is not None and victim.alive and next_pos == act_data:
                    # If both agents.py attack each other, both loose double energy
                    # Think twice before attacking
                    try:
                        contested = (actions_dict[victim].type == ACT_ATTACK)
                    except:
                        contested = False
                    agent.attack(victim, terr_delta, contested)
                    if contested:
                        victim.attack(agent, -terr_delta, True)

            elif action.type == ACT_LIFT:
                if not agent.loaded and self.terr.get(agent.x, agent.y) > 0:
                    agent.loaded = True
                    self.terr.change(agent.x, agent.y, -1)

            elif action.type == ACT_DROP:
                if agent.loaded:
                    agent.loaded = False
                    self.terr.change(agent.x, agent.y, 1)

        # Kill all agents.py with negative energy.
        team = [0 for n in self.minds]
        for (agent, action) in actions:
            if agent.energy < 0 and agent.alive:
                self.energy_map.change(agent.x, agent.y, BODY_ENERGY)
                self.del_agent(agent)
            else:
                team[agent.team] += 1

        # Team wins (and game ends) if opposition team has 0 agents.py remaining.
        # Draw if time exceeds time limit.
        winner = 0
        alive = 0
        for t in team:
            if t != 0:
                alive += 1
            else:
                if alive == 0:
                    winner += 1

        if alive == 1:
            colors = ["red", "white", "purple", "yellow"]
            print("Winner is %s (%s) in %s" % (self.mind_list[winner][1].name,
                                               colors[winner], str(self.time)))
            self.winner = winner

        if alive == 0 or (self.max_time > 0 and self.time > self.max_time):
            print("It's a draw!")
            self.winner = -1

        self.agent_map.unlock()

    def tick(self):
        if not self.headless:
            # Space starts new game
            # q or close button will quit the game
            for event in pygame.event.get():
                if event.type == pygame.locals.KEYUP:
                    if event.key == pygame.locals.K_SPACE:
                        self.winner = -1
                    elif event.key == pygame.locals.K_q:
                        sys.exit()
                    elif event.key == pygame.locals.K_e:
                        self.show_energy = not self.show_energy
                    elif event.key == pygame.locals.K_a:
                        self.show_agents = not self.show_agents
                elif event.type == pygame.locals.MOUSEBUTTONUP:
                    if event.button == 1:
                        print(self.agent_map.get(event.pos[0] / 2,
                                                 event.pos[1] / 2))
                elif event.type == pygame.QUIT:
                    sys.exit()
            self.disp.update(self.terr, self.agent_population,
                             self.plant_population, self.agent_map,
                             self.plant_map, self.energy_map, self.time,
                             len(self.minds), self.show_energy,
                             self.show_agents)

            # test for spacebar pressed - if yes, restart
            for event in pygame.event.get(pygame.locals.KEYUP):
                if event.key == pygame.locals.K_SPACE:
                    self.winner = -1
            if pygame.event.get(pygame.locals.QUIT):
                sys.exit()
            pygame.event.pump()
            self.disp.flip()
        self.run_agents()
        self.run_plants()
        for msg in self.messages:
            msg.update()
        self.time += 1
        self.tic = time.time()
        self.clock.tick(FPS)
コード例 #4
0
class Game(object):
    # Represents a game between different minds.
    def __init__(self, bounds, mind_list, symmetric, max_time, headless=False):
        self.size = self.width, self.height = (bounds, bounds)
        self.mind_list = mind_list
        self.messages = [MessageQueue() for x in mind_list]
        self.headless = headless
        if not self.headless:
            self.disp = Display(self.size, scale=2)
        self.time = 0
        self.clock = pygame.time.Clock()
        self.max_time = max_time
        self.tic = time.time()
        self.terr = ScalarMapLayer(self.size)
        self.terr.set_perlin(10, symmetric)
        self.minds = [m[1].AgentMind for m in mind_list]

        self.show_energy = True
        self.show_agents = True

        self.energy_map = ScalarMapLayer(self.size)
        self.energy_map.set_streak(SCATTERED_ENERGY, symmetric)

        self.plant_map = ObjectMapLayer(self.size)
        self.plant_population = []

        self.agent_map = ObjectMapLayer(self.size)
        self.agent_population = []
        self.winner = None
        if symmetric:
            self.n_plants = 7
        else:
            self.n_plants = 14

        # Add some randomly placed plants to the map.
        for x in range(self.n_plants):
            mx = random.randrange(1, self.width - 1)
            my = random.randrange(1, self.height - 1)
            eff = random.randrange(PLANT_MIN_OUTPUT, PLANT_MAX_OUTPUT)
            p = Plant(mx, my, eff)
            self.plant_population.append(p)
            if symmetric:
                p = Plant(my, mx, eff)
                self.plant_population.append(p)
        self.plant_map.lock()
        self.plant_map.insert(self.plant_population)
        self.plant_map.unlock()

        # Create an agent for each mind and place on map at a different plant.
        self.agent_map.lock()
        for idx in range(len(self.minds)):
            # BUG: Number of minds could exceed number of plants?
            (mx, my) = self.plant_population[idx].get_pos()
            fuzzed_x = mx
            fuzzed_y = my
            while fuzzed_x == mx and fuzzed_y == my:
                fuzzed_x = mx + random.randrange(-1, 2)
                fuzzed_y = my + random.randrange(-1, 2)
            self.agent_population.append(
                Agent(fuzzed_x, fuzzed_y, STARTING_ENERGY, idx,
                      self.minds[idx], None))
            self.agent_map.insert(self.agent_population)
        self.agent_map.unlock()

    def run_plants(self):
        # Increases energy at and around (adjacent position) for each plant.
        # Increase in energy is equal to the eff(?) value of each the plant.
        for p in self.plant_population:
            (x, y) = p.get_pos()
            for dx in (-1, 0, 1):
                for dy in (-1, 0, 1):
                    adj_x = x + dx
                    adj_y = y + dy
                    if self.energy_map.in_range(adj_x, adj_y):
                        self.energy_map.change(adj_x, adj_y, p.get_eff())

    def add_agent(self, a):
        # Adds an agent to the game.
        self.agent_population.append(a)
        self.agent_map.set(a.x, a.y, a)

    def del_agent(self, a):
        # Kills the agent (if not already dead), removes them from the game and
        # drops any load they were carrying in there previously occupied position.
        self.agent_population.remove(a)
        self.agent_map.set(a.x, a.y, None)
        a.alive = False
        if a.loaded:
            a.loaded = False
            self.terr.change(a.x, a.y, 1)

    def move_agent(self, a, x, y):
        # Moves agent, a, to new position (x,y) unless difference in terrain levels between
        # its current position and new position is greater than 4.
        if abs(self.terr.get(x, y) - self.terr.get(a.x, a.y)) <= HEIGHT_DIFF:
            self.agent_map.set(a.x, a.y, None)
            self.agent_map.set(x, y, a)
            a.x = x
            a.y = y

    def run_agents(self):
        # Create a list containing the view for each agent in the population.
        views = []
        agent_map_get_small_view_fast = self.agent_map.get_small_view_fast
        plant_map_get_small_view_fast = self.plant_map.get_small_view_fast
        energy_map = self.energy_map
        terr_map = self.terr
        wv = WorldView
        views_append = views.append
        for a in self.agent_population:
            x = a.x
            y = a.y
            agent_view = agent_map_get_small_view_fast(x, y)
            plant_view = plant_map_get_small_view_fast(x, y)
            world_view = wv(a, agent_view, plant_view, terr_map, energy_map)
            views_append((a, world_view))

        # Create a list containing the action for each agent, where each agent
        # determines its actions based on its view of the world and messages
        # from its team.
        messages = self.messages
        actions = [(a, a.act(v, messages[a.team])) for (a, v) in views]
        actions_dict = dict(actions)
        random.shuffle(actions)

        self.agent_map.lock()
        # Apply the action for each agent - in doing so agent uses up 1 energy unit.
        for (agent, action) in actions:
            # This is the cost of mere survival
            agent.energy -= SUSTAIN_COST

            if action.type == ACT_MOVE:  # Changes position of agent.
                act_x, act_y = action.get_data()
                (new_x, new_y) = get_next_move(agent.x, agent.y, act_x, act_y)
                # Move to the new position if it is in range and it's not
                # currently occupied by another agent.
                if (self.agent_map.in_range(new_x, new_y)
                        and not self.agent_map.get(new_x, new_y)):
                    self.move_agent(agent, new_x, new_y)
                    agent.energy -= MOVE_COST
            elif action.type == ACT_SPAWN:  # Creates new agents.py and uses additional 50 energy units.
                act_x, act_y = action.get_data()[:2]
                (new_x, new_y) = get_next_move(agent.x, agent.y, act_x, act_y)
                if (self.agent_map.in_range(new_x, new_y)
                        and not self.agent_map.get(new_x, new_y)
                        and agent.energy >= SPAWN_TOTAL_ENERGY):
                    agent.energy -= SPAWN_TOTAL_ENERGY
                    agent.energy /= 2
                    a = Agent(new_x, new_y, agent.energy, agent.get_team(),
                              self.minds[agent.get_team()],
                              action.get_data()[2:])
                    self.add_agent(a)
            elif action.type == ACT_EAT:
                # Eat only as much as possible.
                intake = min(self.energy_map.get(agent.x, agent.y),
                             ENERGY_CAP - agent.energy)
                agent.energy += intake
                self.energy_map.change(agent.x, agent.y, -intake)
            elif action.type == ACT_RELEASE:
                # Dump some energy onto an adjacent field
                # No Seppuku
                output = action.get_data()[2]
                output = min(agent.energy - 1, output)
                act_x, act_y = action.get_data()[:2]
                # Use get_next_move to simplyfy things if you know
                # where the energy is supposed to end up.
                (out_x, out_y) = get_next_move(agent.x, agent.y, act_x, act_y)
                if self.agent_map.in_range(out_x, out_y) and agent.energy >= 1:
                    agent.energy -= output
                    self.energy_map.change(out_x, out_y, output)
            elif action.type == ACT_ATTACK:
                # Make sure agent is attacking an adjacent field.
                act_x, act_y = act_data = action.get_data()
                next_pos = get_next_move(agent.x, agent.y, act_x, act_y)
                # new_x, new_y = next_pos
                victim = self.agent_map.get(act_x, act_y)
                terr_delta = (self.terr.get(agent.x, agent.y) -
                              self.terr.get(act_x, act_y))
                if victim is not None and victim.alive and next_pos == act_data:
                    # If both agents.py attack each other, both loose double energy
                    # Think twice before attacking
                    try:
                        contested = (actions_dict[victim].type == ACT_ATTACK)
                    except:
                        contested = False
                    agent.attack(victim, terr_delta, contested)
                    if contested:
                        victim.attack(agent, -terr_delta, True)

            elif action.type == ACT_LIFT:
                if not agent.loaded and self.terr.get(agent.x, agent.y) > 0:
                    agent.loaded = True
                    self.terr.change(agent.x, agent.y, -1)

            elif action.type == ACT_DROP:
                if agent.loaded:
                    agent.loaded = False
                    self.terr.change(agent.x, agent.y, 1)

        # Kill all agents.py with negative energy.
        team = [0 for n in self.minds]
        for (agent, action) in actions:
            if agent.energy < 0 and agent.alive:
                self.energy_map.change(agent.x, agent.y, BODY_ENERGY)
                self.del_agent(agent)
            else:
                team[agent.team] += 1

        # Team wins (and game ends) if opposition team has 0 agents.py remaining.
        # Draw if time exceeds time limit.
        winner = 0
        alive = 0
        for t in team:
            if t != 0:
                alive += 1
            else:
                if alive == 0:
                    winner += 1

        if alive == 1:
            colors = ["red", "white", "purple", "yellow"]
            print("Winner is %s (%s) in %s" % (self.mind_list[winner][1].name,
                                               colors[winner], str(self.time)))
            self.winner = winner

        if alive == 0 or (self.max_time > 0 and self.time > self.max_time):
            print("It's a draw!")
            self.winner = -1

        self.agent_map.unlock()

    def tick(self):
        if not self.headless:
            # Space starts new game
            # q or close button will quit the game
            for event in pygame.event.get():
                if event.type == pygame.locals.KEYUP:
                    if event.key == pygame.locals.K_SPACE:
                        self.winner = -1
                    elif event.key == pygame.locals.K_q:
                        sys.exit()
                    elif event.key == pygame.locals.K_e:
                        self.show_energy = not self.show_energy
                    elif event.key == pygame.locals.K_a:
                        self.show_agents = not self.show_agents
                elif event.type == pygame.locals.MOUSEBUTTONUP:
                    if event.button == 1:
                        print(
                            self.agent_map.get(event.pos[0] / 2,
                                               event.pos[1] / 2))
                elif event.type == pygame.QUIT:
                    sys.exit()
            self.disp.update(self.terr, self.agent_population,
                             self.plant_population, self.agent_map,
                             self.plant_map, self.energy_map, self.time,
                             len(self.minds), self.show_energy,
                             self.show_agents)

            # test for spacebar pressed - if yes, restart
            for event in pygame.event.get(pygame.locals.KEYUP):
                if event.key == pygame.locals.K_SPACE:
                    self.winner = -1
            if pygame.event.get(pygame.locals.QUIT):
                sys.exit()
            pygame.event.pump()
            self.disp.flip()
        self.run_agents()
        self.run_plants()
        for msg in self.messages:
            msg.update()
        self.time += 1
        self.tic = time.time()
        self.clock.tick(FPS)