猫史档案馆


同刚刚的(优化)

用户:JustinChenJustinChen查看: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_())


回复

上一页1 页 / 共 1下一页
Python-happyyyyPython-happyyyy

原来大家编qt都用Qt Designer

点赞0


评论