Quantcast
Viewing latest article 1
Browse Latest Browse All 5

Answer by fredtantini for Forest - A Simulated Ecosystem

Python

Nothing fancy. I kept on adding stuff, so refactoring might be in order. (And I didn't do unitest so bugs might still be present).

I gave random names to lumberjacks and bears.Trees are i, then I, then #,Lumberjacks are x,Bears are o

import osfrom random import randint, choice, shufflefrom time import sleepNGRID = 15SLEEPTIME = 0.0125DURATION = 4800VERBOSE = True###initgrid = [[[] for _ in range(NGRID)] for _ in range(NGRID)]#Money earned this yearn_lumbers = 0#Lumberjacks killed this yearn_maul = 0tick = 0events = []#total number ofd_total = {'trees':0,'lumberjacks': 0,'bears': 0,'cut': 0,'maul': 0,'capture': 0,'lumbers': 0,'fired': 0}d_oldest = {'tree': 0,'lumberjack': (0, ""),'bear': (0, "")}d_most = {'n_maul': (0, ""),'n_lumber': (0, ""),'n_cut': (0, "")}d_year = {'n_maul': 0,'n_lumber': 0}###Classesclass Tree(object):"""Represent a Sapling, Tree, or Elder Tree"""    def __init__(self, coords, m=0, t='Sapling'):        self.months = m        self.typeof = t        self.coords = coords    def grow(self, m=1):"""the tree grows 1 month and its type might change"""        self.months = self.months + m        if self.months == 12:            self.typeof = 'Tree'        elif self.months == 480:            self.typeof = 'Elder Tree'    def __str__(self):        if self.typeof == 'Sapling':            return 'i'        elif self.typeof == 'Tree':            return 'I'        else:            return '#'class Animated(object):"""Animated beings can move"""    def __init__(self, coords):        self.coords = coords        self.old_coords = None        self.months = 0    def where(self):        return c_neighbors(self.coords)    def choose_new_coords(self):        self.old_coords = self.coords        possible = self.where()        if possible:            direction = choice(self.where())            self.coords = [(self.coords[i]+direction[i]) % NGRID for i in range(2)]#    def __del__(self):#        print "died at "+ str(self.coords)class Lumberjack(Animated):"""Lumberjacks chop down trees"""    def __init__(self, coords):        super(Lumberjack, self).__init__(coords)        self.nb_cut = 0        self.nb_lumber = 0        self.name = gen_name("l")    def __str__(self):        return "x"class Bear(Animated):"""Bears maul"""    def __init__(self, coords):        super(Bear, self).__init__(coords)        self.nb_maul = 0        self.name = gen_name("b")    def where(self):        return c_land_neighbors(self.coords)    def __str__(self):        return "o"###list of coordsdef c_neighbors(coords):"""returns the list of coordinates of adjacent cells"""    return [[(coords[0] + i) % NGRID, (coords[1] + j) % NGRID] \            for i in [-1, 0, 1] \            for j in [-1, 0, 1] \            if (i,j) != (0, 0)]def c_empty_neighbors(coords):"""returns the list of coordinates of adjacent cells that are empty """    return [[i, j] for [i,j] in c_neighbors(coords) if grid[i][j] == []]def c_land_neighbors(coords):"""returns the list of coordinates of adjacent cells that contain not Trees    for bears"""    return [[i, j] for [i,j] in c_neighbors(coords)\            if (grid[i][j] == []) or (not isinstance(grid[i][j][0], Tree))]def c_empty_cells():"""returns list of coords of empty cells in the grid"""    return [[i, j] for i in range(NGRID) for j in range(NGRID) if grid[i][j] == []]def c_not_bear_cells():"""returns list of coords of cells without bear"""    return [[i, j] for i in range(NGRID) for j in range(NGRID) \            if not isinstance(grid[i][j], Bear)]###one lessdef maul(lumberjack):"""a lumberjack will die"""    global n_maul    n_maul = n_maul + 1    d_total['maul'] = d_total['maul'] + 1    remove_from_grid(lumberjack.coords, lumberjack)    return lumberjack.name +" is sent to hospital" + check_lumberjacks()def capture_bear():"""too many mauls, a Zoo traps a bear"""    d_total['capture'] = d_total['capture'] + 1    bear = choice(get_bears())    remove_from_grid(bear.coords, bear)    return bear.name +" has been captured"def fire_lumberjack():"""the job is not done correctly, one lumberjack is let go"""    d_total['fired'] = d_total['fired'] + 1    lumberjack = choice(get_lumberjacks())    remove_from_grid(lumberjack.coords, lumberjack)    return lumberjack.name +" has been fired" + check_lumberjacks()def remove_from_grid(coords, item):"""remove item from the grid at the coords"""    grid[coords[0]][coords[1]].remove(item)    del item###one moredef new_animate(class_):"""a new lumberjack or bear joins the forest"""    if class_==Bear:        d_total['bears'] = d_total['bears'] + 1        x, y = choice(c_empty_cells())    else:        d_total['lumberjacks'] = d_total['lumberjacks'] + 1        x, y = choice(c_not_bear_cells())    new_being = class_([x,y])    grid[x][y].append(new_being)    return "a new " + class_.__name__ +" enters the forest: " + new_being.namedef check_lumberjacks():"""we will never reduce our Lumberjack labor force below 0"""    if len(get_lumberjacks())==0:        return " - no more lumberjack, " + new_animate(Lumberjack)    return ""###movementsdef move_on_grid(being):    [x, y] = being.old_coords    grid[x][y].remove(being)    [x, y] = being.coords    grid[x][y].append(being)def move_lumberjack(lumberjack):"""Lumberjacks move 3 times if they don't encounter a (Elder) Tree or a Bear"""    global n_lumbers    for _ in range(3):        lumberjack.choose_new_coords()        move_on_grid(lumberjack)        [x, y] = lumberjack.coords        #is there something at the new coordinate?        #move append so this lumberjack is at the end        if grid[x][y][:-1] != []:            if isinstance(grid[x][y][0], Tree):                the_tree = grid[x][y][0]                price = worth(the_tree)                if price > 0:                    lumberjack.nb_cut = lumberjack.nb_cut + 1                    d_most['n_cut'] = max((lumberjack.nb_cut, lumberjack.name), \                                           d_most['n_cut'])                    d_total['cut'] = d_total['cut'] + 1                    n_lumbers = n_lumbers + price                    d_total['lumbers'] = d_total['lumbers'] + 1                    lumberjack.nb_lumber = lumberjack.nb_lumber + price                    d_most['n_lumber'] = max(d_most['n_lumber'], \                                             (lumberjack.nb_lumber, lumberjack.name))                    remove_from_grid([x, y], the_tree)                    return lumberjack.name +" cuts 1 " + the_tree.typeof            #if there is a bear, all lumberjacks have been sent to hospital            if isinstance(grid[x][y][0], Bear):                #the first bear is the killer                b = grid[x][y][0]                b.nb_maul = b.nb_maul + 1                d_most['n_maul'] = max((b.nb_maul, b.name), d_most['n_maul'])                return maul(lumberjack)    return Nonedef move_bear(bear):"""Bears move 5 times if they don't encounter a Lumberjack"""    for _ in range(5):        bear.choose_new_coords()        move_on_grid(bear)        [x, y] = bear.coords        there_was_something = (grid[x][y][:-1] != [])        if there_was_something:            #bears wander where there is no tree            #so it's either a lumberjack or another bear            #can't be both.            if isinstance(grid[x][y][0], Lumberjack):                bear.nb_maul = bear.nb_maul + 1                d_most['n_maul'] = max((bear.nb_maul, bear.name), \                                       d_most['n_maul'])                return maul(grid[x][y][0])    return None###get objectsdef get_objects(class_):"""get a list of instances in the grid"""    l = []    for i in range(NGRID):        for j in range(NGRID):          if grid[i][j]:              for k in grid[i][j]:                  if isinstance(k, class_):                      l.append(k)    return ldef get_trees():"""list of trees"""    return get_objects(Tree)def get_bears():"""list of bears"""    return get_objects(Bear)def get_lumberjacks():"""list of lumberjacks"""    return get_objects(Lumberjack)###utilsdef gen_name(which="l"):"""generate random name"""    name = ""    for _ in range(randint(1,4)):        name = name + choice("bcdfghjklmnprstvwxz") + choice("auiey")    if which == "b":        name = name[::-1]    return name.capitalize()def worth(tree):"""pieces for a tree"""    if tree.typeof == 'Elder Tree':        return 2    if tree.typeof == 'Tree':        return 1    return 0def one_month():"""a step of one month"""    events = []    global tick    tick = tick + 1    #each Tree can spawn a new sapling    for t in get_trees():        l_empty_spaces = c_empty_neighbors(t.coords)        percent = 10 if t.typeof == 'Tree' else \                  20 if t.typeof == 'Elder Tree' else 0        if (randint(1,100) < percent):            if l_empty_spaces:                [x, y] = choice(l_empty_spaces)                grid[x][y] = [Tree([x,y])]                d_total['trees'] = d_total['trees'] + 1        t.grow()        d_oldest['tree'] = max(t.months, d_oldest['tree'])    #each lumberjack/bear moves    for l in get_lumberjacks():        l.months = l.months + 1        d_oldest['lumberjack'] = max((l.months, l.name), \                                     d_oldest['lumberjack'])        event = move_lumberjack(l)        if event:            events.append(event)    for b in get_bears():        b.months = b.months + 1        d_oldest['bear'] = max((b.months, b.name), d_oldest['bear'])        event = move_bear(b)        if event:            events.append(event)    return eventsdef print_grid():"""print the grid    if more than 1 thing is at a place, print the last.    At 1 place, there is    - at most a tree and possibly several lumberjack    - or 1 bear"""    print "-" * 2 * NGRID    print '\n'.join([''.join([str(i[-1]) if i != [] else '' \                               for i in line]) \                     for line in grid])    print "-" * 2 * NGRIDdef clean():"""clear the console"""    os.system('cls' if os.name == 'nt' else 'clear')def print_grid_and_events():"""print grid and list of events"""    clean()    print_grid()    if VERBOSE:        print '\n'.join(events)        print "-" * 2 * NGRID###populate the forestl = c_empty_cells()shuffle(l)for x, y in l[:((NGRID*NGRID) / 2)]:    grid[x][y] = [Tree([x, y], 12, 'Tree')]    d_total['trees'] = d_total['trees'] + 1l = c_empty_cells()shuffle(l)for x, y in l[:((NGRID*NGRID) / 10)]:    grid[x][y] = [Lumberjack([x, y])]    d_total['lumberjacks'] = d_total['lumberjacks'] + 1l = c_empty_cells()shuffle(l)for x, y in l[:((NGRID*NGRID) / 10)]:    grid[x][y] = [Bear([x, y])]    d_total['bears'] = d_total['bears'] + 1###time goes onwhile (tick <= DURATION and len(get_trees())>0):    events = one_month()    #end of the year    if (tick % 12)==0:        events.append("End of the year")        #lumber tracking        nlumberjacks = len(get_lumberjacks())        events.append(str(n_lumbers) +" lumbers VS " +\                      str(nlumberjacks) +" Lumberjacks")        if n_lumbers >= nlumberjacks:            n_hire = n_lumbers/nlumberjacks            events.append("we hire " + str(n_hire) +\" new Lumberjack" + ("s" if (n_hire > 1) else ""))            for _ in range(n_hire):                events.append(new_animate(Lumberjack))        else:            events.append(fire_lumberjack())        d_year['n_lumber'] = max(d_year['n_lumber'], n_lumbers)        n_lumbers = 0        #maul tracking        events.append("maul this year: " + str(n_maul))        if n_maul == 0:            events.append(new_animate(Bear))        else:            events.append(capture_bear())        d_year['n_maul'] = max(d_year['n_maul'], n_maul)        n_maul = 0    print_grid_and_events()    sleep(SLEEPTIME)print "-"*70print "End of the game"print "-"*70print "month:" + str(tick - 1)print "number of trees still alive: " + str(len(get_trees()))print "number of lumberjacks still alive: " + str(len(get_lumberjacks()))print "number of bears still alive: " + str(len(get_bears()))print "-"*70print "oldest Tree ever is/was: " + str(d_oldest['tree'])print "oldest Lumberjack ever is/was: " + str(d_oldest['lumberjack'][0]) + \" yo " + d_oldest['lumberjack'][1]print "oldest Bear ever is/was: " + str(d_oldest['bear'][0]) + \" yo " + d_oldest['bear'][1]print "-"*70print "max cut by a Lumberjack: " + str(d_most['n_cut'][0]) + \" by " + str(d_most['n_cut'][1])print "max lumber by a Lumberjack: " + str(d_most['n_lumber'][0]) + \" by " + str(d_most['n_lumber'][1])print "max maul by a Bear: " + str(d_most['n_maul'][0]) + \" by " + str(d_most['n_maul'][1])print "-"*70print "max lumber in a year: " + str(d_year['n_lumber'])print "max maul in a year: " + str(d_year['n_maul'])print "-"*70print "Total of:"for i, j in d_total.items():    print i, str(j)

Some outputs:

------------------------------          x    I    I  x   i                     I      i i i   i       I I x ii   I   I i I I   i i     o      i i I I I           i    i I   x i    I I   I I      I     I i            x------------------------------Dy is sent to hospitalLehuniru cuts 1 Tree------------------------------

End of the year

------------------------------            x    xi I     I    i     I               x      I                          i i      x                   I I  i I   i I     i       i  I         i I            i x i    I         i I          o        x------------------------------Fuha cuts 1 TreeKa cuts 1 TreeKy is sent to hospitalEnd of the year11 lumbers VS 4 Lumberjackswe hire 2 new Lumberjacksa new Lumberjack enters the forest: Dia new Lumberjack enters the forest: Dymaul this year: 6Evykut has been captured------------------------------

End of the game

------------------------------          x  i        x     x          x                 x                  x i     x    i               I    I i x x   I i           x                    x   i   i      x i i i i I      i i I   I i I   iI       i     i i        i   x   i            I   i I    I I   x i   I I         x------------------------------Vanabixy cuts 1 TreeFasiguvy cuts 1 Tree----------------------------------------------------------------------------------------------------End of the game----------------------------------------------------------------------month:4800number of trees still alive: 36number of lumberjacks still alive: 15number of bears still alive: 0----------------------------------------------------------------------oldest Tree ever is/was: 129oldest Lumberjack ever is/was: 308 yo Cejukaoldest Bear ever is/was: 288 yo Ekyx----------------------------------------------------------------------max cut by a Lumberjack: 44 by Cejukamax lumber by a Lumberjack: 44 by Cejukamax maul by a Bear: 52 by Ekyx----------------------------------------------------------------------max lumber in a year: 84max maul in a year: 86----------------------------------------------------------------------Total of:bears 211cut 5054fired 67capture 211lumberjacks 1177lumbers 5054maul 1095trees 5090

Viewing latest article 1
Browse Latest Browse All 5

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>