Source code for farmgym.v2.field

from textwrap import indent


class Plot:
    def __init__(self, field, position, type="base"):
        self.field = field
        self.position = position  # x,y
        assert type in ["base", "edge"]
        self.type = type

    def __str__(self):
        return "'" + str(self.position) + ":" + self.type + "'"


[docs]class Field: """ Instanciate a Field. One or several fields are included in a farm and one field includes several plants. Parameters ---------- localization: (latitude, longitude, altitude) localisation of the field shape: (length (int), width (int), scale (multiples of 1 unit in meter)) Shape of the field. Each field of shape (width,length,scale) contains width × length many plots each of size scale entity_managers: list list of couples (entity, name) used to construct the field. Examples -------- >>> from farmgym.v2.field import Field >>> from farmgym.v2.entities.Weather import Weather >>> from farmgym.v2.entities.Soil import Soil >>> from farmgym.v2.entities.Plant import Plant >>> entities = [(Weather, "lille"), (Soil, "clay"), (Plant, "bean")] >>> field1 = Field(localization={"latitude#°": 43, "longitude#°": 4, "altitude#m": 150}, >>> shape={"length#nb": 1, "width#nb": 1, "scale#m": 1.0}, >>> entity_managers=entities) """ def __init__(self, localization, shape, entity_managers: list): self.name = "Field" self.localization = localization assert list(localization.keys()) == ["latitude#°", "longitude#°", "altitude#m"] assert list(shape.keys()) == ["length#nb", "width#nb", "scale#m"] self.shape = shape self.plotsurface = shape["scale#m"] ** 2.0 # TODO: Make it np.zeros list, then manually fill # self.plots = [[Plot(self,[x,y], "edge" if x in [0,shape['length']-1] or y in [0, shape['width']-1] else "base") for y in range (shape['width'])] for x in range(shape['length'])] self.X = self.shape["length#nb"] self.Y = self.shape["width#nb"] self.plots = [str((x, y)) for x in range(self.X) for y in range(self.Y)] # self.plots = [Plot(self,[x,y], "edge" if x in [0,shape['length']-1] or y in [0, shape['width']-1] else "base") for x in range(X) for y in range (Y)] self.entity_managers = entity_managers self.entities = {} cpt = {} for e, param in self.entity_managers: # print('ENAME',e.__name__) # print(self.entities.keys()) if e.__name__ in cpt.keys(): cpt[e.__name__] += 1 name = e.__name__ + "-" + str(cpt[e.__name__]) self.entities[name] = e(self, param) self.entities[name].name = name else: cpt[e.__name__] = 0 name = e.__name__ + "-0" self.entities[name] = e(self, param) self.entities[name].name = name
[docs] def reset(self): """ Reset to initial values """ for e in self.entities.values(): e.reset()
[docs] def get_neighbors(self, plot): """NW N NE,W,E,SW,S,SE""" x, y = plot xm = self.X ym = self.Y assert 0 <= x < xm and 0 <= y < ym neighbors = {} if y > 0: if x > 0: neighbors["NW"] = (x - 1, y - 1) neighbors["N"] = (x, y - 1) if x < xm - 1: neighbors["NE"] = (x + 1, y - 1) if x > 0: neighbors["W"] = (x - 1, y) if x < xm - 1: neighbors["E"] = (x + 1, y) if y < ym - 1: if x > 0: neighbors["SW"] = (x - 1, y + 1) neighbors["S"] = (x, y + 1) if x < xm - 1: neighbors["SE"] = (x + 1, y + 1) return neighbors
def distance_to_edge(self, position): x, y = position if x > self.X / 2: x = self.X - x if y > self.Y / 2: y = self.Y - y return min(x, y)
[docs] def update_to_next_day(self): """ Update internal variables of the field after an increment of 1 day. """ for e in self.entities.values(): e.update_variables(self, self.entities)
def __str__(self): s = self.name + ": " + str(self.localization) + " scale: " + str(self.shape["scale#m"]) + "m\n" s += "\tShape:\n\t\t" for x in range(self.X): for y in range(self.Y): s += "E" if self.distance_to_edge((x, y)) <= 1 else "B" s += "\n\t\t" s += "\n" s += "\t" + self.name + "-Entities:\n" for k in self.entities.keys(): s += indent(str(self.entities[k]), "\t\t", lambda line: True) + "\n" return s