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