Exemple #1
0
def draw_long_spline(spline_sequence, xlim, ylim, plot_vectors=False):
    """Draw a spline_sequence on a plot

    spline_sequence = [all_points, all_points, ...]
    """
    logg = logging.getLogger(f"c.{__name__}.draw_long_spline")
    #  logg.setLevel("INFO")
    logg.debug(f"Starting draw_long_spline")

    fig, ax = plt.subplots()
    ax.set_xlim(*xlim)
    ax.set_ylim(*ylim)

    for all_points in spline_sequence:
        for i in range(len(all_points) - 1):
            p0 = all_points[i]
            p1 = all_points[i + 1]
            if plot_vectors:
                utils.add_vector(p0, ax, color="k", vec_len=20)

            #  spline_x, spline_y = compute_spline(p0, p1)
            spline_x, spline_y = compute_thick_spline(p0, p1, 40)
            utils.add_points(spline_x, spline_y, ax, color="y", marker=".", ls="")

    if plot_vectors:
        utils.add_vector(p1, ax, color="k", vec_len=20)

    utils.plot_build(fig, ax)
    plt.show()
Exemple #2
0
def assemble_tiles(graph):
    corner = set_top_left_corner(graph)
    positions = {corner: (0, 0)}

    for edge in nx.bfs_edges(graph, corner):
        # pylint: disable=cell-var-from-loop
        edges = graph.edges[edge]['edge']
        tile_id_1, tile_id_2 = edge
        tile_1, tile_2 = graph.nodes[tile_id_1]['tile'], graph.nodes[tile_id_2]['tile']

        assert tile_id_1 in positions

        tile_1_edges = tile_1.edges()
        edge_1 = iterutils.first(range(4), key=lambda i: tile_1_edges[i] in edges)
        positions[tile_id_2] = utils.add_vector(positions[tile_id_1], EDGE_TO_VECTOR[edge_1])
        orient_tile_to_edge(tile_1, edge_1, tile_2)

    # Now that positions have been determined, form grid of sub-images
    dims = utils.add_vector(max(positions.values()), (1, 1))
    grid = [
        [None for _ in range(dims[1])]
        for _ in range(dims[0])
    ]

    for tile_id, (i, j) in positions.items():
        tile = graph.nodes[tile_id]['tile']
        grid[i][j] = tile
        # Truncate tile borders
        tile.points = tile.points[1:-1, 1:-1]

    # Merge truncated tiles into final image
    return np.vstack([
        np.hstack([tile.points for tile in row])
        for row in grid
    ])
Exemple #3
0
def example_spline():
    """
    """
    logg = logging.getLogger(f"c.{__name__}.example_spline")
    logg.setLevel("INFO")
    logg.debug(f"Starting example_spline")

    # create the plot
    fig, ax = plt.subplots()
    ax.set_xlim(0, 4)
    ax.set_ylim(-3, 4)

    # sample per segment
    num_samples = 100

    # first segment
    p0 = SPoint(1, 1, 30)
    #  p1 = SPoint(3, 2, 45)
    p1 = SPoint(2.6, 3, 60)
    logg.debug(f"p0: {p0} p1: {p1}")
    # plot the points
    utils.add_vector(p0, ax, color="k")
    utils.add_vector(p1, ax, color="k")

    # compute the spline
    spline_x, spline_y = compute_spline(p0, p1, ax=ax)

    # plot the finished spline
    utils.add_points(spline_x, spline_y, ax, color="y")

    # plot everything
    utils.plot_build(fig, ax)
    plt.show()
Exemple #4
0
def compute_spline(p0, p1, num_samples=100, ax=None):
    """Compute the cubic spline between two points

    * translate to the origin and rotate the points to have both on the x axis
    * compute the spline
    * rotate and translate to original position
    """
    logg = logging.getLogger(f"c.{__name__}.compute_spline")
    logg.setLevel("INFO")
    logg.debug(f"Starting compute_spline")

    # translate and rotate the point to the origin
    rot_p0, rot_p1, dir_01 = translate_points_to_origin(p0, p1)

    # plot the rotated vectors
    if not ax is None:
        utils.add_vector(rot_p0, ax, color="r")
        utils.add_vector(rot_p1, ax, color="r")

    # compute the spline points
    coeff = cubic_curve(rot_p0, rot_p1)
    x_sample, y_segment = compute_segment_points(rot_p0.x, rot_p1.x, coeff)
    if not ax is None:
        utils.add_points(x_sample, y_segment, ax, color="g")

    # rototranslate points to the original position
    rototran_x, rototran_y = rototranslate_points(
        x_sample, y_segment, -dir_01, p0.x, p0.y,
    )

    return rototran_x, rototran_y
