Modeling Bunny&Wolf Population
The goal was to create a simulation modeled after populations of rabbits and wolves in the wild. The rabbit population, if left uncheck, grows exponentially, reproducing within seconds of contact with each other. Bunnies are set to die after reproducing 3 times.
Set bunnies with “r” and wolves with “w”, then SPACE to begin simulation.
Wolves exhibit hunting behavior by speeding up when within proximity to a rabbit. When a wolf successfully catches a rabbit, it eats it, and the rabbit dies.
Running the simulation several times, it becomes apparent that wolves are quite adept at reducing rabbit populations, as long as there are 6+ wolves.
Who will win in the battle for survival largely depends on the starting populations of each species.
Semester project summary: https://medium.com/@jaybuns/semester-project-ideas-b8cc69fc6eaf
import random
import mathxMax = 1500
yMax = 1500class Rabbit:
def __init__(self, xPos, yPos, startSim=False):
self.xPos = xPos
self.yPos = yPos
self.repNum = 0
self.startSim = startSim
self.speed = random.randint(5,10)
self.direction = random.uniform(0, PI*2)
def display(self):
#img needs resizing
image(bunImg, self.xPos, self.yPos, 50, 75)
if self.startSim == True:
self.xPos = self.xPos + self.speed * cos(self.direction) + random.randint(-10,10)
self.yPos = self.yPos + self.speed * sin(self.direction) + random.randint(-10,10)
if self.xPos >= xMax:
self.xPos = 0
elif self.xPos <= 0:
self.xPos = xMax
if self.yPos >= yMax:
self.yPos = 0
elif self.yPos <= 0:
self.yPos = yMax
def beginSim(self):
self.startSim = True
def reproduce(self):
self.repNum += 1def changeDir(self, wolf):
self.direction = math.atan((self.yPos-wolf.yPos)/(self.xPos-wolf.xPos+1)) if (self.xPos-wolf.xPos) == 0 else math.atan((self.yPos-wolf.yPos)/(self.xPos-wolf.xPos+1))
self.speed = 10
class Wolf:
def __init__(self, xPos, yPos, startSim=False):
self.xPos = xPos
self.yPos = yPos
self.bunSnack = 0
self.startSim = startSim
self.speed = random.randint(5, 10)
self.direction = random.uniform(0, PI*2)
def display(self):
#img needs resizing
image(wolfImg, self.xPos, self.yPos, 100, 110)
if self.startSim == True:
self.xPos = self.xPos + self.speed * cos(self.direction) + random.randint(-10,10)
self.yPos = self.yPos + self.speed * sin(self.direction) + random.randint(-10,10)
if self.xPos >= xMax:
self.xPos = 0
elif self.xPos <= 0:
self.xPos = xMax
if self.yPos >= yMax:
self.yPos = 0
elif self.yPos <= 0:
self.yPos = yMax
def eatBun(self):
self.bunSnack += 1
def chase(self, rabbit):
self.direction = math.atan((rabbit.yPos-self.yPos)/(rabbit.xPos-self.xPos+1)) if (rabbit.xPos-self.xPos) == 0 else math.atan((rabbit.yPos-self.yPos)/(rabbit.xPos-self.xPos+1))
self.speed = 15
def beginSim(self):
self.startSim = TruebunList = []
wolfList = []maxBun = 100
maxWolf = 3def setup():
size(xMax, yMax)
global bunImg
global wolfImg
global plantImg, groundImg, rockImg
bunImg = loadImage('bunimg.png')
wolfImg = loadImage('wolfimg.png')
rockImg = loadImage('rock.png')
plantImg = loadImage('plant.png')
groundImg = loadImage('ground.png')def keyPressed():
if key == 'w':
new_wolf = Wolf(mouseX, mouseY)
wolfList.append(new_wolf)
elif key == 'r':
new_bun = Rabbit(mouseX, mouseY)
bunList.append(new_bun)
elif key == ' ':
for wolf in wolfList:
wolf.beginSim()
for rabbit in bunList:
rabbit.beginSim()
def gradient():
noStroke()
g = color(30,73,91)
y = color(103,181,139)
gradientSteps = 100 #how detailed will the gradient be
gradientStripWidth = height/gradientSteps
i = 0
while i < gradientSteps:
i+=1
t = map(i,0,gradientSteps,0.0,1.0);
interpolatedColor = lerpColor(g,y,t);
fill(interpolatedColor)
rect(i*gradientStripWidth,0,gradientStripWidth,height)def environ():
for p in range(width):
for q in range (height):
if q%2 == 0:
image(plantImg, p*300+100, q*200+100, 100, 100)def draw():
background(106, 155, 51)
gradient()
#environ()
for wolf in wolfList:
wolf.display()
for rabbit in bunList:
rabbit.display()
bunPair()
bunChase()
bunEat()
print 'bun count: ', len(bunList)
print 'wolf count: ', len(wolfList)def bunPair():
toRemove = []
newBuns = []
for r_i in range(len(bunList)):
for b_i in range(r_i+1, len(bunList)):
r = bunList[r_i]
b = bunList[b_i]
if abs(r.xPos - b.xPos) < 10 and abs(r.yPos - b.yPos) < 10 and len(bunList) < maxBun: #finding spatial conditions for reproduction
r.reproduce() #+1 reproduction count
b.reproduce()
babyBun = Rabbit((r.xPos + b.xPos)/2, (r.yPos + b.yPos)/2, startSim=True) #create baby bunny with location midpoint of first 2
r.xPos = random.randint(0, xMax)
r.yPos = random.randint(0, yMax)
b.xPos = random.randint(0, xMax)
b.yPos = random.randint(0, yMax)
newBuns.append(babyBun) #adding new bunny to rabbit list
if r.repNum > 3: #condition for deleting bun
toRemove.append(r_i)
if b.repNum > 3:
toRemove.append(b_i)
for deceasedBun_i in sorted(toRemove, reverse=True):
bunList.pop(deceasedBun_i)
bunList.extend(newBuns)
def bunChase():
toRemove = []
for w_i in range(len(wolfList)):
for r_i in range(len(bunList)):
w = wolfList[w_i]
r = bunList[r_i]
if abs(w.xPos - r.xPos) < 30 and abs(w.yPos - r.yPos) < 30: #finding spatial conditions for reproduction
w.chase(r)
r.changeDir(w)
def bunEat():
toRemoveBun = []
toRemoveWolf = []
newWolves = []
for w_i in range(len(wolfList)):
for r_i in range(len(bunList)):
w = wolfList[w_i]
r = bunList[r_i]
if abs(w.xPos - r.xPos) < 10 and abs(w.yPos - r.yPos) < 10: #finding spatial conditions for reproduction
w.eatBun()
toRemoveBun.append(r_i)
if w.bunSnack > 3:
toRemoveWolf.append(w_i)
babyWolf = Wolf(w.xPos + random.randint(-50, 50), w.yPos + random.randint(-50, 50), startSim=True)
newWolves.append(babyWolf)
for deceasedBun_i in sorted(toRemoveBun, reverse=True):
bunList.pop(deceasedBun_i)
for deceasedWolf_i in sorted(list(set(toRemoveWolf)), reverse=True):
wolfList.pop(deceasedWolf_i)
wolfList.extend(newWolves)