SHARE
TWEET

Untitled

a guest Feb 14th, 2020 71 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import numpy
  2. import pprint
  3.  
  4.  
  5. class ImageLayer(object):
  6.   """
  7.   Represents a layer of an image
  8.   """
  9.   def __init__(self, x_shape, y_shape, fill_character, left_x, top_y, right_x, bottom_y):
  10.     self.x_shape = x_shape
  11.     self.y_shape = y_shape
  12.     self.fill_character = fill_character
  13.     self.canvas = self._build_canvas(left_x, top_y, right_x, bottom_y)
  14.  
  15.   def _verify_coords(self, x, y):
  16.     # Check that the co-ordinates are valid
  17.     if x<0 or x>=self.x_shape or y<0 or y>=self.y_shape:
  18.       raise ValueError(f'[{x}, {y}] is outside the bounds')
  19.  
  20.   def _build_canvas(self, left_x, top_y, right_x, bottom_y):
  21.     self._verify_coords(left_x, top_y)
  22.     self._verify_coords(right_x, bottom_y)
  23.     # Create the initial canvas for the layer
  24.     canvas = numpy.zeros(shape=(self.x_shape, self.y_shape))
  25.     canvas[left_x:right_x+1, top_y:bottom_y+1] = numpy.ones(shape=(right_x-left_x+1, bottom_y-top_y+1))
  26.     return canvas
  27.  
  28.   def erase_area(self, left_x, top_y, right_x, bottom_y):
  29.     """
  30.     Erase a section of the layer
  31.     """
  32.     self._verify_coords(left_x, top_y)
  33.     self._verify_coords(right_x, bottom_y)
  34.     self.canvas[left_x:right_x+1, top_y:bottom_y+1] = numpy.zeros(shape=(right_x-left_x+1, bottom_y-top_y+1))
  35.  
  36.   def hit(self, select_x, select_y):
  37.     """
  38.     Check if the layer has any content at these co-ordinates
  39.     """
  40.     self._verify_coords(select_x, select_y)
  41.     return self.canvas[select_x, select_y] == 1
  42.  
  43.   def drag_and_drop(self, move_x, move_y):
  44.     """
  45.     Roll the canvas to move the position of the rectangle
  46.     """
  47.     # This will wrap rectanges around the maximums
  48.     self.canvas = numpy.roll(self.canvas, move_x, axis=0)
  49.     self.canvas = numpy.roll(self.canvas, move_y, axis=1)
  50.  
  51.  
  52. class Image(object):
  53.   """
  54.   Represents an image with multiple layers
  55.   """
  56.   def __init__(self, x_shape=10, y_shape=6):
  57.     self.x_shape = x_shape
  58.     self.y_shape = y_shape
  59.     self.layers = []
  60.  
  61.   def draw_rectangle(self, fill_character, left_x, top_y, right_x, bottom_y):
  62.     """
  63.     Creates a new layer on top with the specified rectangle on it
  64.     """
  65.     new_layer = ImageLayer(
  66.       self.x_shape,
  67.       self.y_shape,
  68.       fill_character,
  69.       left_x,
  70.       top_y,
  71.       right_x,
  72.       bottom_y
  73.     )
  74.     self.layers = [new_layer] + self.layers
  75.  
  76.   def erase_area(self, left_x, top_y, right_x, bottom_y):
  77.     """
  78.     Erase the area on all layers
  79.     """
  80.     for layer in self.layers:
  81.       layer.erase_area(left_x, top_y, right_x, bottom_y)
  82.  
  83.   def drag_and_drop(self, select_x, select_y, release_x, release_y):
  84.     """
  85.     Move the top layer
  86.     """
  87.     for layer in self.layers:
  88.       if layer.hit(select_x, select_y):
  89.         layer.drag_and_drop(release_x-select_x, release_y-select_y)
  90.         return
  91.  
  92.   def bring_to_front(self, select_x, select_y):
  93.     """
  94.     Move the selected layer to the top of the stack
  95.     """
  96.     for i, layer in enumerate(self.layers):
  97.       if layer.hit(select_x, select_y):
  98.         self.layers.pop(i)
  99.         self.layers = [layer] + self.layers
  100.         return
  101.  
  102.   def print_canvas(self):
  103.     """
  104.     Return an array of arrays with the rendered content
  105.     """
  106.     canvas = numpy.zeros(shape=(self.x_shape, self.y_shape)).tolist()
  107.     for layer in reversed(self.layers):
  108.       for i in range(self.x_shape):
  109.         for j in range(self.y_shape):
  110.           if layer.canvas[i, j] == 1:
  111.             canvas[i][j] = layer.fill_character
  112.  
  113.     # This can probably done when initializing the canvas.
  114.     # The solution is somewhere in the numpy docs.
  115.     for i in range(self.x_shape):
  116.       for j in range(self.y_shape):
  117.         if canvas[i][j] == 0:
  118.           canvas[i][j] = ' '
  119.     return canvas
  120.  
  121.  
  122. def command_parser():
  123.   # Parses the file in to the format:
  124.   # ["COMMAND", [*command_args]]
  125.   # BELOW IS HARDCODED EXAMPLE I USED FOR DEBUGGING:
  126.   return [
  127.     ['DRAW_RECTANGLE',['L',1,1,4,4]],
  128.     ['DRAW_RECTANGLE',['R',2,1,4,4]],
  129.     ['PRINT_CANVAS',[]],
  130.     ['ERASE_AREA',[3,2,3,3]],
  131.     ['PRINT_CANVAS',[]],
  132.     ['DRAW_RECTANGLE',['#',1,3,8,4]],
  133.     ['DRAG_AND_DROP',[2,2,6,2]],
  134.     ['PRINT_CANVAS',[]],
  135.     ['BRING_TO_FRONT',[1,2]],
  136.     ['BRING_TO_FRONT',[6,2]],
  137.     ['PRINT_CANVAS',[]],
  138.     ['DRAG_AND_DROP',[3,3,3,2]],
  139.     ['PRINT_CANVAS',[]],
  140.   ]
  141.  
  142.  
  143. def main():
  144.   # Parse the command list
  145.   command_list = command_parser()
  146.   # create an empty image
  147.   image = Image(10, 6)
  148.  
  149.   # For each command apply it to the command list
  150.   for command, command_args in command_list:
  151.     if command == 'DRAW_RECTANGLE':
  152.       image.draw_rectangle(*command_args)
  153.     elif command == 'ERASE_AREA':
  154.       image.erase_area(*command_args)
  155.     elif command == 'DRAG_AND_DROP':
  156.       image.drag_and_drop(*command_args)
  157.     elif command == 'BRING_TO_FRONT':
  158.       image.bring_to_front(*command_args)
  159.     elif command == 'PRINT_CANVAS':
  160.       pprint.pprint(image.print_canvas())
  161.  
  162.  
  163. if __name__ == '__main__':
  164.   main()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top