# Python Game of Rat and Berry

## Python Game of Rat and Berry

Once upon a time, there was an island…

• The island is 10 sq km in area.
• Every day there is a 30% chance it will rain on the island.
• When it rains, the rainfall has a normal distribution with a mean of 20 mm and a standard deviation of 5 mm.
• Rain nourishes the local plant life. The day after it rains, the plants will produce berries. The number of berries produced is equal to (previous day’s rainfall in mm) * (area of the island in sq km) * (100).
• Berries persist for 10 days after which they become inedible.

On the island there were rats...

• Initially, there are 10,000 rats on the island with ages randomly chosen in the range 1 through 20 days (uniform and inclusive).
• Every day a rat will eat a berry (randomly chosen regardless of age) if one is available somewhere on the island.
• If a rat does not eat for 3 days, it dies.
• After 50 days, the rat has a 5% chance of dying from old age. This probably increases by 5% every day thereafter (e.g. 5% after 50 days, 10% after 51 days, 15% after 52 days, etc.).
• After a rat eats a total of 10 berries and every 8 berries thereafter, it will give birth to a litter of new rats. The litter size is random and uniformly distributed between 6 and 10 inclusive.

On the island, there were also cats…

• Initially, there are 1000 cats on the island with ages randomly chosen in the range of 1 through 1000 days (uniform and inclusive).
• Every day a cat will attempt to eat a rat. The probability that a cat will catch a rat is dependent on the density of rats on the island: p = (number of rats/area of the island in sq km) * 0.10. Notice that this probability should be capped at 100%.
• With experience, cats become better at catching rats. A cat receives an additive bonus to its probability of catching a rat: b = age of cat * 0.015. Again, the total probability should be capped.
• If a cat does not eat for 5 days, it dies.
• After 2000 days, the cat has a 1% chance of dying from old age. This probably increases by 0.1% every day thereafter.
• After a cat eats a total of 50 rats and every 35 rats thereafter, it will give birth to a litter of new cats.
• The litter size is random and uniformly distributed between 3 and 6 inclusive.

Then, ten thousand days later…

• Design a simulation to capture the interaction of life on the island over 10,000 days.
• Your simulation should begin by reading parameters from a parameter file. This file should include all of the numbers in marked bold above. For example…
• island_size = 10 o rain_chance = 0.30
• rain_mean = 20
• rain_std = 5
• berry_ coefficient = 100
• berry_persist = 10 etc.

Use classes

• Save to file information about the rainfall and the daily population of berries, rats, and cats.
 Subject Value island_size 10 rain_chance 0.3 rain_mean 20 berry_coefficient 100 rain_std 5 berry_persist 10 num_of_rats 10000 rat_coefficient 3 rat_range 20 rat_total_berries 10 rat_days 50 berry_after 8 uniform_dist_start 6 uniform_dist_end 10 num_of_cats 1000 max_cat_age 1000 cat_rat_catch_prob 0.1 exp_prob 0.015 cat_days_die 2000 cat_rat_eat 50 cat_rat_additional 35 litter_dist_start 50 litter_dist_end 35