Exemple #5
0
def part_2():
    floor = get_initial_floor()

    for _ in range(100):
        black_neighbors = collections.defaultdict(int)

        for position, color in floor.items():
            if color == Color.BLACK:
                neighbor_colors = []

                for vector in VECTORS.values():
                    neighbor = utils.add_vector(position, vector)
                    neighbor_colors.append(floor.get(neighbor, Color.WHITE))
                    black_neighbors[neighbor] += 1

                if all([color == Color.WHITE for color in neighbor_colors]):
                    black_neighbors[position] = 0

        for position, count in black_neighbors.items():
            color = floor[position]
            if color == Color.BLACK and count not in [1, 2]:
                floor[position] = Color.flip(color)
            elif color == Color.WHITE and count == 2:
                floor[position] = Color.flip(color)

    print(list(floor.values()).count(Color.BLACK))
Exemple #6
0
    def get_visible_occupied_seats(self, point):
        visible_occupied_seats = []

        for i in [-1, 0, 1]:
            for j in [-1, 0, 1]:
                vector = (i, j)
                if vector != (0, 0):
                    visible_point = utils.add_vector(point, vector)

                    while self.points.get(visible_point) == PointType.FLOOR:
                        visible_point = utils.add_vector(visible_point, vector)

                    if self.points.get(visible_point) == PointType.OCCUPIED_SEAT:
                        visible_occupied_seats.append(visible_point)

        return visible_occupied_seats
Exemple #7
0
 def checkOptions(self, player, otherPos, rotSeq):
     currentPos = (self.dict['x'], self.dict['y'])
     if otherPos == currentPos:
         options = self.generateCollisionOptions(player)
         bestDirection = utils.direction((self.dict['x'], self.dict['y']), self.dict['prevpos'])
         bdpos = utils.round_vector(bestDirection)
         if utils.magnitude(bdpos) == 0:
             bdpos = rand.choice(optKeys)
         if options[bdpos] and player.getRoom().validPosition(utils.add_vector(currentPos, bdpos)):
             self.dict['x'] += bdpos[0]
             self.dict['y'] += bdpos[1]
             return True
         else:
             for rot in rotSeq:
                 testvec = utils.rotate(bdpos, rot)
                 testvec = utils.round_vector(testvec)
                 if options[testvec]:
                     self.dict['x'] += testvec[0]
                     self.dict['y'] += testvec[1]
                     return True
             # if nothing worked -- this could be expanded to do proper step-by-step
             # checking until invalid
             self.dict['x'] = self.dict['prevpos'][0]
             self.dict['y'] = self.dict['prevpos'][1]
             return True
     return False
Exemple #8
0
def get_trees_encountered(grid, slope):
    position = (0, 0)
    trees = 0

    while position[0] < grid.rows:
        trees += grid[position] == '#'
        position = utils.add_vector(position, slope)

    return trees
Exemple #9
0
def rotated_match(scanner_1, scanner_2):
    for point_1, point_2 in itertools.product(scanner_1, scanner_2):
        diff = tuple(x - y for x, y in zip(point_1, point_2))
        oriented_scanner_2 = Scanner(
            scanner_2.id,
            frozenset([utils.add_vector(point, diff) for point in scanner_2]),
        )
        if len(scanner_1.points & oriented_scanner_2.points) >= 12:
            return oriented_scanner_2, diff

    return None
Exemple #10
0
def get_initial_floor():
    tiles = utils.get_input(__file__, delimiter=None, cast=str)
    lexer = TileLexer()
    floor = collections.defaultdict(lambda: Color.WHITE)

    for tile in tiles:
        position = (0, 0, 0)
        for token in lexer.tokenize(tile):
            position = utils.add_vector(position, VECTORS[token.value])

        floor[position] = Color.flip(floor[position])

    return floor
