用户:JustinChen查看:1 回复:1 评论:1 创建时间:2021-08-04T10:24:43
-不-要-脸-,-明-明-创-建-6-0-0-天-它-才-4-9-9-行-【doge】
import random
import sys
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image, ImageQt
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
class Ui_Maze(object):
def setupUi(self, Maze):
if not Maze.objectName():
Maze.setObjectName(u"Maze")
Maze.resize(750, 450)
Maze.setMinimumSize(QSize(750, 450))
Maze.setMaximumSize(QSize(750, 450))
self.centralwidget = QWidget(Maze)
self.centralwidget.setObjectName(u"centralwidget")
self.information1 = QLabel(self.centralwidget)
self.information1.setObjectName(u"information1")
self.information1.setGeometry(QRect(260, 19, 61, 21))
self.information1.setMinimumSize(QSize(61, 21))
self.information1.setMaximumSize(QSize(61, 21))
self.row = QLineEdit(self.centralwidget)
self.row.setObjectName(u"row")
self.row.setGeometry(QRect(330, 19, 41, 20))
self.row.setMinimumSize(QSize(41, 20))
self.row.setMaximumSize(QSize(41, 20))
self.information2 = QLabel(self.centralwidget)
self.information2.setObjectName(u"information2")
self.information2.setGeometry(QRect(380, 19, 21, 21))
self.information2.setMinimumSize(QSize(21, 21))
self.information2.setMaximumSize(QSize(21, 21))
self.col = QLineEdit(self.centralwidget)
self.col.setObjectName(u"col")
self.col.setGeometry(QRect(410, 19, 41, 20))
self.col.setMinimumSize(QSize(41, 20))
self.col.setMaximumSize(QSize(41, 20))
self.information3 = QLabel(self.centralwidget)
self.information3.setObjectName(u"information3")
self.information3.setGeometry(QRect(460, 20, 54, 21))
self.information3.setMinimumSize(QSize(54, 21))
self.information3.setMaximumSize(QSize(54, 21))
self.maze = QLabel(self.centralwidget)
self.maze.setObjectName(u"maze")
self.maze.setGeometry(QRect(40, 90, 300, 300))
self.maze.setMinimumSize(QSize(300, 300))
self.maze.setMaximumSize(QSize(300, 300))
self.maze.setAlignment(Qt.AlignCenter)
self.ans = QLabel(self.centralwidget)
self.ans.setObjectName(u"ans")
self.ans.setGeometry(QRect(410, 90, 300, 300))
self.ans.setMinimumSize(QSize(300, 300))
self.ans.setMaximumSize(QSize(300, 300))
self.ans.setAlignment(Qt.AlignCenter)
self.savemaze = QPushButton(self.centralwidget)
self.savemaze.setObjectName(u"savemaze")
self.savemaze.setGeometry(QRect(160, 410, 61, 23))
self.savemaze.setMinimumSize(QSize(61, 23))
self.savemaze.setMaximumSize(QSize(61, 23))
self.saveans = QPushButton(self.centralwidget)
self.saveans.setObjectName(u"saveans")
self.saveans.setGeometry(QRect(530, 410, 61, 23))
self.saveans.setMinimumSize(QSize(61, 23))
self.saveans.setMaximumSize(QSize(61, 23))
self.create = QPushButton(self.centralwidget)
self.create.setObjectName(u"create")
self.create.setGeometry(QRect(280, 50, 71, 23))
self.create.setMinimumSize(QSize(71, 23))
self.create.setMaximumSize(QSize(71, 23))
self.mzplt = QPushButton(self.centralwidget)
self.mzplt.setObjectName(u"mzplt")
self.mzplt.setGeometry(QRect(150, 50, 81, 23))
self.mzplt.setMinimumSize(QSize(81, 23))
self.mzplt.setMaximumSize(QSize(81, 23))
self.ansplt = QPushButton(self.centralwidget)
self.ansplt.setObjectName(u"ansplt")
self.ansplt.setGeometry(QRect(520, 50, 81, 23))
self.ansplt.setMinimumSize(QSize(81, 23))
self.ansplt.setMaximumSize(QSize(81, 23))
self.pbtn = QPushButton(self.centralwidget)
self.pbtn.setObjectName(u"pbtn")
self.pbtn.setGeometry(QRect(400, 50, 71, 23))
self.pbtn.setMinimumSize(QSize(71, 23))
self.pbtn.setMaximumSize(QSize(71, 23))
Maze.setCentralWidget(self.centralwidget)
self.retranslateUi(Maze)
QMetaObject.connectSlotsByName(Maze)
# setupUi
def retranslateUi(self, Maze):
Maze.setWindowTitle(QCoreApplication.translate("Maze", u"maze", None))
self.information1.setText(QCoreApplication.translate(
"Maze", u"\u751f\u6210\u4e00\u4e2a\u6709", None))
self.row.setText("")
self.information2.setText(
QCoreApplication.translate("Maze", u"\u884c\u3001", None))
self.col.setText("")
self.information3.setText(QCoreApplication.translate(
"Maze", u"\u5217\u7684\u8ff7\u5bab", None))
self.maze.setText(QCoreApplication.translate(
"Maze", u"\u751f\u6210\u7684\u8ff7\u5bab\uff08\u5c3d\u91cf\u8f93\u5165\u957f\u5bbd\u5dee\u4e0d\u591a\u7684\uff09", None))
self.ans.setText(QCoreApplication.translate(
"Maze", u"\u6b63\u786e\u7684\u8def\u5f84\uff08\u5c3d\u91cf\u8f93\u5165\u957f\u5bbd\u5dee\u4e0d\u591a\u7684\uff09", None))
self.savemaze.setText(QCoreApplication.translate(
"Maze", u"\u4fdd\u5b58", None))
self.saveans.setText(QCoreApplication.translate(
"Maze", u"\u4fdd\u5b58", None))
self.create.setText(QCoreApplication.translate(
"Maze", u"\u751f\u6210\u8def\u591a\u7684", None))
self.mzplt.setText(QCoreApplication.translate(
"Maze", u"\u56fe\u7247\u7a97\u53e3\u6d4f\u89c8", None))
self.ansplt.setText(QCoreApplication.translate(
"Maze", u"\u56fe\u7247\u7a97\u53e3\u6d4f\u89c8", None))
self.pbtn.setText(QCoreApplication.translate(
"Maze", u"\u751f\u6210\u66f2\u6298\u7684", None))
# retranslateUi
class maze(QMainWindow, Ui_Maze):
def __init__(self):
super().__init__()
self.setupUi(self)
self.setup()
self.show()
def setup(self):
self.yz = 0
self.create.clicked.connect(self.cre)
self.pbtn.clicked.connect(self.cr)
self.savemaze.clicked.connect(self.s_m)
self.saveans.clicked.connect(self.sa)
self.mzplt.clicked.connect(self.mz)
self.ansplt.clicked.connect(self.asp)
def mz(self):
try:
plt.imshow(self.img1)
plt.show()
except:
QMessageBox.warning(self, '注意', '请先创建迷宫')
def asp(self):
try:
plt.imshow(self.img2)
plt.show()
except:
QMessageBox.warning(self, '注意', '请先创建迷宫')
def sa(self):
if self.ans.text() != "正确的路径(尽量输入长宽差不多的)":
f_p = QFileDialog.getSaveFileName(caption='保存文件', filter='(*.png)')
if f_p[0]:
s_p = f_p[0]
self.img2.save(s_p)
else:
QMessageBox.warning(self, '注意', '请重新选择保存位置')
else:
QMessageBox.warning(self, '注意', '请先创建迷宫')
def s_m(self):
if self.maze.text() != "生成的迷宫(尽量输入长宽差不多的)":
f_p = QFileDialog.getSaveFileName(caption='保存文件', filter='(*.png)')
if f_p[0]:
s_p = f_p[0]
self.img1.save(s_p)
else:
QMessageBox.warning(self, '注意', '请重新选择保存位置')
else:
QMessageBox.warning(self, '注意', '请先创建迷宫')
def build_tortuous(self, num_rows, num_cols): # 曲折迷宫
m = np.zeros((num_rows, num_cols, 5), dtype=np.uint8)
r = 0
c = 0
trace = [(r, c)]
while trace:
m[r, c, 4] = 1 # 标记为已访问
check = []
if c > 0 and m[r, c - 1, 4] == 0:
check.append('L')
if r > 0 and m[r - 1, c, 4] == 0:
check.append('U')
if c < num_cols - 1 and m[r, c + 1, 4] == 0:
check.append('R')
if r < num_rows - 1 and m[r + 1, c, 4] == 0:
check.append('D')
if len(check):
trace.append([r, c])
direction = random.choice(check)
if direction == 'L':
m[r, c, 0] = 1
c = c - 1
m[r, c, 2] = 1
if direction == 'U':
m[r, c, 1] = 1
r = r - 1
m[r, c, 3] = 1
if direction == 'R':
m[r, c, 2] = 1
c = c + 1
m[r, c, 0] = 1
if direction == 'D':
m[r, c, 3] = 1
r = r + 1
m[r, c, 1] = 1
else:
r, c = trace.pop()
m[0, 0, 0] = 1
m[num_rows - 1, num_cols - 1, 2] = 1
return m
def build_twist(self, num_rows, num_cols):
# (行坐标,列坐标,四面墙的有无&访问标记)
m = np.zeros((num_rows, num_cols, 5), dtype=np.uint8)
r, c = 0, 0
trace = [(r, c)]
while trace:
r, c = random.choice(trace)
m[r, c, 4] = 1
trace.remove((r, c))
check = []
if c > 0:
if m[r, c - 1, 4] == 1:
check.append('L')
elif m[r, c - 1, 4] == 0:
trace.append((r, c - 1))
m[r, c - 1, 4] = 2
if r > 0:
if m[r - 1, c, 4] == 1:
check.append('U')
elif m[r - 1, c, 4] == 0:
trace.append((r - 1, c))
m[r - 1, c, 4] = 2
if c < num_cols - 1:
if m[r, c + 1, 4] == 1:
check.append('R')
elif m[r, c + 1, 4] == 0:
trace.append((r, c + 1))
m[r, c + 1, 4] = 2
if r < num_rows - 1:
if m[r + 1, c, 4] == 1:
check.append('D')
elif m[r + 1, c, 4] == 0:
trace.append((r + 1, c))
m[r + 1, c, 4] = 2
if len(check):
direction = random.choice(check)
if direction == 'L': # 打通一面墙
m[r, c, 0] = 1
c = c - 1
m[r, c, 2] = 1
if direction == 'U':
m[r, c, 1] = 1
r = r - 1
m[r, c, 3] = 1
if direction == 'R':
m[r, c, 2] = 1
c = c + 1
m[r, c, 0] = 1
if direction == 'D':
m[r, c, 3] = 1
r = r + 1
m[r, c, 1] = 1
m[0, 0, 0] = 1
m[num_rows - 1, num_cols - 1, 2] = 1
return m
def draw(self, num_rows, num_cols, m):
image = np.zeros((num_rows * 10, num_cols * 10), dtype=np.uint8)
for row in range(0, num_rows):
for col in range(0, num_cols):
cell_data = m[row, col]
for i in range(10 * row + 2, 10 * row + 8):
image[i, range(10 * col + 2, 10 * col + 8)] = 255
if cell_data[0] == 1:
image[range(10 * row + 2, 10 * row + 8), 10 * col] = 255
image[range(10 * row + 2, 10 * row + 8),
10 * col + 1] = 255
if cell_data[1] == 1:
image[10 * row, range(10 * col + 2, 10 * col + 8)] = 255
image[10 * row + 1,
range(10 * col + 2, 10 * col + 8)] = 255
if cell_data[2] == 1:
image[range(10 * row + 2, 10 * row + 8),
10 * col + 9] = 255
image[range(10 * row + 2, 10 * row + 8),
10 * col + 8] = 255
if cell_data[3] == 1:
image[10 * row + 9,
range(10 * col + 2, 10 * col + 8)] = 255
image[10 * row + 8,
range(10 * col + 2, 10 * col + 8)] = 255
return image
def draw_path(self, image, move_list):
row, col = (0, 0)
image[range(10 * row + 2, 10 * row + 8), 10 * col] = 127
image[range(10 * row + 2, 10 * row + 8), 10 * col + 1] = 127
for i in range(len(move_list) + 1):
for x in range(10 * row + 2, 10 * row + 8):
image[x, range(10 * col + 2, 10 * col + 8)] = 127
if i > 0:
go = move_list[i - 1]
if go == 'L':
image[range(10 * row + 2, 10 * row + 8),
10 * col + 9] = 127
image[range(10 * row + 2, 10 * row + 8),
10 * col + 8] = 127
elif go == 'U':
image[10 * row + 9,
range(10 * col + 2, 10 * col + 8)] = 127
image[10 * row + 8,
range(10 * col + 2, 10 * col + 8)] = 127
elif go == 'R':
image[range(10 * row + 2, 10 * row + 8), 10 * col] = 127
image[range(10 * row + 2, 10 * row + 8),
10 * col + 1] = 127
elif go == 'D':
image[10 * row, range(10 * col + 2, 10 * col + 8)] = 127
image[10 * row + 1,
range(10 * col + 2, 10 * col + 8)] = 127
if i >= len(move_list):
break
go = move_list[i]
if go == 'L':
image[range(10 * row + 2, 10 * row + 8), 10 * col] = 127
image[range(10 * row + 2, 10 * row + 8), 10 * col + 1] = 127
elif go == 'U':
image[10 * row, range(10 * col + 2, 10 * col + 8)] = 127
image[10 * row + 1, range(10 * col + 2, 10 * col + 8)] = 127
elif go == 'R':
image[range(10 * row + 2, 10 * row + 8), 10 * col + 9] = 127
image[range(10 * row + 2, 10 * row + 8), 10 * col + 8] = 127
elif go == 'D':
image[10 * row + 9, range(10 * col + 2, 10 * col + 8)] = 127
image[10 * row + 8, range(10 * col + 2, 10 * col + 8)] = 127
if go == 'L':
col = col - 1
elif go == 'U':
row = row - 1
elif go == 'R':
col = col + 1
elif go == 'D':
row = row + 1
image[range(10 * row + 2, 10 * row + 8), 10 * col + 9] = 127
image[range(10 * row + 2, 10 * row + 8), 10 * col + 8] = 127
return image
def solve_backtrack(self, num_rows, num_cols, map_arr): # 回溯法
move_list = ['R']
m = 1 # 回溯点组号
mark = []
r, c = (0, 0)
while True:
if (r == num_rows-1) and (c == num_cols-1):
break
wall = map_arr[r, c]
way = []
if wall[0] == 1:
way.append('L')
if wall[1] == 1:
way.append('U')
if wall[2] == 1:
way.append('R')
if wall[3] == 1:
way.append('D')
come = move_list[len(move_list) - 1]
if come == 'L':
way.remove('R')
elif come == 'U':
way.remove('D')
elif come == 'R':
way.remove('L')
elif come == 'D':
way.remove('U')
while way:
mark.append((r, c, m, way.pop())) # 记录当前坐标和可行移动方向
if mark:
r, c, m, go = mark.pop()
del move_list[m:] # 删除回溯点之后的移动
else:
return False
m = m + 1
move_list.append(go)
if go == 'L':
c = c - 1
elif go == 'U':
r = r - 1
elif go == 'R':
c = c + 1
elif go == 'D':
r = r + 1
del move_list[0]
return move_list
def fig2data(self, fig):
import PIL.Image as Image
# draw the renderer
fig.canvas.draw()
# Get the RGBA buffer from the figure
w, h = fig.canvas.get_width_height()
buf = np.fromstring(fig.canvas.tostring_argb(), dtype=np.uint8)
buf.shape = (w, h, 4)
# canvas.tostring_argb give pixmap in ARGB mode. Roll the ALPHA channel to have it in RGBA mode
buf = np.roll(buf, 3, axis=2)
image = Image.frombytes("RGBA", (w, h), buf.tostring())
image = np.asarray(image)
return image
def cr(self):
try:
rows = int(self.row.text())
cols = int(self.col.text())
except:
QMessageBox.warning(self, '错误', '输入有误')
else:
Map = self.build_tortuous(rows, cols)
plt.imshow(self.draw(rows, cols, Map), cmap='gray')
self.fig1 = plt.gcf()
self.fig1.set_size_inches(cols/5, rows/5)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
plt.subplots_adjust(top=1, bottom=0, right=1,
left=0, hspace=0, wspace=0)
plt.margins(0, 0)
img = self.fig2data(self.fig1)
self.img1 = Image.fromarray(img.astype('uint8')).convert('RGB')
img = ImageQt.toqpixmap(self.img1)
self.maze.setPixmap(img)
self.maze.setScaledContents(True)
move = self.solve_backtrack(rows, cols, Map)
plt.imshow(self.draw_path(
self.draw(rows, cols, Map), move), cmap='hot')
self.fig2 = plt.gcf()
self.fig2.set_size_inches(cols/5, rows/5)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
plt.subplots_adjust(top=1, bottom=0, right=1,
left=0, hspace=0, wspace=0)
plt.margins(0, 0)
img = self.fig2data(self.fig2)
self.img2 = Image.fromarray(img.astype('uint8')).convert('RGB')
img = ImageQt.toqpixmap(self.img2)
self.ans.setPixmap(img)
self.ans.setScaledContents(True)
def cre(self):
try:
rows = int(self.row.text())
cols = int(self.col.text())
except:
QMessageBox.warning(self, '错误', '输入有误')
else:
Map = self.build_twist(rows, cols) # build_tortuous
plt.imshow(self.draw(rows, cols, Map), cmap='gray')
self.fig1 = plt.gcf()
self.fig1.set_size_inches(cols/5, rows/5)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
plt.subplots_adjust(top=1, bottom=0, right=1,
left=0, hspace=0, wspace=0)
plt.margins(0, 0)
img = self.fig2data(self.fig1)
self.img1 = Image.fromarray(img.astype('uint8')).convert('RGB')
img = ImageQt.toqpixmap(self.img1)
self.maze.setPixmap(img)
self.maze.setScaledContents(True)
# if(self.yz==1):
# plt.show()
# self.yz=0
move = self.solve_backtrack(rows, cols, Map)
plt.imshow(self.draw_path(
self.draw(rows, cols, Map), move), cmap='hot')
self.fig2 = plt.gcf()
self.fig2.set_size_inches(cols/5, rows/5)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
plt.subplots_adjust(top=1, bottom=0, right=1,
left=0, hspace=0, wspace=0)
plt.margins(0, 0)
img = self.fig2data(self.fig2)
self.img2 = Image.fromarray(img.astype('uint8')).convert('RGB')
img = ImageQt.toqpixmap(self.img2)
self.ans.setPixmap(img)
self.ans.setScaledContents(True)
# if(self.yz == 2):
# plt.show()
# self.yz = 0
if __name__ == '__main__':
app = QApplication(sys.argv)
window = maze()
sys.exit(app.exec_())