Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

КУРСАЧ / ТП КР Пояснительная записка

.pdf
Скачиваний:
2
Добавлен:
25.06.2023
Размер:
394.2 Кб
Скачать

Функция initialize_wave_function возвращает массив размером size каждый элемент которого заполнен списком всех возможных паттернов. Код функции в соответствии с листингом 16.

Листинг 16 – Код функции «initialize_wave_function»

def initialize_wave_function(size, patterns): coefficients = []

for col in range(size[0]): row = []

for r in range(size[1]): row.append(patterns) coefficients.append(row)

return coefficients

Функция is_fully_collapsed проверяет всели элементы массива coefficients

имеют только одно значение. Код функции в соответствии с листингом 17.

Листинг 17 – Код функции «is_fully_collapsed»

def is_fully_collapsed(coefficients):

for col in coefficients:

for entry in col:

if(len(entry)>1):

return False

return True

21

Функция observe определяет координаты клетки карты с наименьшей энтропией. Зазывает в coefficients по указынным координатам один случайный паттерн из доступных для нее. Затем возвращает координаты данной клетки. Код функции в соответствии с листингом 18.

Листинг 18 – Код функции «observe»

def observe(probability, coefficients):

min_entropy_pos = get_min_entropy_pos(coefficients, probability)

if min_entropy_pos == None: print("All tiles have 0 entropy") return

semi_random_pattern = random.choice(get_possible_patterns_at_position(min_entropy_pos, coefficients))

coefficients[min_entropy_pos[0]][min_entropy_pos[1]] = semi_random_pattern

return min_entropy_po

22

Функция get_min_entropy_pos проходит по массиву coefficients вычисляет для каждого значения энтропию функцией get_shannon_entropy, определяет у кого она наименьшая и возвращает его координаты. Код функции в соответствии с листингом 19.

Листинг 19 – Код функции «get_min_entropy_pos»

def get_min_entropy_pos(coefficients, probability): minEntropy = None

minEntropyPos = None

for x, col in enumerate(coefficients): for y, row in enumerate(col):

entropy = get_shannon_entropy((x, y), coefficients,

probability)

if entropy == 0: continue

if minEntropy is None or entropy < minEntropy: minEntropy = entropy

minEntropyPos = (x, y) return minEntropyPos

Функция get_min_entropy_pos высчитывает и возвращает энтропию Шеннона и добавляет к ней шума для более случайного результат генерации. Код функции в соответствии с листингом 20.

Листинг 20 – Код функции «get_min_entropy_pos»

def get_shannon_entropy(position, coefficients, probability): x, y = position

entropy = 0

if len(coefficients[x][y]) == 1: return 0

for pattern in coefficients[x][y]:

entropy += probability[pattern] * math.log(probability[pattern], 2)

entropy *= -1

entropy -= random.uniform(0, 0.1) return entropy

23

Функция propagate проходит циклом по всем соседям сколлапсированной клетки и обновляет списки возможных паттернов для них. На каждой итерации цикла получает текущие возможные паттерны для каждого соседа с помощью функции get_possible_patterns_at_position, а затем проверяет с помощью функции check_possibility класса Index каждый из паттернов на валидность при условии сколлапсировавшей ячейки по соседству. Код функции в соответствии с листингом А.5 приложения А.

Функция get_possible_patterns_at_position возвращает все значения паттернов из coefficients по указанному адресу. Код функции в соответствии с листингом 21.

Листинг 1 – Фрагмент функции «get_possible_patterns_at_position»

def get_possible_patterns_at_position(position, coefficients):

x, y = position

possible_patterns = coefficients[x][y] return possible_patterns

Функция final_pixels_map создает карту местности final_pixels из элементов паттернов по индексу [0][0], оставшихся в списке coefficients после его коллапсирования и возвращает его. Код функции в соответствии с листингом 22.

Листинг 22 – Код функции «final_pixels_map»

def final_pixels_map(coefficients): final_pixels = []

for i in coefficients: row = []

for j in i:

if isinstance(j, list):

first_pixel = j[0].pixels[0][0] else:

first_pixel = j.pixels[0][0] row.append(first_pixel)