Exemple #11
0
def get_label(graph, first_letter):
    # Either down or right
    second_letter_vectors = [VECTORS[1], VECTORS[2]]

    for vector in second_letter_vectors:
        neighbor = utils.add_vector(first_letter, vector)
        if is_letter(graph, neighbor):
            label_position = None
            candidate_positions = [
                utils.add_vector(first_letter, -1 * vector),
                utils.add_vector(neighbor, vector),
            ]
            for position in candidate_positions:
                if is_empty(graph, position):
                    label_position = position

            if label_position:
                label = graph.nodes[first_letter]['value'] + graph.nodes[
                    neighbor]['value']
                return Label(label, label_position, [first_letter, neighbor])

    return None
Exemple #12
0
    def generateCollisionOptions(self, player):
        currentPos = (self.dict['x'], self.dict['y'])
        room = player.getRoom()
        getRel = lambda x, y : (x.dict['x'] - y.dict['x'], x.dict['y'] - y.dict['y'])
        relpos = [getRel(x, self) for x in player.getRoom().dict['things']]
        ppos = room.getPlayerPos(player)
        relpos.append((ppos[0] - self.dict['x'], ppos[1] - self.dict['y']))
        opts = {k:True for k in optKeys}

        for pos in relpos:
            if pos in opts:
                opts[pos] = False

        for pos in opts:
            if not room.validPosition(utils.add_vector(currentPos, pos)):
                opts[pos] = False

        return opts
Exemple #13
0
    def neighbors(self, coordinate):
        neighbors = []
        for vector in VECTORS:
            neighbor = utils.add_vector(coordinate, vector)
            val = self.get(neighbor)
            if val is not None:
                neighbors.append(val)

        if not self.recursive:
            return neighbors

        i, j, k = coordinate
        more_neighbors = []
        if (i, j) == (2, 1):
            more_neighbors = itertools.product(range(5), [0], [k + 1])
        elif (i, j) == (2, 3):
            more_neighbors = itertools.product(range(5), [4], [k + 1])
        elif (i, j) == (1, 2):
            more_neighbors = itertools.product([0], range(5), [k + 1])
        elif (i, j) == (3, 2):
            more_neighbors = itertools.product([4], range(5), [k + 1])
        else:
            if i == 0:
                more_neighbors.append((1, 2, k - 1))
            elif i == 4:
                more_neighbors.append((3, 2, k - 1))

            if j == 0:
                more_neighbors.append((2, 1, k - 1))
            elif j == 4:
                more_neighbors.append((2, 3, k - 1))

        for neighbor in more_neighbors:
            val = self.get(neighbor)
            if val is not None:
                neighbors.append(val)

        return neighbors
