summaryrefslogtreecommitdiffstats
path: root/grid.py
blob: 9c753dbd60b29bfe514ffe5ffbb294cd317c56de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import random

from PIL import Image, ImageDraw, ImageFilter

from cell import Cell


class Grid(object):
    rows = None
    columns = None

    def __init__(self, rows, columns):
        self.rows = rows
        self.columns = columns
        self.grid = self.prepare_grid()
        self.configure_cells()

    def prepare_grid(self):
        grid = []
        for x in range(0, self.rows):
            row = []
            for y in range(0, self.columns):
                row.append(Cell(x, y))
            grid.append(row)

        return grid

    def configure_cells(self):
        for cell in self.each_cell():
            row, col = cell.row, cell.column
            cell.north = self[row - 1, col]
            cell.south = self[row + 1, col]
            cell.west  = self[row, col - 1]
            cell.east  = self[row, col + 1]

    def __getitem__(self, key):
        row, column = key
        if not 0 <= row <= self.rows - 1:
            return None

        if not 0 <= column <= len(self.grid[row]) - 1:
            return None

        return self.grid[row][column]

    def random_cell(self):
        row = random.randint(0, self.rows - 1)
        column = random.randint(0, len(self.grid[row]))
        return self[row, column]

    def size(self):
        return self.rows * self.columns

    def each_row(self):
        for row in self.grid:
            yield row

    def each_cell(self):
        for row in self.each_row():
            for cell in row:
                if cell:
                    yield cell

    def __str__(self):
        output = '+' + '---+' * self.columns + '\n'

        for row in self.each_row():
            top = '|'
            bottom = '+'

            for cell in row:
                if not cell:
                    cell = Cell(-1, -1)

                if cell.is_linked_to(cell.east):
                    east_boundary = ' '
                else:
                    east_boundary = '|'
                top = top + '   ' + east_boundary

                if cell.is_linked_to(cell.south):
                    south_boundary = '   '
                else:
                    south_boundary = '---'
                bottom = bottom + south_boundary + '+'

            output += top + '\n'
            output += bottom + '\n'

        return output

    def to_img(self, cell_size=50):
        img_width = cell_size * self.columns
        img_height = cell_size * self.rows

        img = Image.new(mode='RGB', size=(img_width + 1, img_height + 1), color='#FFFFFF')
        draw = ImageDraw.Draw(img)

        for cell in self.each_cell():
            x1 = cell.column * cell_size
            y1 = cell.row * cell_size
            x2 = (cell.column + 1) * cell_size
            y2 = (cell.row + 1) * cell_size

            if not cell.north:
                draw.line([(x1, y1), (x2, y1)], fill='#000000')

            if not cell.west:
                draw.line([(x1, y1), (x1, y2)], fill='#000000')

            if not cell.is_linked_to(cell.east):
                draw.line([(x2, y1), (x2, y2)], fill='#000000', width=4)
                draw.ellipse((x2 - 1, y1 - 1, x2 + 1, y1 + 1), fill='#000000')
                draw.ellipse((x2 - 1, y2 - 1, x2 + 1, y2 + 1), fill='#000000')

            if not cell.is_linked_to(cell.south):
                draw.line([(x1, y2), (x2, y2)], fill='#000000', width=4)
                draw.ellipse((x1 - 1, y2 - 1, x1 + 1, y2 + 1), fill='#000000')
                draw.ellipse((x2 - 1, y2 - 1, x2 + 1, y2 + 1), fill='#000000')

        img = img.filter(ImageFilter.GaussianBlur(radius=0.8))
        return img