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