if dx == 0:
                steps = dy  # moving on y axis only
            elif dy == 0:
                steps = dx  # moving on x axis only
            else:
                # determine max diagonal steps we can take
                # in this direction without going too far
                steps = min([dx, dy])

            keycode = ['[' + direction.compass + ']']
            jumpkeycode = ['[+' + direction.compass + ']']
            move = direction.delta()
            if not allowjumps or steps < 8 or not allow_overshoot:
                # render single movement keys
                keys.extend(keycode * steps)
                (x1, y1) = add_points((x1, y1), scale_point(move, steps))
                allow_overshoot = True
            else:
                # use DF's move-by-10-units commands
                jumps = (steps // 10)
                leftover = steps % 10
                jumpmove = scale_point(move, 10)

                # backtracking optimization
                if leftover >= 8:
                    # test if jumping an extra 10-unit step
                    # would put us outside of the bounds of
                    # the blueprint (want to prevent)
                    (xt, yt) = add_points((x1, y1), scale_point(jumpmove, (jumps + 1)))

                    if self.grid.is_out_of_bounds(xt, yt):
Ejemplo n.º 2
0
            if dx == 0:
                steps = dy  # moving on y axis only
            elif dy == 0:
                steps = dx  # moving on x axis only
            else:
                # determine max diagonal steps we can take
                # in this direction without going too far
                steps = min([dx, dy])

            keycode = ['[' + direction.compass + ']']
            jumpkeycode = ['[+' + direction.compass + ']']
            move = direction.delta()
            if not allowjumps or steps < 8 or not allow_overshoot:
                # render single movement keys
                keys.extend(keycode * steps)
                (x1, y1) = add_points((x1, y1), scale_point(move, steps))
                allow_overshoot = True
            else:
                # use DF's move-by-10-units commands
                jumps = (steps // 10)
                leftover = steps % 10
                jumpmove = scale_point(move, 10)

                # backtracking optimization
                if leftover >= 8:
                    # test if jumping an extra 10-unit step
                    # would put us outside of the bounds of
                    # the blueprint (want to prevent)
                    (xt, yt) = add_points((x1, y1),
                                          scale_point(jumpmove, (jumps + 1)))
Ejemplo n.º 3
0
    def find_largest_area_in_quad(self, x, y, dir1, dir2, bestarea):
        """
        Given the quad starting at (x, y) and formed by dir1 and dir2
        (treated as rays with (x, y) as origin), we find the max
        contiguous-cell distance along dir1, then for each position
        along dir1, we find the max contiguous-cell distance along
        dir2. This allows us to find the largest contiguous area
        constructable by travelling down dir1, then at a right angle
        along dir2 for each position.

        Returns the largest area found.
        """

        command = self.grid.get_cell(x, y).command

        # Get the min/max size that this area may be, based on the command
        sizebounds = self.buildconfig.get('sizebounds', command) \
            or (1, 1000, 1, 1000)  # default sizebounds are very large

        # Get the max width of this area on the axis defined by
        # pos and dir1 direction, and max width from
        # the dir2.
        # width and height are conceptually aligned to an
        # east(dir1) x south(dir2) quad below.
        maxwidth = self.grid.count_contiguous_cells(x, y, dir1)
        maxheight = self.grid.count_contiguous_cells(x, y, dir2)

        if maxwidth < sizebounds[0]:
            # constructions narrower than the minimum width for this
            # command are ineligible to be any larger than 1 wide
            maxwidth = 1
        elif maxwidth > sizebounds[1]:
            # don't let constructions be wider than allowed
            maxwidth = sizebounds[1]

        if maxheight < sizebounds[2]:
            # constructions shorter than the minimum height for this
            # command are ineligible to be any larger than 1 tall
            maxheight = 1
        elif maxheight > sizebounds[3]:
            # don't let constructions be taller than allowed
            maxheight = sizebounds[3]

        if maxwidth * maxheight < bestarea.size():
            return None  # couldn't be larger than the best one yet found

        if maxheight == 1 and maxwidth == 1:
            # 1x1 area, just return it
            return Area((x, y), (x, y))

        # (width x 1) sized area
        bestarea = Area((x, y),
                        add_points((x, y),
                                   scale_point(dir1.delta(), maxwidth - 1)))

        for ydelta in range(1, maxheight):
            (xt, yt) = add_points((x, y), scale_point(dir2.delta(), ydelta))

            height = ydelta + 1
            width = self.grid.count_contiguous_cells(xt, yt, dir1)

            if width > maxwidth:
                # this row can't be wider than previous rows
                width = maxwidth
            elif width < maxwidth:
                # successive rows can't be wider than this row
                maxwidth = width

            if width * height > bestarea.size():
                bestarea = Area((x, y),
                                add_points((xt, yt),
                                           scale_point(dir1.delta(),
                                                       width - 1)))
            else:
                continue

        return bestarea
Ejemplo n.º 4
0
    def find_largest_area_in_quad(self, x, y, dir1, dir2, bestarea):
        """
        Given the quad starting at (x, y) and formed by dir1 and dir2
        (treated as rays with (x, y) as origin), we find the max
        contiguous-cell distance along dir1, then for each position
        along dir1, we find the max contiguous-cell distance along
        dir2. This allows us to find the largest contiguous area
        constructable by travelling down dir1, then at a right angle
        along dir2 for each position.

        Returns the largest area found.
        """

        command = self.grid.get_cell(x, y).command

        # Get the min/max size that this area may be, based on the command
        sizebounds = self.buildconfig.get('sizebounds', command) \
            or (1, 1000, 1, 1000)  # default sizebounds are very large

        # Get the max width of this area on the axis defined by
        # pos and dir1 direction, and max width from
        # the dir2.
        # width and height are conceptually aligned to an
        # east(dir1) x south(dir2) quad below.
        maxwidth = self.grid.count_contiguous_cells(x, y, dir1)
        maxheight = self.grid.count_contiguous_cells(x, y, dir2)

        if maxwidth < sizebounds[0]:
            # constructions narrower than the minimum width for this
            # command are ineligible to be any larger than 1 wide
            maxwidth = 1
        elif maxwidth > sizebounds[1]:
            # don't let constructions be wider than allowed
            maxwidth = sizebounds[1]

        if maxheight < sizebounds[2]:
            # constructions shorter than the minimum height for this
            # command are ineligible to be any larger than 1 tall
            maxheight = 1
        elif maxheight > sizebounds[3]:
            # don't let constructions be taller than allowed
            maxheight = sizebounds[3]

        if maxwidth * maxheight < bestarea.size():
            return None  # couldn't be larger than the best one yet found

        if maxheight == 1 and maxwidth == 1:
            # 1x1 area, just return it
            return Area((x, y), (x, y))

        # (width x 1) sized area
        bestarea = Area((x, y),
            add_points(
                (x, y),
                scale_point(dir1.delta(), maxwidth - 1)
            )
        )

        for ydelta in range(1, maxheight):
            (xt, yt) = add_points(
                (x, y),
                scale_point(dir2.delta(), ydelta)
            )

            height = ydelta + 1
            width = self.grid.count_contiguous_cells(xt, yt, dir1)

            if width > maxwidth:
                # this row can't be wider than previous rows
                width = maxwidth
            elif width < maxwidth:
                # successive rows can't be wider than this row
                maxwidth = width

            if width * height > bestarea.size():
                bestarea = Area((x, y),
                    add_points(
                        (xt, yt),
                        scale_point(dir1.delta(), width - 1)
                    )
                )
            else:
                continue

        return bestarea