import numpy as np
import random
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.colors import LogNorm
import matplotlib.colors as cc
from matplotlib.colors import ListedColormap
WOLFCOUNT = 10
SHEEPCOUNT = 30
WOLFENERGYSTART = 200.0
WOLFENERGY = 10
WOLFMOVECOST = 1
WOLFLINGLEVEL = 50
SHEEPLINGPROB = 0.04
colors = cc.ColorConverter.colors
cols = [colors['w'],
colors['r']]
acolors = ListedColormap(cols)
def von_neuman_neighbors(i, j, size):
n = []
if i > 0:
n.append((i - 1, j))
if j > 0:
n.append((i, j - 1))
if i < size - 1:
n.append((i + 1, j))
if j < size - 1:
n.append((i, j + 1))
return n
def moore_neighbors(i, j, size):
n = []
if i > 0:
n.append((i - 1, j))
if j > 0:
n.append((i - 1, j - 1))
if j < size - 1:
n.append((i - 1, j + 1))
if j > 0:
n.append((i, j - 1))
if i < size - 1:
n.append((i + 1, j))
if j > 0:
n.append((i + 1, j - 1))
if j < size - 1:
n.append((i + 1, j + 1))
if j < size - 1:
n.append((i, j + 1))
return n
class Agent():
def __init__(self, x, y, world, color):
self.x = x
self.y = y
self.world = world
self.color = color
def wander(self):
n = von_neuman_neighbors(self.x, self.y, self.world.size)
self.x, self.y = random.choice(n)
def update(self):
pass
class Wolf(Agent):
def __init__(self, x, y, world, energy):
Agent.__init__(self, x, y, world, 1)
self.energy = energy
def update(self):
self.wander()
self.energy -= 0.5
if self.energy >= WOLFLINGLEVEL:
self.world.wolves.append(Wolf(self.x, self.y, self.world, self.energy / 2))
self.energy /= 2
elif self.energy <= 0:
self.world.wolves.remove(self)
else:
for s in self.world.sheep:
if self.x == s.x and self.y == s.y:
self.energy += WOLFENERGY
self.world.sheep.remove(s)
break
class Sheep(Agent):
def __init__(self, x, y, world):
Agent.__init__(self, x, y, world, 0)
def update(self):
self.wander()
if (np.random.random() < SHEEPLINGPROB):
self.world.sheep.append(Sheep(self.x, self.y, self.world))
class CA():
states = {"EMPTY":0, "GRASS":1}
def __init__(self, size):
self.size = size
self.x = np.arange(size)
self.y = np.arange(size)
self.cells = np.zeros((size, size))
self.time = 0
self.wolves = []
for w in range(WOLFCOUNT):
i, j = np.random.random_integers(0, size, 2)
self.wolves.append(Wolf(i, j, self, WOLFENERGYSTART))
self.sheep = []
for s in range(SHEEPCOUNT):
i, j = np.random.random_integers(0, size, 2)
self.sheep.append(Sheep(i, j, self))
def random_setup(self, n):
for i in range(n):
a, b = np.random.random_integers(0, size - 1, 2)
self.cells[a, b] = CA.states["GRASS"]
def image_setup(self):
self.plt = plt.imshow(self.cells, interpolation='nearest',
origin='bottom',
vmin=np.min(0),
vmax=np.max(1),
cmap=plt.cm.winter)
ax = []
ay = []
ac = []
for a in self.wolves:
ax.append(a.x)
ay.append(a.y)
ac.append(a.color)
for f in self.sheep:
ax.append(f.x)
ay.append(f.y)
ac.append(f.color)
self.ant_plot = plt.scatter(ax, ay, c=ac, s=60, cmap=acolors)
def update(self):
for a in self.wolves:
a.update()
for a in self.sheep:
a.update()
self.time += 1
def plot(self):
self.plt.set_data(np.transpose(self.cells))
ap = []
ac = []
for a in self.wolves:
ap.append((a.x, a.y))
ac.append(a.color)
for f in self.sheep:
ap.append((f.x, f.y))
ac.append(f.color)
self.ant_plot.set_offsets(ap)
ac = np.array(ac)
self.ant_plot.set_array(ac)
return self.plt, self.ant_plot
size = 40
fig, ax = plt.subplots()
ax.set_ylim(-1, size)
ax.set_xlim(-1, size)
ca = CA(size)
ca.image_setup()
#ca.random_setup(100)
numsheep = []
numwolves = []
time = []
def update(data):
ca.update()
#ca.random_setup(50)
time.append(ca.time)
numsheep.append(len(ca.sheep))
numwolves.append(len(ca.wolves))
return ca.plot(),
def data_gen():
while True: yield 1
ani = animation.FuncAnimation(fig, update, data_gen, blit=False, interval=40)
plt.show()