Skip to content
Snippets Groups Projects
Select Git revision
  • a523d9647081382449783cc71147f133804bc36f
  • master default protected
2 results

eclipse_path_includes_settings.xml

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ackland_schoen.py 23.10 KiB
    from graphics import *
    import time
    import random
    import math
    import csv
    
    #-----global variables--------------------
    visual = False
    winWidth = 700
    winHeight = 700
    
    if visual:
        window = GraphWin("Window", winWidth, winHeight)
    else:
        window = None
    
    maxTime = 10000
    
    agentNum = 80
    predNum = 8#agentNum/10
    generations = 100
    
    foodCluster = 16
    clusterSize = 8
    clusterradius = 20
    
    # choose simulation type
    isFood = False
    isPred = False
    Both = True
    
    t = 0.1
    
    rr = 5
    
    # area an agent can see
    As = 5000 * (rr**2)
    Am = 5 * (rr**2) * t
    
    #mutate values
    m_zoo_r = 5
    m_zoa_r = 10
    m_speed = 0.1
    m_food = 0.1
    m_pred = 0.1
    m_noise = 0.05
    
    #-----Agent class--------------------
    
    class Agent:
        def __init__(self, point, window ):
                self.color = color_rgb(0,0,0)
    
                self.point = point
                self.window = window
                self.Velocity_x = 1
                self.Velocity_y = 1
                self.tempV = [0,0]
    
                self.line = Line(self.point, Point(self.point.getX() + self.Velocity_x, self.point.getY()+self.Velocity_y))
    
                #evolvable
                self.speed = 4
                self.zor_r = 5#fix
                self.zoo_r = 20
                self.zoa_r = 200
    
                self.attCircle = Circle(self.point, self.zoa_r)
    
                self.blind_angle = 30
                self.turn_angle = 50
    
                self.food_pref = 5
                self.anti_pred = 0
                self.foodlevel = 0
                self.noise = 2
    
        def drawLine(self):
            self.line.undraw()
            self.line = Line(self.point, Point(self.point.getX() + self.Velocity_x, self.point.getY()+self.Velocity_y))
            self.line.setArrow("last")
            self.line.setFill(self.color)
            self.line.draw(self.window)
    
        def create_random_agent(self):
            self.Velocity_x = random.uniform(-1, 1)
            self.Velocity_y = random.uniform(-1, 1)
    
            self.zor_r = rr
            self.zoa_r = random.uniform( math.sqrt(As/(2*math.pi)), 1.5*math.sqrt(As/(2*math.pi)) )
            self.zoo_r = random.uniform(rr, self.zoa_r)
    
            self.speed = random.uniform(1, 5)
            self.blind_angle = (360 - math.degrees(As/(self.zoa_r**2)) ) / 2
            self.turn_angle = math.degrees(Am/(2*(self.speed**2)))
    
            self.food_pref = random.uniform(0,5)
            self.anti_pred = random.uniform(0,5)
    
            self.noise = random.uniform(0,1)
    
            r = random.randrange(256)
            g = random.randrange(256)
            b = random.randrange(256)
    
            return self
            #agent.color = color_rgb(r,g,b)
    
    """
            self.attCircle.undraw()
            self.attCircle = Circle(self.point, self.zoa_r)
            self.attCircle.setOutline("black")
            self.attCircle.draw(self.window)
    """
    #-----Predator class--------------------
    
    class Predator:
    
        def __init__(self, point, window ):
            self.color = "red"
            self.point = point
            self.window = window
            self.Velocity_x = 1
            self.Velocity_y = 1
            self.tempV = [0,0]
    
            self.line = Line(self.point, Point(self.point.getX() + self.Velocity_x, self.point.getY()+self.Velocity_y))
    
            #evolvable
            self.speed = 5.5
    
            self.zor_r = 10#fix
            #self.zoo_r = 20
            self.zoa_r = 200
    
            self.attCircle = Circle(self.point, self.zoa_r)
    
            self.blind_angle = 90
            self.turn_angle = 50
    
            #self.food_pref = 5
            #self.anti_pred = 0
            #self.foodlevel = 0
            self.noise = 2
            self.hasEaten = False
            self.lifeTime = 0
    
        def drawLine(self):
            self.line.undraw()
            self.line = Line(self.point, Point(self.point.getX() + self.Velocity_x, self.point.getY()+self.Velocity_y))
            self.line.setArrow("last")
            self.line.setFill(self.color)
            self.line.draw(self.window)
    
        def create_random_predator(self):
            self.Velocity_x = random.uniform(-1, 1)
            self.Velocity_y = random.uniform(-1, 1)
    
            self.zor_r = rr
            view_angle = 360-(self.blind_angle*2)
            self.zoa_r = 20*math.sqrt(As/view_angle)
            #self.blind_angle = (360 - math.degrees(As/(self.zoa_r**2)) ) / 2
            #self.turn_angle = math.degrees(1.5*Am/(2*(self.speed**2)))
            self.turn_angle = 140
    
            return(self)
            
    
    #-----Food class--------------------
    
    class Food:
        def __init__(self, Point):
                self.point = Point
    
    def generate_food(widthTemp, heightTemp):
        foods = []
        for j in range (foodCluster):
            x = random.uniform(widthTemp + clusterradius, winWidth-clusterradius)
            y = random.uniform(heightTemp + clusterradius, winHeight- clusterradius)
            for k in range (clusterSize):
                xk = random.uniform(x - clusterradius, x + clusterradius)
                yk = random.uniform(y - clusterradius, y + clusterradius)
                f = Food(Point(xk, yk))
                if visual:
                    f.point.setFill("blue")
                    f.point.draw(window)
                foods.append(f)
        return foods
                
    #-----help functions--------------------
    
    
    # Distance function betwen points xi, yi and xii,yii
    def distance(xi,xii,yi,yii):
        sq1 = (xi-xii)*(xi-xii)
        sq2 = (yi-yii)*(yi-yii)
        return math.sqrt(sq1 + sq2)
    
    # absolute value of a vector (a,b)
    def absvec(a, b):
        m = math.sqrt(a*a + b*b)
        if m == 0: m = 0.001
        return m
    
    # angle between two direction vectors
    def calc_angle(x1, y1, x2, y2):
            skalar = x1*x2 + y1*y2
            abs1 = absvec(x1, y1)
            abs2 = absvec(x2, y2)
    
            erg = skalar/(abs1* abs2)
            if erg > 1:
                #print erg
                erg=1
    
            elif erg < -1:
                #print erg
                erg=-1
            return math.degrees(math.acos(erg))
    
    # returns nearest neighbour of a in aas
    def nearest_neighbour(a,aas):
    
        minDis = float('inf')
        nn = None
    
        for b in aas:
    
            disVecX = b.point.getX() - a.point.getX()
            disVecY = b.point.getY() - a.point.getY()
            alpha = calc_angle(a.Velocity_x,a.Velocity_y, disVecX, disVecY)
    
            if (a == b):
                True
            elif alpha < 180 - a.blind_angle and alpha > 180 + a.blind_angle:
                True
            elif (nn == None):
                nn = b
            else:
                dis = distance(a.point.getX(),b.point.getX(), a.point.getY(), b.point.getY())
                if(dis < minDis):
                    minDis = dis
                    nn = b
        return nn
    
    
    #-----couzin movement--------------------
    
    # returns three lists, one for each zone,
    # contaning all other agents in the zone.
    # ignores all agents in the angle behind the current agent defined by blind.
    def neigbour_in_zones(a, aas):
        zor = []
        zoo = []
        zoa = []
    
        for agent in aas:
            disVecX = agent.point.getX() - a.point.getX()
            disVecY = agent.point.getY() - a.point.getY()
            alpha = calc_angle(a.Velocity_x, a.Velocity_y, disVecX, disVecY)
    
            if (a == agent):
                True
            elif alpha < 180 - a.blind_angle and alpha > 180 + a.blind_angle:
                True
            else:
                dis = absvec(agent.point.getX() - a.point.getX() , agent.point.getY() - a.point.getY() )
                if dis <= a.zor_r:
                    zor.append(agent)
                elif dis <= a.zoo_r:
                    zoo.append(agent)
                elif dis <= a.zoa_r:
                    zoa.append(agent)
    
        #print len(zoo)+len(zor)+len(zoa)
        return [zor, zoo, zoa]
    
    #update Velocity a la couzin
    def updateV_couzin(a, matrix):
    
        dx=0
        dy=0
    
        #zor
        if matrix[0] != []:
            for agent in matrix[0]:
                disX = agent.point.getX() - a.point.getX()
                disY = agent.point.getY() - a.point.getY()
    
                rX = disX/absvec(disX, disY)
                rY = disY/absvec(disX, disY)
    
                dx += rX / absvec(rX, rY)
                dy += rY / absvec(rX, rY)
    
            dx = -dx
            dy = -dy
    
        # zoo ; zoa leer
        elif matrix[1] != []  and matrix[2] == []:
            for agent in matrix[1]:
                dx += agent.Velocity_x / absvec(agent.Velocity_x, agent.Velocity_y)
                dy += agent.Velocity_y / absvec(agent.Velocity_x, agent.Velocity_y)
            dx += a.Velocity_x / absvec(a.Velocity_x, a.Velocity_y)
            dy += a.Velocity_y / absvec(a.Velocity_x, a.Velocity_y)
    
    
        # zoo leer ; zoa
        elif matrix[1] == []  and matrix[2] != []:
            for agent in matrix[2]:
                disX = agent.point.getX() - a.point.getX()
                disY = agent.point.getY() - a.point.getY()
    
                rX = disX/absvec(disX, disY)
                rY = disY/absvec(disX, disY)
    
                dx += rX / absvec(rX, rY)
                dy += rY / absvec(rX, rY)
    
        # zoo ; zoa
        elif matrix[1] != []  and matrix[2] != []:
            for agent in matrix[1]:
                dx += agent.Velocity_x / absvec(agent.Velocity_x, agent.Velocity_y)
                dy += agent.Velocity_y / absvec(agent.Velocity_x, agent.Velocity_y)
            dx += a.Velocity_x / absvec(a.Velocity_x, a.Velocity_y)
            dy += a.Velocity_y / absvec(a.Velocity_x, a.Velocity_y)
    
            for agent in matrix[2]:
                disX = agent.point.getX() - a.point.getX()
                disY = agent.point.getY() - a.point.getY()
    
                rX = disX/absvec(disX, disY)
                rY = disY/absvec(disX, disY)
    
                dx += rX / absvec(rX, rY)
                dy += rY / absvec(rX, rY)
    
            dx = 0.5*dx
            dy = 0.5*dy
    
    	# all zones empty
        else:
            dx = a.Velocity_x
            dy = a.Velocity_y
    
    	# randomness factor / error
        dx += random.uniform(-a.noise/2, a.noise/2)
        dy += random.uniform(-a.noise/2, a.noise/2)
    
        return [dx, dy]
    
    # searches nearest food item, checks if it can be eaten,
    # else returns direction vector pointing towards it
    def check_food(agent, foods):
        dX=0
        dY=0
        if foods == []:
            return [dX,dY]
    
        nf = nearest_neighbour(agent, foods)
        dis = distance(agent.point.getX(), nf.point.getX(), agent.point.getY(), nf.point.getY())
    
    
        if dis<=agent.zor_r:
            nf.point.undraw()
            foods.remove(nf)
            agent.foodlevel += 1
    
        elif dis<=agent.zoa_r:
            disX = nf.point.getX() - agent.point.getX()
            disY = nf.point.getY() - agent.point.getY()
    
            rX = disX/absvec(disX, disY)
            rY = disY/absvec(disX, disY)
    
            dX = rX / absvec(rX, rY)
            dY = rY / absvec(rX, rY)
    
        return [dX, dY]
    
    #same as checkfood, but can not eat a predator
    def check_predator(agent, predators):
        dX=0
        dY=0
        if predators == []:
            return [dX,dY]
    
        nf = nearest_neighbour(agent, predators)
        dis = distance(agent.point.getX(), nf.point.getX(), agent.point.getY(), nf.point.getY())
    
        if dis<=agent.zoa_r:
            disX = nf.point.getX() - agent.point.getX()
            disY = nf.point.getY() - agent.point.getY()
    
            rX = disX/absvec(disX, disY)
            rY = disY/absvec(disX, disY)
    
            dX = rX / absvec(rX, rY)
            dY = rY / absvec(rX, rY)
    
        return [dX, dY]
    
    #check for nearest prey in agents, and test if it can be eaten
    def check_prey(predator, agents):
        dX = predator.Velocity_x
        dY = predator.Velocity_y
    
        if agents == []:
            return [dX,dY]
    
        na = nearest_neighbour(predator, agents)
        dis = distance(predator.point.getX(), na.point.getX(), predator.point.getY(), na.point.getY())
    
        if dis <= predator.zor_r:
            if visual:
                na.point.undraw()
                na.line.undraw()
                agents.remove(na)
    
            predator.hasEaten = True
    
        elif dis <= predator.zoa_r:
            disX = na.point.getX() - predator.point.getX()
            disY = na.point.getY() - predator.point.getY()
    
            rX = disX/absvec(disX, disY)
            rY = disY/absvec(disX, disY)
    
            dX = rX / absvec(rX, rY)
            dY = rY / absvec(rX, rY)
    
        return [dX, dY]
    
    # updates velocity, taking food and predators and other agents into account
    def updateV_final(agent, matrix,foods, predators):
        vc = updateV_couzin(agent, matrix)
        vf = check_food(agent, foods)
        vp = check_predator(agent, predators)
    
        vvX = vc[0] + agent.food_pref* vf[0] - agent.anti_pred * vp[0]
        vvY = vc[1] + agent.food_pref* vf[1] - agent.anti_pred * vp[1]
    
        return [vvX, vvY]
    
    
    # check for window boundaries
    def checkBoundary(agent, winWidth, winHeight):
        point = agent.point
        point.move(agent.Velocity_x,agent.Velocity_y)
    
        x = point.getX()
        y = point.getY()
    
        if x > 0 and y < winHeight and x < winWidth and y > 0:
            agent.point = point
    
        else:
            if x <= 0 or x >= winWidth:
                agent.Velocity_x = agent.Velocity_x * (-1)
    
            if y <= 0 or y >= winHeight:
                agent.Velocity_y = agent.Velocity_y * (-1)
    
            agent.point.move(agent.Velocity_x,agent.Velocity_y)
        return agent
    
    
    #update and draw agents
    def update_couzin(agents,foods, predators,winWidth, winHeight, window):
            # Velocity update
            for agent  in agents:
                neigbour_matrix = neigbour_in_zones(agent, agents)
                agent.tempV = updateV_final(agent, neigbour_matrix, foods, predators)
            
            # move, draw
            for agent in agents:
                # alpha = calc_angle(agent[1], agent[2],agent.tempV[0],agent[4][1])
                
    	    # test if in ragne of agent.turn_angle,
    	    # if true, set velocity == new velocity
    	    # else rotate angle by maxTurn in
    	    # direction of new direction
                radTurn = math.radians(agent.turn_angle)
                negRadTurn = math.radians(360-agent.turn_angle)
    
                angle_old = math.atan2(agent.Velocity_y, agent.Velocity_x)
                angle_new = math.atan2(agent.tempV[1], agent.tempV[0])
                alpha = math.degrees(angle_old - angle_new)
    
                if abs(alpha) > 180:
                    if alpha < 0:
                        alpha += 360
                    else:
                        alpha -= 360
    
                if abs(alpha)<agent.turn_angle:
                    agent.Velocity_x = agent.tempV[0]
                    agent.Velocity_y = agent.tempV[1]
                elif alpha < 0:
                    agent.Velocity_x =  agent.Velocity_x * math.cos(radTurn) - agent.Velocity_y  * math.sin(radTurn)
                    agent.Velocity_y =  agent.Velocity_x * math.sin(radTurn) + agent.Velocity_y  * math.cos(radTurn)
                else:
                    agent.Velocity_x =  agent.Velocity_x * math.cos(negRadTurn) - agent.Velocity_y  * math.sin(negRadTurn)
                    agent.Velocity_y =  agent.Velocity_x * math.sin(negRadTurn) + agent.Velocity_y  * math.cos(negRadTurn)
    
    		# normalise dirction vector to 1, and multiply by constant speed
                agent.Velocity_x = agent.Velocity_x/absvec(agent.Velocity_x, agent.Velocity_y)  * agent.speed
                agent.Velocity_y = agent.Velocity_y/absvec(agent.Velocity_x, agent.Velocity_y)  * agent.speed
                agent = checkBoundary(agent, winWidth, winHeight)
    
    		# draw arrow
                if visual:
                    agent.drawLine()
            return agents
    
    #update and draw predator
    def update_predator(predator, agents, winWidth, winHeight, window):
    
        predator.tempV = check_prey(predator, agents)
    
        # test if in ragne of agent.turn_angle,
        # if true, set velocity == new velocity
        # else rotate angle by maxTurn in
        # direction of new direction
    
        radTurn = math.radians(predator.turn_angle)
        negRadTurn = math.radians(360-predator.turn_angle)
    
        angle_old = math.atan2(predator.Velocity_y, predator.Velocity_x)
        angle_new = math.atan2(predator.tempV[1], predator.tempV[0])
        alpha = math.degrees(angle_old - angle_new)
    
        if abs(alpha) > 180:
            if alpha < 0:
                alpha += 360
            else:
                alpha -= 360
    
        if abs(alpha)<predator.turn_angle:
            predator.Velocity_x = predator.tempV[0]
            predator.Velocity_y = predator.tempV[1]
        elif alpha < 0:
            predator.Velocity_x =  predator.Velocity_x * math.cos(radTurn) - predator.Velocity_y  * math.sin(radTurn)
            predator.Velocity_y =  predator.Velocity_x * math.sin(radTurn) + predator.Velocity_y  * math.cos(radTurn)
        else:
            predator.Velocity_x =  predator.Velocity_x * math.cos(negRadTurn) - predator.Velocity_y  * math.sin(negRadTurn)
            predator.Velocity_y =  predator.Velocity_x * math.sin(negRadTurn) + predator.Velocity_y  * math.cos(negRadTurn)
    
        # normalise diection vector to 1, and multiply by constant speed
        predator.Velocity_x = predator.Velocity_x/absvec(predator.Velocity_x, predator.Velocity_y)  * predator.speed
        predator.Velocity_y = predator.Velocity_y/absvec(predator.Velocity_x, predator.Velocity_y)  * predator.speed
        predator = checkBoundary(predator, winWidth, winHeight)
    
        # draw arrow
        if visual:
            predator.drawLine()
        return predator
    
    
    # for choosing parent
    def generateWheel(agents):
        """
        foodsum = 0
        for agent in agents:
            foodsum += agent.foodlevel
        """
        wheel = []
        currentsum = 0
        for agent in agents:
            currentsum += agent.foodlevel
            wheel.append(currentsum)
        return wheel
    
    # chooses parent to mutate
    def pickParent(agents, wheel):
        r = random.randrange(wheel[-1]) +1
    
        for i in range(len(wheel)):
            if r <= wheel[i]:
                return agents[i]
    
    # greates a new agent, and assinges random values close to those of the parent
    def mutate(parent):
    
        point = Point(random.uniform(0,winWidth/2), random.uniform(0,winHeight/2))
        child = Agent(point, window)
    
        child.Velocity_x = random.uniform(-1, 1)
        child.Velocity_y = random.uniform(-1, 1)
    
        child.zoa_r = random.uniform(parent.zoa_r - m_zoa_r, parent.zoa_r + m_zoa_r )
        child.zoa_r = max (child.zoa_r, math.sqrt(As/(2*math.pi)) )
    
        child.zoo_r = random.uniform(parent.zoo_r - m_zoo_r, parent.zoo_r + m_zoo_r)
        child.zoo_r = min( child.zoa_r , max(child.zoo_r, child.zor_r))
    
        child.speed = random.uniform(parent.speed - m_speed, parent.speed + m_speed)
        child.speed = min( 5 , max(child.speed, 1))
    
        child.blind_angle = (360 - math.degrees(As/(child.zoa_r**2)) ) / 2
        child.turn_angle = math.degrees(Am/(2*(child.speed**2)))
    
        child.food_pref = random.uniform(parent.food_pref - m_food, parent.food_pref + m_food)
        child.anti_pred = random.uniform(parent.anti_pred - m_pred, parent.anti_pred + m_pred)
    
        child.noise = random.uniform(parent.noise - m_noise, parent.noise + m_noise)
    
        return child
    
    # picks parents, creates new agents with mutated values,
    # returns them in a new agents list
    def nextGen_food(agents):
        wheel = generateWheel(agents)
        tempAgents = []
    
        for i in range(agentNum):
            if wheel[-1] == 0:
                parent = pickParent_simple_random(agents)
            else:
                parent = pickParent(agents, wheel)
            child = mutate(parent)
            tempAgents.append(child)
    
        return tempAgents
    
    
    #----------new generation for predator simulation
    def pickParent_simple_random(agents):
        r = random.randrange(len(agents))
        return agents[r]
    
    # picks parents, creates new agents with mutated values,
    # returns them in a new agents list
    def nextGen_pred(agents):
        tempAgents = []
    
        for i in range(agentNum):
            parent = pickParent_simple_random(agents)
            child = mutate(parent)
            tempAgents.append(child)
    
        return tempAgents
    
    # ------------main------------------------
    def simulate():
        # zones for couzin, vicsek
        # radii of zones
        # swarm: 10, 20, 200
        # torus: 5, 60, 200
        # dynamic parallel group: 5, 100, 200
        # highly parallel group: 5, 180, 200
        agents = []
        foods = []
        predators = []
    
        with open('data.csv','w') as csvfile:
            filewriter = csv.writer(csvfile, delimiter=',',quotechar='|',quoting = csv.QUOTE_MINIMAL)
            filewriter.writerow(["Iterations","Speed","turn","food pref","zoa","zoo","blind","noise","antipred"])
    
    
        widthTemp = winWidth
        heightTemp = winHeight
    
        maxLife = 1000
    
        global window
    
        # first generation , random
        for i in range (agentNum):
            agent = Agent(Point(random.uniform(0,winWidth/2), random.uniform(0,winHeight/2)) , window)
            agents.append(agent.create_random_agent())
    
    
        for j in range(generations):
            if isPred or Both:
                for i in range(predNum):
                    predator = Predator(Point(random.uniform(0,winWidth), random.uniform(0,winHeight)) , window)
                    predators.append(predator.create_random_predator())
    
            # -----ausgabe------
            print ("generation " + str(j))
    
            avgSpeed = 0
            avgTurn = 0
            avgFood = 0
            avgPred = 0
            avgZOA = 0
            avgZOO = 0
            avgBlind = 0
            avgNoise = 0
    
            for agent in agents:
                avgSpeed += agent.speed
                avgPred += agent.anti_pred
                avgTurn += agent.turn_angle
                avgFood += agent.food_pref
                avgZOA += agent.zoa_r
                avgZOO += agent.zoo_r
                avgBlind += agent.blind_angle
                avgNoise += agent.noise
    
            avgSpeed /= agentNum
            avgTurn /= agentNum
            avgFood /= agentNum
            avgZOA /= agentNum
            avgZOO /= agentNum
            avgBlind /= agentNum
            avgNoise /= agentNum
            avgPred /= agentNum
    
            #("speed: " +str(avgSpeed))
            #print ("turn: " +str(avgTurn))
            #print ("food pref: " +str(avgFood))
            #print ("zoa: " +str(avgZOA))
            #print ("zoo: " +str(avgZOO))
            #print ("blind: " +str(avgBlind))
            #print ("noise: "+str(avgNoise))
            #print ("antipred: " + str(avgPred))
    
            with open('data.csv','a') as csvfile:
                filewriter = csv.writer(csvfile, delimiter=',',quotechar='|',quoting = csv.QUOTE_MINIMAL)
                filewriter.writerow([j,avgSpeed,avgTurn,avgFood,avgZOA,avgZOO,avgBlind,avgNoise,avgPred])
    
            
            # -----ausgabe ende------
    
            #if visual:
            #   for agent in agents:
            #       agent.point.undraw()
            #       agent.point.draw(window)
        
    
            if isFood or Both:
                widthTemp = winWidth/2
                heightTemp = winHeight/2
            else:
                widthTemp = winWidth
                heightTemp = winHeight
    
            #timeStep = 0    
            for timeStep in range(maxTime):
    
                # generate food and release agents
                if timeStep == maxTime * 0.025 and (isFood or Both):
                    foods = generate_food(widthTemp, heightTemp)
                    
                    widthTemp = winWidth
                    heightTemp = winHeight
    
                # exit generation if enough food has been eaten
                if timeStep >= maxTime * 0.025 and isFood:
                    if len(foods) <= 1.0/8 * clusterSize * foodCluster:
                        #print ("done eating")
                        break
    
                # start predating
                if timeStep >= maxTime * 0.025 and (isPred or Both):
                    if predators == []:
                        #print ("preds are done")
                        break
                    else:
                        if(predators[-1].hasEaten or predators[-1].lifeTime >= maxLife):
                            print ("hasEaten")
                            if visual:
                                predators[-1].line.undraw()
    
                            predators.pop()
                        else:
                            predators[-1] = update_predator(predators[-1], agents, winWidth, winHeight, window)
                            predators[-1].lifeTime += 1
    
                # update agents
                agents = update_couzin(agents, foods, predators, widthTemp, heightTemp, window)
    
                #if visual:
                #   time.sleep(0.01*t)
    
            print ("eating time: " + str(i))
    
            # new windos + new generation
            if visual:
                window.close()
                window = GraphWin("Window", winWidth, winHeight)
            if isFood or Both:
                agents = nextGen_food(agents)
            elif isPred:
                agents = nextGen_pred(agents)
    
    
    simulate()