def _derive_nearest(self): self.nearest_objects = [] self.enemies_in_cast_range = [] self.matrix = [[0] * MATRIX_CELL_AMOUNT for _ in range(MATRIX_CELL_AMOUNT)] matrix_top = self.me.y - MATRIX_CELL_SIZE * MATRIX_CELL_AMOUNT / 2 matrix_left = self.me.x - MATRIX_CELL_SIZE * MATRIX_CELL_AMOUNT / 2 for obj in chain(self.world.buildings, self.world.minions, self.world.wizards, self.world.trees): obj.distance = distance(self.me, obj) if obj.distance <= NEAREST_RADIUS and obj.id != self.me.id: self.nearest_objects.append(obj) if self._is_enemy( obj) and obj.distance <= self.game.wizard_cast_range: self.enemies_in_cast_range.append(obj) col_left = int( (obj.x - obj.radius - matrix_left) // MATRIX_CELL_SIZE) col_right = int( (obj.x + obj.radius - matrix_left) // MATRIX_CELL_SIZE) row_top = int( (obj.y - obj.radius - matrix_top) // MATRIX_CELL_SIZE) row_bottom = int( (obj.y + obj.radius - matrix_top) // MATRIX_CELL_SIZE) for row in range(row_top, row_bottom + 1): for col in range(col_left, col_right + 1): if 0 <= col < MATRIX_CELL_AMOUNT and 0 <= row < MATRIX_CELL_AMOUNT: self.matrix[row][col] = -1
def _check_state(self): if distance(self.me, self.top_line_bound) < ON_LINE_DISTANCE: new_state = LineState.ON_LINE else: new_state = LineState.MOVING_TO_LINE if self.line_state != new_state: old_state = self.line_state self.line_state = new_state self._line_state_changed(old_state)
def goto(self, target: Vec): if self._check_if_stacked(): return if distance(self.me, target) < TARGET_DISTANCE_TO_STAY: self.move_state = MoveState.STAYING return else: self.move_state = MoveState.MOVING_TO_TARGET self.move_obj.speed = self.game.wizard_forward_speed angle = self.me.get_angle_to_unit(target) self.move_obj.turn = angle vec = Vec(target.x - self.me.x, target.y - self.me.y) self.move_obj.strafe_speed = self._calc_strafe(vec)
def put_simple(self, map, pos, force, radius): row, col = int(pos.y // self.CELL_SIZE), int(pos.x // self.CELL_SIZE) rad = radius // self.CELL_SIZE row_min = max(0, int(row - rad)) col_min = max(0, int(col - rad)) row_max = min(self.CELL_AMOUNT - 1, int(row + rad)) col_max = min(self.CELL_AMOUNT - 1, int(col + rad)) for row in range(row_min, row_max + 1): for col in range(col_min, col_max + 1): x = col * self.CELL_SIZE + self.HALF_CELL_SIZE y = row * self.CELL_SIZE + self.HALF_CELL_SIZE dist = distance(pos.x, pos.y, x, y) if dist < radius: # map[row, col] = min(map[row,col], (radius - dist) / radius * force) map[row, col] += (radius - dist) / radius * force
def battle_goto_smart(self, target, look_at): if distance(self.me, target) < 1.42 * MATRIX_CELL_SIZE: return self.battle_goto(target, look_at) shifted_target = Vec(target.x - MATRIX_CELL_SIZE / 2, target.y - MATRIX_CELL_SIZE / 2) matrix_top = self.me.y - MATRIX_CELL_SIZE * MATRIX_CELL_AMOUNT / 2 matrix_left = self.me.x - MATRIX_CELL_SIZE * MATRIX_CELL_AMOUNT / 2 target_row = int((shifted_target.y - matrix_top) / MATRIX_CELL_SIZE) target_row = max(0, min(MATRIX_CELL_AMOUNT - 1, target_row)) target_col = int((shifted_target.x - matrix_left) / MATRIX_CELL_SIZE) target_col = max(0, min(MATRIX_CELL_AMOUNT - 1, target_col)) me_row = me_col = int(MATRIX_CELL_AMOUNT / 2) - 1 self.matrix[me_row][me_col] = 1 self.matrix[me_row + 1][me_col] = 0 self.matrix[me_row + 1][me_col + 1] = 0 self.matrix[me_row][me_col + 1] = 0 heap = [] heappush(heap, (distance(me_row, me_col, target_row, target_col), (me_row, me_col))) stop = False while heap and not stop: _, (cur_row, cur_col) = heappop(heap) path_length = self.matrix[cur_row][cur_col] + 1 for drow, dcol in ((-1, 0), (0, 1), (1, 0), (0, -1)): row = cur_row - drow col = cur_col - dcol if 0 <= row < MATRIX_CELL_AMOUNT - 1 and 0 <= col < MATRIX_CELL_AMOUNT - 1 and self.empty(row, col) \ and (self.matrix[row][col] == 0 or self.matrix[row][col] > path_length): self.matrix[row][col] = path_length heappush(heap, (distance(row, col, target_row, target_col), (row, col))) if row == target_row and col == target_col: stop = True break if self.matrix[target_row][target_col] <= 0: visited = set() visited.add((target_row, target_col)) queue = deque() queue.append((target_row, target_col)) stop = False while not stop: cur_row, cur_col = queue.popleft() for drow, dcol in ((-1, 0), (0, 1), (1, 0), (0, -1)): row = cur_row - drow col = cur_col - dcol row_col = (row, col) if 0 <= row < MATRIX_CELL_AMOUNT - 1 and 0 <= col < MATRIX_CELL_AMOUNT - 1 and row_col not in visited: if self.matrix[row][col] > 0: target_row, target_col = row, col stop = True break visited.add(row_col) queue.append(row_col) path = [] cur_row, cur_col = target_row, target_col path_length = self.matrix[target_row][target_col] - 1 while (cur_row, cur_col) != (me_row, me_col): for drow, dcol in ((-1, 0), (0, 1), (1, 0), (0, -1)): row = cur_row - drow col = cur_col - dcol if 0 <= row < MATRIX_CELL_AMOUNT - 1 and 0 <= col < MATRIX_CELL_AMOUNT - 1 \ and self.matrix[row][col] == path_length: path.append((row, col)) cur_row, cur_col = row, col path_length -= 1 break for row, col in path: self.matrix[row][col] = 666 if len(path) == 0: return self.battle_goto(target, look_at) elif len(path) > 1: row, col = path[-2] else: row, col = path[-1] target = Vec(matrix_left + (col + 1) * MATRIX_CELL_SIZE, matrix_top + (row + 1) * MATRIX_CELL_SIZE) self.battle_goto(target, look_at)