Exemple #14
0
def compute_thick_spline(p0, p1, thickness, num_samples=100, ax=None):
    """Compute the thick cubic spline between two points

    * translate to the origin and rotate the points to have both on the x axis
    * compute the spline
    * make it thicker
    * rotate and translate to original position
    """
    logg = logging.getLogger(f"c.{__name__}.compute_spline")
    logg.setLevel("INFO")
    logg.debug(f"Starting compute_spline")

    # translate and rotate the point to the origin
    rot_p0, rot_p1, dir_01 = translate_points_to_origin(p0, p1)
    logg.debug(f"rot_p0: {rot_p0} rot_p1: {rot_p1}")

    # compute the normal direction to the vectors
    np0_ori_rad = rot_p0.ori_rad + pi / 2
    np1_ori_rad = rot_p1.ori_rad + pi / 2

    # compute the corner points of the thick spline
    offset_x_0 = cos(np0_ori_rad) * thickness
    offset_y_0 = sin(np0_ori_rad) * thickness
    logg.debug(f"offset_x_0: {offset_x_0} offset_y_0: {offset_y_0}")
    p0t = SPoint(rot_p0.x + offset_x_0, rot_p0.y + offset_y_0, rot_p0.ori_deg)
    p0b = SPoint(rot_p0.x - offset_x_0, rot_p0.y - offset_y_0, rot_p0.ori_deg)
    logg.debug(f"p0t: {p0t} p0b: {p0b}")
    offset_x_1 = cos(np1_ori_rad) * thickness
    offset_y_1 = sin(np1_ori_rad) * thickness
    logg.debug(f"offset_x_1: {offset_x_1} offset_y_1: {offset_y_1}")
    p1t = SPoint(rot_p1.x + offset_x_1, rot_p1.y + offset_y_1, rot_p1.ori_deg)
    p1b = SPoint(rot_p1.x - offset_x_1, rot_p1.y - offset_y_1, rot_p1.ori_deg)
    logg.debug(f"p1t: {p1t} p1b: {p1b}")

    # compute the coeff of the line passing through the points
    coeff_l = line_curve(p0t, p0b)
    coeff_r = line_curve(p1t, p1b)
    logg.debug(f"coeff_l: {coeff_l} coeff_r: {coeff_r}")

    # compute the spline points
    coeff_t = cubic_curve(p0t, p1t)
    coeff_b = cubic_curve(p0b, p1b)
    x_sample_t, y_segment_t = sample_segment_points(p0t.x, p1t.x, coeff_t)
    x_sample_b, y_segment_b = sample_segment_points(p0b.x, p1b.x, coeff_b)
    logg.debug(f"x_sample_t.shape: {x_sample_t.shape}")
    logg.debug(f"x_sample_b.shape: {x_sample_b.shape}")

    contour_t, contour_b, x_sample = build_contour(
        p0t,
        p0b,
        p1t,
        p1b,
        coeff_l,
        coeff_r,
        x_sample_t,
        y_segment_t,
        x_sample_b,
        y_segment_b,
        ax,
    )

    # compute the top and bottom contours
    logg.debug(f"x_sample.shape: {x_sample.shape}")
    logg.debug(f"contour_t.shape: {contour_t.shape}")
    logg.debug(f"contour_b.shape: {contour_b.shape}")

    # get the max and min y, aligned on the grid
    max_y = np.amax(contour_t)
    min_y = np.amin(contour_b)
    logg.debug(f"max_y: {max_y} min_y: {min_y}")
    max_y_aligned = floor(max_y)
    min_y_aligned = ceil(min_y)
    logg.debug(f"max_y_aligned: {max_y_aligned} min_y_aligned: {min_y_aligned}")

    #  sample all the points inside the spline, aligned on the grid
    on_points_x = []
    on_points_y = []
    for i, x_curr in enumerate(x_sample):
        for y_curr in range(min_y_aligned, max_y_aligned + 1):
            if contour_b[i] <= y_curr <= contour_t[i]:
                on_points_x.append(x_curr)
                on_points_y.append(y_curr)

    # rototranslate points to the original position
    rototran_x, rototran_y = rototranslate_points(
        on_points_x, on_points_y, -dir_01, p0.x, p0.y,
    )

    # plot everything to debug things
    if not ax is None:
        vec_len = 3
        ## plot the points
        utils.add_vector(p0, ax, color="r", vec_len=vec_len)
        utils.add_vector(p1, ax, color="r", vec_len=vec_len)
        ## plot the rotated vectors
        utils.add_vector(rot_p0, ax, color="k", vec_len=vec_len)
        utils.add_vector(rot_p1, ax, color="k", vec_len=vec_len)
        ## plot the corner of the spline
        utils.add_vector(p0t, ax, color="k", vec_len=vec_len)
        utils.add_vector(p1t, ax, color="k", vec_len=vec_len)
        utils.add_vector(p0b, ax, color="k", vec_len=vec_len)
        utils.add_vector(p1b, ax, color="k", vec_len=vec_len)
        ## plot top and bottom splines
        #  utils.add_points(x_sample_t, y_segment_t, ax, color="b", marker=".", ls="")
        #  utils.add_points(x_sample_b, y_segment_b, ax, color="b", marker=".", ls="")
        utils.add_points(x_sample_t, y_segment_t, ax, color="r", marker="", ls="-")
        utils.add_points(x_sample_b, y_segment_b, ax, color="r", marker="", ls="-")
        ## plot top and bottom contours
        utils.add_points(x_sample, contour_t, ax, color="r", marker=".", ls="")
        utils.add_points(x_sample, contour_b, ax, color="r", marker=".", ls="")
        ## plot on point
        utils.add_points(on_points_x, on_points_y, ax, color="b", marker=".", ls="")
        ## plot on point translated back to original position
        utils.add_points(rototran_x, rototran_y, ax, color="b", marker=".", ls="")

    return rototran_x, rototran_y