`# -*- coding: utf-8 -*-import pandas as pdfrom numpy import randomimport numpy as npratList = []catList = []berriesBasket = []def readFile():    'function to read a file that consist of many variables for our program'            #use pandas read_csv function to read the variable names and values    #as a dictionary    dictD = pd.read_csv("data.csv", header=0, index_col=0, squeeze=True).to_dict()        for key,val in dictD.items():        islandSize = dictD['island_size']        rainChance = dictD['rain_chance']        rainMean = dictD['rain_mean']        berryCoeff = dictD['berry_coefficient']        rainStd = dictD['rain_std']        berryPersist = dictD['berry_persist']        numRats = dictD['num_of_rats']        ratCoeff = dictD['rat_coefficient']        ratRange = dictD['rat_range']        ratTotalBerries = dictD['rat_total_berries']        ratDays = dictD['rat_days']        berryAfter = dictD['berry_after']        uniformDistStart = dictD['uniform_dist_start']           uniformDistEnd = dictD['uniform_dist_end']         numCats = dictD['num_of_cats']         maxCatAge = dictD['max_cat_age']         catRatCatchProb = dictD['cat_rat_catch_prob']         expProb = dictD['exp_prob']         catDaysDie = dictD['cat_days_die']         catRatEat = dictD['cat_rat_eat']           catRatAdd = dictD['cat_rat_additional']         litterDistStart = dictD['litter_dist_start']         litterDistEnd = dictD['litter_dist_end']                                return islandSize,rainChance,rainMean,berryCoeff,rainStd,berryPersist,numRats,ratCoeff,ratDays,ratRange,ratTotalBerries,berryAfter,uniformDistStart,uniformDistEnd,numCats,maxCatAge,catRatCatchProb,expProb,catDaysDie,catRatEat,catRatAdd,litterDistStart,litterDistEnd# getraindef rain():    'function to determine if it rains'        # generate a number from 1-100, if 100 is less than 30    # then it will rain    if random.rand() < float(readFile()[1]) :        return 0        # if it rains, how much will it rain    return random.normal(float(readFile()[2]),float(readFile()[4]), size=(1, 1))[0][0]    def generateRat():    """ Initialize the rats in the island """    num_rat = int(readFile()[6])    for i in range(num_rat):        rat = Rats(random.randint(0, num_rat))        ratList.append(rat)def generateCat():    """ Initilaze the cat in the island """    num_cat = int(readFile()[14])    for _ in range(0, num_cat):        cat = Cats(random.randint(0, num_cat))        catList.append(cat)def deleteDeadObject():    """ In case rat or cat is dead. Need to remove them all"""    for berry in berriesBasket:        if not berry.isEatable():            berriesBasket.remove(berry)    for rat in ratList:        if rat.isDead():            ratList.remove(rat)    for cat in catList:        if cat.isDead():            catList.remove(cat)# class for ratsclass Rats :    'class that represents a rat that inherits from Island'    def __init__(self, age):                #define the constructor variables        self.ratsBirth_initBerries = int(readFile()[5])        self.numRats = int(readFile()[6])        self.ratCoeff = int(readFile()[7])        self.ratDays = int(readFile()[8])        self.ratRange = int(readFile()[9])        self.ratTotalBerries = int(readFile()[10])        self.berryAfter = int(readFile()[11])        self.uniformDistStart = int(readFile()[12])        self.uniformDistEnd = int(readFile()[13])        self.ratsBeginAge = int(readFile()[19])        self.days = age        self.eatDaysAgo = 0        self.berriesEaten = 0    def passDay(self):        self.days += 1        self.eatDaysAgo += 1    def tryEat(self):        berriesNum = len(berriesBasket)        if berriesNum > 0:            r = random.randint(0, berriesNum)            self.eatDaysAgo = 0            self.berriesEaten += 1            del berriesBasket[r]        def isDead(self):        """ simulate rats dead """        if self.eatDaysAgo >= 3:            return True        if self.days > self.ratTotalBerries and (random.rand() < 0.01 * 0.05 * (self.days - 49)):            return True        return False                   def givingBirth(self):        """ Simulate rat birth """        if self.berriesEaten < self.ratsBirth_initBerries:            return        if (self.berriesEaten - self.ratsBirth_initBerries) % self.berryAfter == 0:            ratsBorn = random.randint(self.uniformDistStart, self.uniformDistEnd + 1)            for r in range(1, ratsBorn):                ratList.append(Rats(0))        #class for catsclass Cats:    'class that represents a cat'    def __init__(self, age):                #define the constructor variables        self.islandArea = int(readFile()[0])        self.numCats = int(readFile()[14])        self.maxCatAge = int(readFile()[15])        self.catchProb = float(readFile()[16])        self.expProb = float(readFile()[17])        self.catDaysDie = int(readFile()[18])        self.catRatEat = int(readFile()[19])        self.catAdditional = int(readFile()[20])        self.litterSizeStart = int(readFile()[21])        self.litterSizeEnd = int(readFile()[22])        self.days = age        self.eatDaysAgo = 0        self.ratsEaten = 0    def passDay(self):        self.days += 1        self.eatDaysAgo += 1    def tryEat(self):        """ Simulate eat rats """        ratsNum = len(ratList)        if ratsNum > 0 and(random.rand() < (self.catchProb * ratsNum) / self.islandArea + self.days * 5):            r = random.randint(0, ratsNum)            self.eatDaysAgo = 0            self.ratsEaten += 1            del ratList[r]    def isDead(self):        """ Simulate Cat is dead"""        if self.eatDaysAgo >= 5: # no eat in 5 days.            return True        if self.days > self.catDaysDie and (random.rand() < 0.01 * (self.expProb + self.catchProb * (self.days - self.catDaysDie))):                return True        return False    def givingBirth(self):        """ Simulate cat birth """        if self.ratsEaten < self.catRatEat:             return        if (self.ratsEaten - self.catRatEat) % self.catAdditional == 0:            rats_born = random.randint(self.litterSizeEnd, self.litterSizeStart + 1)            for k in range(0, rats_born):                catList.append(Cats(0))class Berry:    def __init__(self):        self.ageDays = 0        self.berryPersist = int(readFile()[5])    def isEatable(self):        return self.ageDays <= self.berryPersist    def passDay(self):        self.ageDays += 1def simulation():    """ Simulation the assignment """    rainn = int(0)    generateRat()    generateCat()    daysLimit = 10000    islandArea = int(readFile()[0])    berryCoeff = float(readFile()[3])    for i in range(1, daysLimit):        newBerries = int(rainn * islandArea * berryCoeff)         for berry in range(1, newBerries):            berriesBasket.append(Berry())        for berry in berriesBasket:            berry.passDay()        for rat in ratList:            rat.tryEat()            rat.givingBirth()            rat.passDay()        for cat in catList:            cat.tryEat()            cat.givingBirth()            cat.passDay()        rainn = rain()        deleteDeadObject()def main():    simulation()    daysLimit = 10000    print("Simulator in {} days".format(str(daysLimit)))    print("Berries population: {} ea".format(str(len(berriesBasket))))    print("Rats population: {} ea".format(str(len(ratList))))    print("Cats population: {} ea".format(str(len(catList))))    out = open("output.txt", "w")    out.write("Simulator in " + str(daysLimit) + "days\n")    out.write("Berries population: " + str(len(berriesBasket)) + "\n")    out.write("Rats population: " + str(len(ratList)) + "\n")    out.write("Cats population: " + str(len(catList)) + "\n")    out.close()if __name__ == "__main__":    main()`