import numpy as np class Board: MAX_BLOB = 255.0 MIN_BLOB = 0.0 INIT_FOOD = 100 def __init__(self, width, height): self.width = width self.height = height self.dropped_blob = np.zeros(shape=(width, height), dtype=float) self.foods = np.zeros(shape=(width, height), dtype=float) self.touched = np.zeros(shape=(width, height), dtype=bool) def save(self): stream = str(self.width) + ' ' + str(self.height) + '\n' for y in range(self.height): for x in range(self.width): saved_node = "{:d},{},{} ".format(self.touched[x, y], self.foods[x, y], self.dropped_blob[x, y]) stream += saved_node stream = stream.rstrip(' ') stream += '\n' return stream.rstrip('\n') def load(self, filename): with open(filename, 'r') as file: dim = file.readline() dims = dim.split(' ') if dims[0] != self.width and dims[1] != self.height: self.__init__(int(dims[0]), int(dims[1])) y = 0 for line in file: nodes = line.split(' ') if len(nodes) != self.width: print("Error with given height !" + str(len(nodes))) x = 0 for node in nodes: values = node.split(',') if len(values) != 3: print("Error with packaged values !") self.touched[x, y] = values[0] == '1' self.foods[x, y] = float(values[1]) self.dropped_blob[x, y] = float(values[2]) x += 1 y += 1 def has_food(self, x, y): return self.inside(x, y) and self.foods[x, y] > 0 def set_food(self, x, y, value=INIT_FOOD): if not self.foods[x, y] > 0: self.foods[x, y] = value def remove_food(self, x, y): if self.foods[x, y] > 0: self.foods[x, y] = 0 def update_blob(self, x, y, change_value): if self.inside(x, y): self.touched[x, y] = True self.dropped_blob[x, y] = max(Board.MIN_BLOB, min(self.dropped_blob[x, y] + change_value, Board.MAX_BLOB)) return True else: return False def eat_food(self, x, y, change_value): if self.foods[x, y] > 0: if self.foods[x, y] - change_value >= 0: self.foods[x, y] -= change_value else: change_value = self.foods[x, y] self.foods[x, y] = 0 else: change_value = 0 return change_value, self.foods[x, y] <= 0 def get_blob(self, x, y): if self.inside(x, y): return self.dropped_blob[x, y] else: return None def inside(self, x, y): return 0 <= x < self.width and 0 <= y < self.height def is_touched(self, x, y): if self.inside(x, y): return self.touched[x, y] else: return False def get_cover(self, half_board=0): if half_board == 1: val = np.sum(self.touched[:, 0:int(self.height/2)]) * 2 elif half_board == 2: val = np.sum(self.touched[:, int(self.height/2):self.height]) * 2 else: val = np.sum(self.touched) return val / self.height / self.width * 100 def get_blob_total(self): total = 0 for x in range(self.width): for y in range(self.height): total += self.dropped_blob[x, y] return total / self.height / self.width / self.MAX_BLOB * 100 def manage_blob(self, value, min_food_value=MIN_BLOB): for x in range(self.width): for y in range(self.height): if self.touched[x, y]: if not (self.foods[x, y] > 0 and self.dropped_blob[x, y] <= min_food_value): self.update_blob(x, y, -value) def reset(self, x, y): if self.inside(x, y): self.touched[x, y] = False self.dropped_blob[x, y] = 0 self.foods[x, y] = 0 def compare(self, board): if board.height != self.height and board.width != self.width: print("Size don't match !") return None board_comp = Board(self.width, self.height) for x in range(self.width): for y in range(self.height): board_comp.foods[x, y] = board.foods[x, y] - self.foods[x, y] board_comp.touched[x, y] = self.touched[x, y] == board.touched[x, y] board_comp.dropped_blob[x, y] = board.dropped_blob[x, y] - self.dropped_blob[x, y] return board_comp