Exemple #15
0
 def pre_update(self):
     pressed = pygame.key.get_pressed()
     if self.active_rock:
         self.pannable.pan_to_game_object(self.active_rock)
     if self.game_state is PRE_GAME:
         self.p1_score, self.p2_score = 0, 0
         self.game_state = PRE_END
         self.end = 0
     if self.game_state is PRE_END:
         self.end += 1
         self.remove_all_rocks()
         print('just removed all rocks:', self.rocks)
         self.team = not self.end % 2
         self.throws_left = 6
         self.update_bottom_panel()
         self.game_state = PRE_THROW
     if self.game_state is PRE_THROW:
         self.start_aim()
     self.broom.move_to(
         self.sweeper.rect.move((150, 75 + self.broom_offset)).topleft)
     if self.game_state is AIMING:
         if not self.active_rock:
             self.active_rock = self.add_rock((1000, 500))
         # region Aim
         rot_limit = 3
         if up_key_is_pressed(
         ) and not 180 > self.trajectory.get_rotation() > rot_limit:
             self.trajectory.rotate(0.1)
         if down_key_is_pressed(
         ) and not 180 < self.trajectory.get_rotation() < 360 - rot_limit:
             self.trajectory.rotate(-0.1)
         self.mini_trajectory.set_rotation(self.trajectory.get_rotation())
         source = (605, 500)
         if self.trajectory.get_rotation() < 180:
             self.trajectory.move_to(
                 (source[0], source[1] - self.trajectory.rect.height + 2))
             self.mini_trajectory.move_to(
                 (source[0] // 5,
                  source[1] // 5 - self.mini_trajectory.rect.height + 1))
         else:
             self.trajectory.move_to((source[0], source[1] - 2))
             self.mini_trajectory.move_to(
                 (source[0] // 5, source[1] // 5 - 1))
         traj_pos = self.trajectory.rect.topleft
         #endregion
     if self.game_state is THROWING:
         if self.active_rock.rect.right > 2590:  # hog line
             self.release_rock()
         if up_key_is_pressed():
             self.active_rock.rotvel += 3
         if down_key_is_pressed():
             self.active_rock.rotvel -= 3
         # TODO adjust spin
     if self.game_state is SWEEPING:
         sweep_limit = 50
         sweep_speed = 3
         if up_key_is_pressed() and self.sweeper_offset > -50:
             self.sweeper_offset -= sweep_speed
             self.sweeper.move((0, -sweep_speed))
         if down_key_is_pressed() and self.sweeper_offset < 50:
             self.sweeper_offset += sweep_speed
             self.sweeper.move((0, sweep_speed))
         if action_key_is_pressed():
             self.active_rock.use_reduced_friction()
             self.active_rock.vel = utils.add_vector(
                 self.active_rock.vel,
                 (0, math.hypot(*self.active_rock.vel) *
                  self.sweeper_offset / 200000))
             self.animate_broom_frame()
         else:
             self.active_rock.use_normal_friction()
         if self.active_rock.rect.right > 9000 or self.active_rock.vel[
                 0] < 30:
             self.deactivate_sweeper()
     if self.game_state is WATCHING:
         if self.timer or not (any(r.vel != (0, 0) or r.rotvel
                                   for r in self.rocks)):
             self.timer += 1
             if self.timer >= 60:
                 self.timer = 0
                 if self.throws_left:
                     self.prep_next_throw()
                 else:
                     s = self.get_end_scores()
                     print('last throw happened; here are the rocks')
                     for r in self.rocks:
                         print(r.rect.center, r.team)
                     print()
                     self.p1_score += s[0]
                     self.p2_score += s[1]
                     self.game_state = PRE_END
                     self.update_bottom_panel()
                     # if self.end == 2: # TODO
                     if self.end == 1:
                         self.end_game()