КУРСАЧ / ТП КР Пояснительная записка
.pdffont.setFamily("Times New Roman") font.setPointSize(20) self.label_3.setFont(font)
self.label_3.setAlignment(QtCore.Qt.AlignCenter) self.label_3.setObjectName("label_3") self.verticalLayout.addWidget(self.label_3)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem) self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
self.horizontalLayout_5.setObjectName("horizontalLayout_5") self.verticalLayout_4 = QtWidgets.QVBoxLayout() self.verticalLayout_4.setObjectName("verticalLayout_4") self.label = QtWidgets.QLabel(self.centralwidget)
font = QtGui.QFont() font.setFamily("Times New Roman") font.setPointSize(14) self.label.setFont(font) self.label.setObjectName("label")
self.verticalLayout_4.addWidget(self.label)
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_4.addItem(spacerItem1) self.label_2 = QtWidgets.QLabel(self.centralwidget) font = QtGui.QFont()
font.setFamily("Times New Roman") font.setPointSize(14) self.label_2.setFont(font) self.label_2.setObjectName("label_2") self.verticalLayout_4.addWidget(self.label_2)
self.horizontalLayout_5.addLayout(self.verticalLayout_4) self.verticalLayout_5 = QtWidgets.QVBoxLayout() self.verticalLayout_5.setObjectName("verticalLayout_5") self.spinBox = QtWidgets.QSpinBox(self.centralwidget)
31
font = QtGui.QFont() font.setFamily("Times New Roman") font.setPointSize(14) self.spinBox.setFont(font) self.spinBox.setMinimum(3) self.spinBox.setMaximum(50) self.spinBox.setProperty("value", 15) self.spinBox.setObjectName("spinBox")
self.verticalLayout_5.addWidget(self.spinBox)
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_5.addItem(spacerItem2) self.spinBox_2 = QtWidgets.QSpinBox(self.centralwidget) font = QtGui.QFont()
font.setFamily("Times New Roman") font.setPointSize(14) font.setBold(False) font.setWeight(50) font.setKerning(True) self.spinBox_2.setFont(font)
self.spinBox_2.setFocusPolicy(QtCore.Qt.WheelFocus) self.spinBox_2.setMinimum(3) self.spinBox_2.setMaximum(50) self.spinBox_2.setProperty("value", 10) self.spinBox_2.setObjectName("spinBox_2") self.verticalLayout_5.addWidget(self.spinBox_2) self.horizontalLayout_5.addLayout(self.verticalLayout_5) self.verticalLayout.addLayout(self.horizontalLayout_5) spacerItem3 = QtWidgets.QSpacerItem(20, 40,
QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem3) self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3") |
|
||
spacerItem4 |
= |
QtWidgets.QSpacerItem(40, |
20, |
|
|
|
|
|
|
32 |
|
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem4) self.startButton =
QtWidgets.QPushButton(self.centralwidget)
self.startButton.setEnabled(True) font = QtGui.QFont() font.setFamily("Times New Roman") font.setPointSize(16) self.startButton.setFont(font)
self.startButton.setObjectName("startButton") self.horizontalLayout_3.addWidget(self.startButton) spacerItem5 = QtWidgets.QSpacerItem(40, 20,
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem5) self.verticalLayout.addLayout(self.horizontalLayout_3) self.verticalLayout_2.addLayout(self.verticalLayout) spacerItem6 = QtWidgets.QSpacerItem(20, 40,
QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem6)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.start_functions()
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow",
"Генерация и поиск")) self.label_3.setText(_translate("MainWindow", "Генерация
карты местности и\n"
"нахождение кратчайшего пути")) self.label.setText(_translate("MainWindow", "Количество
столбцов карты"))
33
self.label_2.setText(_translate("MainWindow", "уоличество строк карты"))
self.startButton.setText(_translate("MainWindow", "Начать генерацию карты"))
def start_functions(self): self.startButton.clicked.connect(lambda:
self.t1(self.spinBox.value(), self.spinBox_2.value()))
def t1(self, cols, rows): self.startButton.setEnabled(False)
self.startButton.setText('Закройте окно карты, чтобы сгенерировать заново')
t1 = Thread(target=draw_best_way, args=(cols, rows, self)) t1.start()
if __name__ == "__main__": import sys
app = QtWidgets.QApplication(sys.argv) w = QtWidgets.QMainWindow()
ui = Ui_MainWindow() ui.setupUi(w) w.show() sys.exit(app.exec_())
Листинг А.2 – Код функции «draw_best_way»
def draw_best_way(cols, rows, self): WIDTH, HEIGHT = 1000, 600 TILE_WIDTH = WIDTH // cols TILE_HEIGHT = HEIGHT // rows
RES = WIDTH, HEIGHT = TILE_WIDTH * cols, TILE_HEIGHT * rows +
50
colors = {1 : '#b5a858', 2 : '#cedf88', 4 : '#90af0a', 7 : '#09af83', 9 : '#ab9494'}
34
grid_exampl = [[2, 2, 2, 2, 2, 2], [1, 1, 1, 2, 2, 4], [2, 9, 1, 1, 4, 4], [7, 7, 7, 1, 4, 4], [7, 7, 7, 1, 2, 4], [7, 7, 9, 1, 1, 9]]
grid = []
start = (0, int(rows / 2)) |
# Начальная точка |
|
||
goal = start |
# Точка назначения |
|
||
visited = {start: None} |
# Список посещенных клеток |
|||
pg.init() |
# Инициируем окно |
|
||
sc = pg.display.set_mode(RES) |
# Устанавливаем разрешение |
|||
окна |
|
|
|
|
pg.display.set_caption("Поиск |
кротчайшего |
пути |
на |
|
сгенерированной карте местности") |
# Устанавливаем заголовок |
|||
clock = pg.time.Clock() |
# Инициируем таймер |
|
||
while True: |
|
|
|
|
if grid == []: |
|
|
|
|
text_on_screen(sc, |
'Times |
New |
Roman', |
30, |
'Loading...', (255, 255, 255), WIDTH // 2 - 50, HEIGHT // 2 - 50)
grid = wfc(grid_exampl, cols, rows) graph = build_graph(grid)
else:
sc.fill((0, 0, 0))
# Отрисовывыем поле
fill_screen(sc, cols, rows, TILE_WIDTH, TILE_HEIGHT, grid, colors)
# Получаем кординату точки и находим кратчайший путь mouse_pos = get_click_mouse_pos(TILE_WIDTH,
TILE_HEIGHT, HEIGHT, sc)
if mouse_pos and mouse_pos != goal:
visited = dijkstra(start, mouse_pos, graph) goal = mouse_pos
35
# Отрисовываем кратчайший путь
path_head, path_segment = goal, visited[goal] x, y = path_head
path_time = 0 if path_segment is None else grid[y][x] path_step = 0 if path_segment is None else 1
while path_segment != start and path_segment: draw_circle(sc, *path_segment, 'blue',
TILE_HEIGHT, TILE_WIDTH)
# Подсчет количества необходимых шагов и времени
на путь
x, y = path_segment path_time += grid[y][x] path_step += 1
path_segment = visited[path_segment]
# Отрисовываем начало и конец пути
draw_circle(sc, *start, 'green', TILE_HEIGHT,
TILE_WIDTH)
draw_circle(sc, *path_head, 'magenta', TILE_HEIGHT,
TILE_WIDTH)
text_on_screen(sc, 'Times New Roman', 25, 'Кратчайший путь состоит из ' + str(path_step) + ' шаг(-а/-ов) и занимает ' + str(path_time) + ' единиц времени.',
(255, 255, 255), 20, HEIGHT - 40)
# pygame necessary lines events = pg.event.get() for event in events:
if event.type == pg.QUIT: self.startButton.setEnabled(True)
36
self.startButton.setText('Начать генерацию
карты')
pg.display.quit() return
pg.display.flip()
clock.tick(60)
Листинг А.4 – Код функции «wfc»
def wfc(example, output_cols, output_rows): input_size = (len(example), len(example[0])) output_size = (output_rows, output_cols)
N = 2 |
# Размер паnтерна |
patterns = [] |
# Хранит паттерны размера N*N |
weights = {} # Словарь количества появлений каждого паттерна в примере
{паттерн: кол-во в примере}
parse_patterns(input_size, example, weights, patterns, N) # Разделяем пример на уникальные паттерны (patterns) и находим сколько раз встречается каждый паттерн в примере (weights)
sum_of_weights = sum(weights.values()) patterns = [Pattern(p) for p in patterns]
weights = {pattern : weights[pattern.pixels] for pattern in patterns} # Кол-во probability = {pattern : weights[pattern] / sum_of_weights for pattern in patterns}
# Вероятность появлении паттерна в выходном массиве карты местности
directions = [(0, -1), (-1, 0), (0, 1), (1, 0), (-1, -1), (1, -1), (-1, 1), (1, 1)]
index = Index(patterns, directions) # Записываем паттерны и направления возможных пресоендинений других паттернов для каждого паттерна
37
rule_generator(patterns, directions, index) # Записываем в index для каждого паттерна по каждому направлению набор паттернов которые можно к нему присоединить
coefficients = initialize_wave_function(output_size, patterns) attempt_count = 0
while not is_fully_collapsed(coefficients): min_entropy_pos = observe(probability, coefficients)
failed_generation = propagate(min_entropy_pos, coefficients, output_size, index)
if failed_generation == None:
print('Неудачная генерация( Пробуем снова') attempt_count += 1
if attempt_count > 5: return [[example[0][0] for x in range(output_cols)]for y in range(output_rows)]
coefficients = initialize_wave_function(output_size, patterns) return final_pixels_map(coefficients)
Листинг А.5 – Код функции «propagate»
def propagate(min_entropy_pos, coefficients, output_size, index): stack = [min_entropy_pos]
while len(stack) > 0: pos = stack.pop()
possible_patterns =
get_possible_patterns_at_position(pos, coefficients)
# Перебирать каждое местоположение, непосредственно примыкающее к текущему местоположению (pos)
for d in valid_dirs(pos, output_size):
38
adjacent_pos = (pos[0] + d[0], pos[1] + d[1]) possible_patterns_at_adjacent =
get_possible_patterns_at_position(adjacent_pos, coefficients)
# Iterate over all still available patterns in adjacent tile and check if pattern is still possible in this location
if not isinstance(possible_patterns_at_adjacent,
list):
possible_patterns_at_adjacent = [possible_patterns_at_adjacent]
for possible_pattern_at_adjacent in possible_patterns_at_adjacent:
if len(possible_patterns) > 1:
is_possible = any([index.check_possibility(pattern, possible_pattern_at_adjacent, d) for pattern in possible_patterns])
else:
is_possible = index.check_possibility(possible_patterns, possible_pattern_at_adjacent, d)
if is_possible is None: return None
if not is_possible:
x, y = adjacent_pos
coefficients[x][y] = [patt for patt in coefficients[x][y] if patt.pixels != possible_pattern_at_adjacent.pixels]
if adjacent_pos not in stack: stack.append(adjacent_pos)
return 1
39