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):
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)))
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
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