import random import sys import pygame class MondrianRectangle(object): def __init__(self, rect, colour = (255, 255, 255)): self.rect = rect self.colour = colour def __getitem__(self, key): return self.rect[key] def __setitem__(self, key, value): self.rect[key] = value def draw(self, surface): surface.fill(self.colour, self.rect) class MondrianLine(object): def __init__(self, direction = "horizontal", start_pos = (0, 0), end_pos = (0, 0), width = 0): self.direction = direction self.start_pos = start_pos self.end_pos = end_pos self.width = width def draw(self, surface): pygame.draw.line(surface, (0, 0, 0), self.start_pos, self.end_pos, self.width) def generate_random_line(): width = 5 if random.random() > 0.5: line_pos = random.randint(0, 1024) return MondrianLine("vertical", (line_pos, 0), (line_pos, 768), width) else: line_pos = random.randint(0, 768) return MondrianLine("horizontal", (0, line_pos), (1024, line_pos), width) def split_rectangles(rectangles, line): new_rectangles = [] for j, rectangle in enumerate(rectangles): if (line.direction == "horizontal" and rectangle[1] < line.start_pos[1] < rectangle[3] and min(line.start_pos[0], line.end_pos[0]) <= rectangle[0] and max(line.start_pos[0], line.end_pos[0]) >= rectangle[2] ): new_rectangles.extend([ MondrianRectangle((rectangle[0], rectangle[1], rectangle[2], line.start_pos[1])), MondrianRectangle((rectangle[0], line.start_pos[1], rectangle[2], rectangle[3])) ]) elif (line.direction == "vertical" and rectangle[0] < line.start_pos[0] < rectangle[2] and min(line.start_pos[1], line.end_pos[1]) <= rectangle[1] and max(line.start_pos[1], line.end_pos[1]) >= rectangle[3] ): new_rectangles.extend([ MondrianRectangle((rectangle[0], rectangle[1], line.start_pos[0], rectangle[3])), MondrianRectangle((line.start_pos[0], rectangle[1], rectangle[2], rectangle[3])) ]) else: new_rectangles.append(rectangle) return new_rectangles def main(): screen = pygame.display.set_mode((1024, 768)) # Step 1 lines = [] rectangles = [MondrianRectangle((0, 0, 1024, 768))] for i in range(random.randint(5, 10)): line = generate_random_line() lines.append(line) rectangles = split_rectangles(rectangles, line) #Step 2 horizontal_lines = [line for line in lines if line.direction == "horizontal"] vertical_lines = [line for line in lines if line.direction == "vertical"] for i in range(random.randint(1, 10)): if random.random() > 0.5 and len(horizontal_lines) >= 2: lines_to_join = random.sample(horizontal_lines, 2) line_pos = random.randint(0, 1024) new_line = MondrianLine( "vertical", start_pos = (line_pos, lines_to_join[0].start_pos[1]), end_pos = (line_pos, lines_to_join[1].start_pos[1]), width = 5 ) rectangles = split_rectangles(rectangles, new_line) lines.append(new_line) elif len(vertical_lines) >= 2: lines_to_join = random.sample(vertical_lines, 2) line_pos = random.randint(0, 768) new_line = MondrianLine( "horizontal", start_pos = (lines_to_join[0].start_pos[0], line_pos), end_pos = (lines_to_join[1].start_pos[0], line_pos), width = 5 ) rectangles = split_rectangles(rectangles, new_line) lines.append(new_line) #Step 3 for rectangle in random.sample(rectangles, random.randint(1, 10)): rectangle.colour = ( random.randint(0, 255), random.randint(0, 255), random.randint(0, 255) ) while True: screen.fill((255, 255, 255)) for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() [rectangle.draw(screen) for rectangle in rectangles] [line.draw(screen) for line in lines] pygame.display.flip() if __name__ == "__main__": main()