final_pixels.append(row) return final_pixels

24

Для реализации использовался Python версии 3.10.0.

25

3 Примеры работы приложения

Реализовали оконное приложение, в котором можно выбрать размер генерируемой карты местности и сгенерировать ее, а потом на ней находить оптимальные пути до нужных точек.

На рисунке 1 изображен интерфейс стартового меню, в котором можно выбрать размер карты для генерации генерация начинается после нажатия кнопки в нижней части окна, созданный с помощью PyQt.

Рисунок 1 – Интерфейс стартового меню На рисунке 2 изображен интерфейс окна с картой местности и поиском

оптимального пути, созданный с помощью Pygame. Карта местности отображается после генерации и затем на ней мышкой можно выбрать точку, до которой мы хотим построить маршрут. Информация о построенном маршруте отображается в нижней части экрана.

Рисунок 2 – Интерфейс экрана карты

26

В программе учтены все возможные крайние случаи, которые могут вызвать ошибку или привести к некорректному выводу данных. Пользователь может генерировать несколько карт местности за один сеанс работы программы.

Для этого необходимо закрыть окно карты местности и нажать кнопку начала генерации в стартовом меню, не закрыв окно карты не удастся сгенерировать новую карту так как во время работы окна карты кнопка генерации в окне меню не активна.

27

ЗАКЛЮЧЕНИЕ

В ходе выполнения данной курсовой работы были изучены алгоритмы процедурной генерации и поиска кратчайшего пути в графе, выбраны наиболее подходящие для решения поставленной задачи и применены в реализации оконного приложения с генерацией карты местности алгоритмом коллапса волновой функции и поиском кратчайшего пути с помощью алгоритма А*.

Программа написана на языке программирования Python и может быть запущена на любом компьютере, имеющем интерпретатор для установленной на нем операционной системы.

Удобный интерфейс позволяет легко ориентироваться в программе.

Таким образом, основная цель работы была достигнута и все задачи успешно выполнены.

При необходимости есть возможность расширить возможности разработанного приложения, а именно добавить в него возможность загружать в него свои примеры карт местности для тестирования на различных наборах паттернов.

Данное программное обеспечение наглядно демонстрирует возможности прикладных алгоритмов писка кратчайшего пути и процедурной генерации, в

данной курсовой работе затронута лишь малая часть этих обширных тем.

В целом можно сделать вывод о том, что программное средство эффективно, выполняет все требования, которые выдвигались к нему и все удалось реализовать.

28

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

1 Habr: Доступное объяснение алгоритма коллапса волновой функции,

URL: https://habr.com/ru/post/461323/ (дата обращения 21.10.2021)

2 Habr: Введение в алгоритм A*, URL: https://habr.com/ru/post/331192/ (дата обращения 21.11.2021)

3 python.org: Официальный сайт python, URL: https://www.python.org/ (дата обращения 28.11.2021)

4 doc.qt.io: Документация по PyQt, URL: https://doc.qt.io/qtforpython/

(дата обращения 05.12.2021)

5 pygame.org: Документация по Pygame, URL: https://www.pygame.org/docs/

(дата обращения 10.12.2021)

29

ПРИЛОЖЕНИЕ А

Код программы

Листинг А.1 – Код «Стартового меню»

from typing import ForwardRef, MappingView from PyQt5 import QtCore, QtGui, QtWidgets from draw import draw_best_way

from threading import *

class Ui_MainWindow(object):

def setupUi(self, MainWindow):

MainWindow.setObjectName("Сгенерируй и найди")

MainWindow.resize(600, 350)

sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)

sizePolicy.setHorizontalStretch(0)

sizePolicy.setVerticalStretch(0)

sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightFor Width())

MainWindow.setSizePolicy(sizePolicy)

MainWindow.setAutoFillBackground(False)

MainWindow.setDocumentMode(False)

MainWindow.setDockNestingEnabled(False) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.verticalLayout_2 =

QtWidgets.QVBoxLayout(self.centralwidget) self.verticalLayout_2.setObjectName("verticalLayout_2") self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.label_3 = QtWidgets.QLabel(self.centralwidget) font = QtGui.QFont()

30