Write a Python class and methods to simulate a neighborhood
containing two
types of animals, Dogs and Cats. The neighborhood consists of a
large list of
locations. Each element of the list should be a Dog object, a Cat
object, or None.
In each time step, based on a random process, each animal either
attempts to
move into a random empty (i.e., previously None) location or stay
where it is. If
two animals of the same type are about to collide in the same
location, then they
stay where they are, but they create a new instance of that type of
animal, which
is placed in the collision location in the list. If a Dog and a Cat
collide, however,
then the Cat escapes to the closest empty location in the list.
Each animal is
assigned a random amount of life span (between 1 to 10 time steps),
after which
it dies.
Simulate a neighborhood of 50 locations, with initially 10 dogs and
10 cats, for
100 time steps. Print the neighborhood, total number of cats and
dogs after each
10 time step.
CODE:
import random
# Animal class to store a cat or dog
class Animal:
# constructor
def __init__(self, type = '', lifespan = 0, nextmove = None):
self.type = type
self.lifespan = lifespan
# function to print the value of animal
def printVal(self):
print('(', self.type, ',', self.lifespan, ')', end = "; "),
# get next move of an animal
def getNextMove(self, neighbourhood):
# decrease lifespan
self.lifespan = self.lifespan - 1
# first choose to move or not
choice = random.random()
# move
if(choice <= 0.5):
# get a random empty position
while(True):
index = random.randrange(0, 50)
if(neighbourhood[index] == None):
return index
else: # do not move
return -1
# function to print neighbourhood
def printN(neighbourhood):
for i in range(0, 50):
if(neighbourhood[i] == None):
print(neighbourhood[i], end = "; ")
else:
neighbourhood[i].printVal()
print()
def getNearestEmpty(neighbourhood, pos):
itr = 1
# iteratively move to the next steps
while(True):
if((pos-itr)>=0 and neighbourhood[pos-itr] == None):
return (pos-itr)
if((pos+itr)<=49 and neighbourhood[pos+itr] == None):
return (pos+itr)
itr = itr + 1
def getCount(neighbourhood):
count = 0
for i in range(0, 50):
if(neighbourhood[i] != None):
count = count + 1
return count
# neighbourhood with 5 locations
neighbourhood = [None] * 50
# put 10 dogs
for i in range(0, 10):
# generate lifespan
lifespan = random.randrange(0, 10) + 1
# get an empty location
while(True):
index = random.randrange(0, 50)
if(neighbourhood[index] == None):
dog = Animal('Dog', lifespan)
neighbourhood[index] = dog
break
# put 10 cats
for i in range(0, 10):
# generate lifespan
lifespan = random.randrange(0, 10) + 1
# get an empty location
while(True):
index = random.randrange(0, 50)
if(neighbourhood[index] == None):
dog = Animal('Cat', lifespan)
neighbourhood[index] = dog
break
print("intial ---------------------------------------")
printN(neighbourhood)
# simulate for 100 steps
for k in range(0, 100):
# check for dead animals
for i in range(0, 50):
if(neighbourhood[i] == None):
continue
if(neighbourhood[i].lifespan == 0):
neighbourhood[i] = None
# if neighbourhood is empty
if(getCount(neighbourhood) == 0):
print('Empty neighbourhood after', k, 'time steps')
break
# cannot move if neighbourhood is full
if(getCount(neighbourhood) >= 50):
# decrease lifespan of every animal
for i in range(0, 50):
neighbourhood[i].lifespan = neighbourhood[i].lifespan - 1
# go to next time step
continue
# for each step
# get next moves for each animal in neighbourhood
# store next moves
next_moves = [-1] * 50
for i in range(0, 50):
# skip if empty
if(neighbourhood[i] == None):
continue
next_moves[i] = neighbourhood[i].getNextMove(neighbourhood)
# now that next moves are calculated
# check for collisions and move the animals
for i in range(0, 50):
if(next_moves[i] == -1):
continue
# check for a collision
for j in range(0, 50):
if(neighbourhood[j]!=None and i!=j and
next_moves[i]==next_moves[j]):
index = next_moves[i]
# if both are same type
if(neighbourhood[i].type == neighbourhood[j].type):
if(getCount(neighbourhood) < 50):
# create new animal of the same type
lifespan = random.randrange(0, 10) + 1
animal = Animal(neighbourhood[i].type, lifespan)
neighbourhood[index] = animal
# do not move the present animals
next_moves[i] = -1
next_moves[j] = -1
break
else: # cat vs dog
# dog remains at that position
# move cat
if(neighbourhood[i].type == 'Cat'):
next_moves[i] = getNearestEmpty(neighbourhood, index)
break
else:
next_moves[j] = getNearestEmpty(neighbourhood, index)
# now that collisions are checked, move the animals
for i in range(0, 50):
if(next_moves[i] == -1):
continue
neighbourhood[next_moves[i]] = neighbourhood[i]
neighbourhood[i] = None
if((k+1)%10 == 0):
# print after 10 steps
print("After", k+1, "steps
---------------------------------------")
printN(neighbourhood)
Output Snapshot:

Write a Python class and methods to simulate a neighborhood containing two types of animals, Dogs...