class Ant: DIR_UP = Vector2D(0, 1) DIR_RIGHT = Vector2D(1, 0) DIR_DOWN = Vector2D(0, -1) DIR_LEFT = Vector2D(-1, 0) def __init__(self, ground, row, col, direction=DIR_UP): self.pos = Vector2D(row, col) self.ground = ground self.direction = direction self.ground.ants[self.pos.get()] = self @property def row(self): return self.pos.x @property def col(self): return self.pos.y def move(self): moves = self.get_possible_moves() move = choice(moves) del self.ground.ants[self.pos.get()] self.ground.ants[move.get()] = self self.direction = move - self.pos self.pos = move def rotate_direction(self, right=False): rads = radians(90) if right: rads *= -1 new_x = cos(rads) * self.direction.x - sin(rads) * self.direction.y new_y = sin(rads) * self.direction.x + cos(rads) * self.direction.y return Vector2D(int(new_x), int(new_y)) def get_possible_moves(self): possible_moves = [] for d in [ self.rotate_direction(right=False), self.direction, self.rotate_direction(right=True) ]: move = self.pos + d if self.check_bounds(move): possible_moves.append(move) return possible_moves def check_bounds(self, pos): return 0 <= pos.x < self.ground.cols and 0 <= pos.y < self.ground.rows
def move(self): if self.direction == "up": new_x = self.head().x new_y = (self.head().y - 1) % self.height if self.direction == "right": new_x = (self.head().x + 1) % self.width new_y = self.head().y if self.direction == "down": new_x = self.head().x new_y = (self.head().y + 1) % self.width if self.direction == "left": new_x = (self.head().x - 1) % self.height new_y = self.head().y new_head = Vector2D(new_x, new_y) if new_head in self.body: self.alive = False self.body.insert(0, new_head) if new_head == self.food: self.new_food() return True else: self.body.pop() return False
def rotate_direction(self, right=False): rads = radians(90) if right: rads *= -1 new_x = cos(rads) * self.direction.x - sin(rads) * self.direction.y new_y = sin(rads) * self.direction.x + cos(rads) * self.direction.y return Vector2D(int(new_x), int(new_y))
def new_food(self, x=-1, y=-1): if x < 0 or y < 0: while True: self.food = Vector2D( randint(0, self.width), randint(0, self.height) ) if self.food not in self.body: break else: if x >= self.width or y >= self.height: raise ValueError("Arguments out of bounds.") if Vector2D(x, y) in self.body: raise ValueError("There is a piece of body there.") self.food = Vector2D(x, y)
def __init__(self): self.finished = False self.dt = 0.01 self.lend_pos = -1 self.rend_pos = 1 self.l_M_pos = Vector2D(0, 0) self.r_M_pos = Vector2D(0, 0) self.l_T = 0 self.m_T = 0 self.r_T = 0 self.alpha = 0 self.beta = 0 self.D = self.rend_pos - self.lend_pos
def compute_mass_positions(self): print("\nnew pos computation") for i in range(10000): sin_a, cos_a, sin_b, cos_b = fsolve(self.angles_equations, sp.rand(4)) print("\t", sin_a, sin_b) if 0 <= sin_a < 1 \ and 0 < cos_a <= 1 \ and 0 <= sin_b < 1 \ and 0 < cos_b <= 1 \ and self.LROPE_LEN * sin_a + self.RROPE_LEN * sin_b <= self.D: self.l_M_pos = Vector2D(sin_a, -cos_a) * self.LROPE_LEN self.l_M_pos += Vector2D(self.lend_pos, 0) self.r_M_pos = Vector2D(-sin_b, -cos_b) * self.RROPE_LEN self.r_M_pos += Vector2D(self.rend_pos, 0) m_diff = self.l_M_pos - self.r_M_pos norm = m_diff.norm() print("norm:", norm) rend_to_l_M = self.l_M_pos - Vector2D(self.rend_pos, 0) sin_of_this = -rend_to_l_M.x / rend_to_l_M.norm() print("sins:", sin_of_this, sin_b) if sp.absolute(self.MROPE_LEN - norm) < 1e-2 \ and sin_of_this >= sin_b: print("break") break else: raise RuntimeError("Angle computation failed") self.alpha = sp.arcsin(sin_a) self.beta = sp.arcsin(sin_b)
def __init__(self, width=50, height=50, direction="up", starvation_time=np.inf): self.width = width self.height = height self.direction = direction self.starvation_time = starvation_time self.body = [ Vector2D( randint(0, width), randint(0, height) ) ] self.food = None self.alive = True self.new_food()
def __init__(self, ground, row, col, direction=DIR_UP): self.pos = Vector2D(row, col) self.ground = ground self.direction = direction self.ground.ants[self.pos.get()] = self