-
Notifications
You must be signed in to change notification settings - Fork 0
/
GridVisualizer.py
129 lines (105 loc) · 5.12 KB
/
GridVisualizer.py
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
123
124
125
126
127
128
129
import math
import random as rnd
import sys
from itertools import product
import numpy as np
import pygame
class Grid:
"""Used to read and write values to a Grid"""
def __init__(self, width, height):
self.height = height
self.width = width
# define your stored datatype here (dtype=):
self.matrix = np.zeros((width, height), dtype=np.int32)
def getDimensions(self):
return self.width, self.height
# will return whether (x,y) is inside the grid(valid)
def valid_cell(self, x, y):
return 0 <= x < self.width and 0 <= y < self.height
# will return False, if cell outside the grid is accessed
def set(self, x, y, value):
if self.valid_cell(x, y):
self.matrix[x][y] = value
return True
else:
return False
# will return 'None' if a value outside the grid is accessed
def get(self, x, y):
if self.valid_cell(x, y):
return self.matrix[x][y]
# will fill the grid with random values from [a, b]
def setRndValues(self, a, b):
for x, y in product(range(self.width), range(self.height)):
self.set(x, y, rnd.randint(a, b))
class Visualizer:
# TODO: Change Grid's size while visualizing
def __init__(self, g: Grid, window_width, window_height, border_size, window_name="Grid Visualizer"):
self.g = g
self.border_size = border_size
self.screen = pygame.display.set_mode((window_width, window_height), pygame.RESIZABLE)
self.border_window_ratio = self.border_size / window_width
self.__update_window_size(window_width, window_height)
# default color_layout (TODO: method to change color_layout)
self.color_layout = {0: pygame.Color("black"),
1: pygame.Color("white")}
pygame.init()
pygame.display.set_caption(window_name)
# updates variables, according to (new) window size
def __update_window_size(self, window_width, window_height):
window_width, window_height = self.get_max_grid_size(window_width, window_height)
self.border_size = math.ceil(window_width * self.border_window_ratio)
print(self.border_size)
self.cell_size = min(Visualizer.get_max_cell_size(self.g.width, self.border_size, window_width),
Visualizer.get_max_cell_size(self.g.height, self.border_size, window_height))
self.res_x = Visualizer.get_window_size(self.g.width, self.border_size, self.cell_size)
self.res_y = Visualizer.get_window_size(self.g.height, self.border_size, self.cell_size)
print((self.res_x, self.res_y), (window_width, window_height))
# call this to redraw the grid
def update(self):
self.screen.fill((255, 255, 255))
self.__draw_grid()
pygame.display.update()
# call this with pygame.event.get())
def handle_events(self, events):
for e in events:
if e.type == pygame.QUIT:
pygame.quit()
sys.exit()
if e.type == pygame.VIDEORESIZE:
self.screen = pygame.display.set_mode((e.size[0], e.size[1]), pygame.RESIZABLE)
self.__update_window_size(e.size[0], e.size[1])
self.update()
def __draw_grid(self):
# draw cells
for x, y in product(range(self.g.width), range(self.g.height)):
# rnd_color = (rnd.randint(1, 255), rnd.randint(1, 255), rnd.randint(1, 255))
c = self.color_layout[self.g.get(x, y)]
x0 = (x * (self.border_size + self.cell_size) + self.border_size)
y0 = (y * (self.border_size + self.cell_size) + self.border_size)
pygame.draw.rect(self.screen, c,
pygame.Rect(x0, y0, math.ceil(self.cell_size),
math.ceil(self.cell_size)))
# draw cell borders
for x in range(self.g.width + 1):
for o in range(self.border_size):
x0 = (x * (self.border_size + self.cell_size)) + o
pygame.draw.line(self.screen, (0, 0, 0), (x0, 0), (x0, self.res_y - 1), 1)
for y in range(self.g.height + 1):
for o in range(self.border_size):
y0 = (y * (self.border_size + self.cell_size)) + o
pygame.draw.line(self.screen, (0, 0, 0), (0, y0), (self.res_x - 1, y0), 1)
@staticmethod
def get_max_cell_size(cell_count, border_size, window_size):
return math.floor(window_size - ((cell_count + 1) * border_size)) / cell_count
@staticmethod
def get_window_size(cell_count, border_size, cell_size):
return ((cell_count + 1) * border_size) + (cell_count * cell_size)
def get_max_grid_size(self, w, h):
h_size = Visualizer.get_max_cell_size(self.g.width, self.border_size, w)
v_size = Visualizer.get_max_cell_size(self.g.height, self.border_size, h)
if h_size < v_size:
new_h = Visualizer.get_window_size(self.g.height, self.border_size, h_size)
return w, new_h
else:
new_w = Visualizer.get_window_size(self.g.width, self.border_size, v_size)
return new_w, h