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

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

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

font.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