View difference between Paste ID: xhGSnBFz and
SHOW: | | - or go back to the newest paste.
1-
1+
import random
2
import sys
3
import pygame
4
5
class MondrianRectangle(object):
6
    def __init__(self, rect, colour = (255, 255, 255)):
7
        self.rect = rect
8
        self.colour = colour
9
10
    def __getitem__(self, key):
11
        return self.rect[key]
12
13
    def __setitem__(self, key, value):
14
        self.rect[key] = value
15
    
16
    def draw(self, surface):
17
        surface.fill(self.colour, self.rect)
18
        
19
20
class MondrianLine(object):
21
    def __init__(self, direction = "horizontal", start_pos = (0, 0), end_pos = (0, 0), width = 0):
22
        self.direction = direction
23
        self.start_pos = start_pos
24
        self.end_pos = end_pos
25
        self.width = width
26
27
    def draw(self, surface):
28
        pygame.draw.line(surface, (0, 0, 0), self.start_pos, self.end_pos, self.width)
29
30
31
def generate_random_line():
32
    width = 5
33
    if random.random() > 0.5:
34
        line_pos = random.randint(0, 1024)
35
        return MondrianLine("vertical", (line_pos, 0), (line_pos, 768), width)
36
    else:                     
37
        line_pos = random.randint(0, 768)
38
        return MondrianLine("horizontal", (0, line_pos), (1024, line_pos), width)
39
40
41
def split_rectangles(rectangles, line):
42
    new_rectangles = []
43
    for j, rectangle in enumerate(rectangles):
44
        if (line.direction == "horizontal" and 
45
            rectangle[1] < line.start_pos[1] < rectangle[3] and 
46
            min(line.start_pos[0], line.end_pos[0]) <= rectangle[0] and 
47
            max(line.start_pos[0], line.end_pos[0]) >= rectangle[2]
48
        ):
49
            new_rectangles.extend([
50
                MondrianRectangle((rectangle[0], rectangle[1], rectangle[2], line.start_pos[1])),
51
                MondrianRectangle((rectangle[0], line.start_pos[1], rectangle[2], rectangle[3]))
52
            ])
53
54
        elif (line.direction == "vertical" and 
55
            rectangle[0] < line.start_pos[0] < rectangle[2] and
56
            min(line.start_pos[1], line.end_pos[1]) <= rectangle[1] and
57
            max(line.start_pos[1], line.end_pos[1]) >= rectangle[3]
58
        ):
59
            new_rectangles.extend([
60
                MondrianRectangle((rectangle[0], rectangle[1], line.start_pos[0], rectangle[3])),
61
                MondrianRectangle((line.start_pos[0], rectangle[1], rectangle[2], rectangle[3]))
62
            ])
63
64
        else:
65
            new_rectangles.append(rectangle)
66
67
    return new_rectangles
68
69
70
def main():
71
    screen = pygame.display.set_mode((1024, 768))
72
73
    # Step 1
74
    lines = []
75
    rectangles = [MondrianRectangle((0, 0, 1024, 768))]
76
    for i in range(random.randint(5, 10)):
77
        line = generate_random_line()
78
        lines.append(line)
79
        rectangles = split_rectangles(rectangles, line)
80
81
    #Step 2
82
    horizontal_lines = [line for line in lines if line.direction == "horizontal"]
83
    vertical_lines = [line for line in lines if line.direction == "vertical"]
84
85
    for i in range(random.randint(1, 10)):
86
        if random.random() > 0.5 and len(horizontal_lines) >= 2:
87
            lines_to_join = random.sample(horizontal_lines, 2)
88
            line_pos = random.randint(0, 1024)
89
            new_line = MondrianLine(
90
                "vertical", 
91
                start_pos = (line_pos, lines_to_join[0].start_pos[1]),
92
                end_pos = (line_pos, lines_to_join[1].start_pos[1]),
93
                width = 5
94
            )
95
            rectangles = split_rectangles(rectangles, new_line)
96
            lines.append(new_line)
97
        elif len(vertical_lines) >= 2:
98
            lines_to_join = random.sample(vertical_lines, 2)
99
            line_pos = random.randint(0, 768)
100
            new_line = MondrianLine(
101
                "horizontal", 
102
                start_pos = (lines_to_join[0].start_pos[0], line_pos),
103
                end_pos = (lines_to_join[1].start_pos[0], line_pos),
104
                width = 5
105
            )
106
            rectangles = split_rectangles(rectangles, new_line)
107
            lines.append(new_line)
108
     
109
    #Step 3
110
    for rectangle in random.sample(rectangles, random.randint(1, 10)):
111
        rectangle.colour = (
112
            random.randint(0, 255), 
113
            random.randint(0, 255),
114
            random.randint(0, 255)
115
        )
116
    
117
    while True:
118
        screen.fill((255, 255, 255))
119
        for event in pygame.event.get():
120
            if event.type == pygame.QUIT: sys.exit()
121
        [rectangle.draw(screen) for rectangle in rectangles]
122
        [line.draw(screen) for line in lines]
123
        pygame.display.flip()
124
 
125
126
if __name__ == "__main__":
127
    main()