python&pygame随机迷宫基于A*算法自动寻路

caidan_youxi.py

import sys

import pygame
from PyQt5.QtWidgets import QApplication, QMainWindow

import login

if __name__ == '__main__':
    pygame.init()
    pygame.mixer.init()
    pygame.mixer.music.load('bgm.mp3')  # 加载歌曲
    pygame.mixer.music.play()  # 播放
    app = QApplication(sys.argv)
    win = QMainWindow()
    loginUi = login.Ui_MainWindow()
    loginUi.setupUi(win)
    win.show()
    sys.exit(app.exec_())

my_migong.py

import pygame
import random
import numpy as np
import time



class Point:
    def __init__(self, row=0, col=0):
        self.row = row
        self.col = col

    def copy(self):
        return Point(self.row, self.col)


w = 720
h = 720
Row = 9
Col = 9

f = open("speed.txt", mode='r')
speed = f.read()
print(speed)
f.close()
if speed=="9":
    w=720
    h=720
    Row=9
    Col=9

elif speed=="61":
    w=732
    h=732
    Row=61
    Col=61

elif speed=="101":
    w=707
    h=707
    Row=101
    Col=101

size = (w, h)
pygame.init()
window = pygame.display.set_mode(size)
pygame.display.set_caption("迷宫 123不同等级提示")
bak_color = (0, 0, 0)

showWindow = True
showjiesu=True
Shengli = False
clock = pygame.time.Clock()  # 时钟控制


def lu_q(point):
    a = []
    for i in range(0, len(Qiang)):
        if point.col - 1 == Qiang[i].col and point.row == Qiang[i].row:
            a.append(Qiang[i])
        if point.col + 1 == Qiang[i].col and point.row == Qiang[i].row:
            a.append(Qiang[i])
        if point.col == Qiang[i].col and point.row - 1 == Qiang[i].row:
            a.append(Qiang[i])
        if point.col == Qiang[i].col and point.row + 1 == Qiang[i].row:
            a.append(Qiang[i])
    return a


def qi_l(point):
    a = []
    for i in range(0, len(lu)):
        if point.col - 1 == lu[i].col and point.row == lu[i].row:
            a.append(lu[i])
        if point.col + 1 == lu[i].col and point.row == lu[i].row:
            a.append(lu[i])
        if point.col == lu[i].col and point.row - 1 == lu[i].row:
            a.append(lu[i])
        if point.col == lu[i].col and point.row + 1 == lu[i].row:
            a.append(lu[i])
    return a


def xiangling(point):
    global s
    a = []
    for i in range(0, len(lu)):
        if point.col - 2 == lu[i].col and point.row == lu[i].row:
            a.append(lu[i])
        if point.col + 2 == lu[i].col and point.row == lu[i].row:
            a.append(lu[i])
        if point.col == lu[i].col and point.row - 2 == lu[i].row:
            a.append(lu[i])
        if point.col == lu[i].col and point.row + 2 == lu[i].row:
            a.append(lu[i])
    for j in range(0, len(lu)):
        if point.col == lu[j].col and point.row == lu[j].row:
            s = j
    genghuan = []
    for i in range(0, len(a)):
        for j in liebiao:
            if a[i].col == j.col:
                if a[i].row == j.row:
                    genghuan.append(i)

    genghuan.sort(reverse=True)

    for i in genghuan:
        a.pop(i)
    if a != None:
        lu.pop(s)
    return a


Qiang = []
for i in range(1, Row - 1):
    for j in range(1, Col - 1):
        Qiang.append(Point(i, j))

lu = []
for i in range(1, Row, 2):
    for j in range(1, Col, 2):
        lu.append(Point(i, j))
lu2 = lu

genghuan = []
for i in range(0, len(Qiang)):
    for j in lu:
        if Qiang[i].col == j.col:
            if Qiang[i].row == j.row:
                genghuan.append(i)

genghuan.sort(reverse=True)

for i in genghuan:
    Qiang.pop(i)

qidian = Point(1, 1)
lujing = []
liebiao = []
liebiao.append(qidian)
lujing.append(qidian)

zhongdian = Point(Row - 2, Col - 2)
lujin = []
x = 0
while len(liebiao):
#for i in range(0,10):

    ran = random.randint(1, len(liebiao))
    lujing.append(liebiao[ran - 1])

    for i in range(0, len(lujing)):
        if lujing[i].row - 2 == lujing[x + 1].row and lujing[i].col == lujing[x + 1].col:
            lujin.append(Point(lujing[i].row - 1, lujing[i].col))
            break
        if lujing[i].row + 2 == lujing[x + 1].row and lujing[i].col == lujing[x + 1].col:
            lujin.append(Point(lujing[i].row + 1, lujing[i].col))
            break
        if lujing[i].row == lujing[x + 1].row and lujing[i].col - 2 == lujing[x + 1].col:
            lujin.append(Point(lujing[i].row, lujing[i].col - 1))
            break
        if lujing[i].row == lujing[x + 1].row and lujing[i].col + 2 == lujing[x + 1].col:
            lujin.append(Point(lujing[i].row, lujing[i].col + 1))
            break

        # lujin.append(Point(int((lujing[x].row+lujing[x+1].row)/2),int((lujing[x].col+lujing[x+1].col)/2)))
    guo = xiangling(liebiao[ran - 1])
    liebiao.pop(ran - 1)
    liebiao.extend(guo)
    x = x + 1

lu.extend(lujin)
lu.extend(lujing)


def rect(point, color):
    cell_width = w / Col
    cell_height = h / Row
    left = (point.col) * cell_width
    top = (point.row) * cell_height
    pygame.draw.rect(
        window, color,
        (left, top, cell_width, cell_height)
    )


image = pygame.image.load("lan.jpg")
new1 = pygame.transform.scale(image, (h/Row, w/Col))
window.blit(new1, (0, 0))


def rect2(point):
    cell_width = w / Col
    cell_height = h / Row
    left = point.col * cell_width
    top = point.row * cell_height
    # py.draw.rect(
    #     window, color,
    #     (left, top, cell_width, cell_height)
    # )
    window.blit(
        new1,
        (left, top)
    )


xx = 1
yy = 1
renwu = Point(xx, yy)
jilu_ren = []
jilu_ren.append(renwu)


def Index(point):
    for i in range(0, len(lu)):
        if point.col == lu[i].col and point.row == lu[i].row:
            return True
    return False


# A*算法自动寻路
num = [[1 for i in range(0, Row - 2)] for j in range(0, Col - 2)]
for i in range(0, Row - 2):
    for j in range(0, Col - 2):
        if Index(Point(i + 1, j + 1)):
            num[i][j] = 0


def xunlu(liebiao, qi, zhong):
    a = np.mat(liebiao)

    def gs(i, j):
        return abs(i - startx) + abs(j - starty)

    def h1(i, j):
        return 10 * (abs(i - endx) + abs(j - endy))

    def h2(i, j):
        return pow(i - endx, 2) + pow(j - endy, 2)

    print("地图为:(1表示墙,0表示路)")
    for l in range(len(a)):
        for m in range(a[0].size):
            print(a[l, m], end=' ')
        print('')
    print('')

    startx, starty = qi.row, qi.col
    endx, endy = zhong.row, zhong.col
    if a[startx - 1, starty - 1] == 1:
        print("起点%s位置为墙,最短路径寻找失败!" % ([startx, starty]))
    else:
        # 存储已扩展结点,即所有寻找的节点
        Close = [[startx, starty]]
        # 存储已生成节点,即最终走过的节点
        Opens = [[startx, starty]]
        # 存储未走的分叉节点
        crossings = []
        # 设置在原地图行走的路径值
        road = 100
        start = time.time()
        rows, cols = a.shape
        while True:
            # 判断最后走过的节点是否为终点
            if Close[-1] != [endx, endy]:
                Open = []
                # 减1得到数组下标值
                i, j = Close[-1][0] - 1, Close[-1][1] - 1
                # 对当前节点上下左右四个节点进行判断
                for ni, nj in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
                    if [ni + 1, nj + 1] not in Opens and 0 <= ni < rows and 0 <= nj < cols and a[ni, nj] == 0:
                        Open.append([ni + 1, nj + 1])
                # 将已走过的节点值修改为路径值,并将路径值加1
                a[i, j] = road
                road = road + 1
                if Open:
                    # 对所有扩展到的节点进行排序,reverse=True 结果从大到小,即尾部存储代价最小的节点
                    Open = sorted(Open, key=lambda x: gs(x[0], x[1]) + h2(x[0], x[1]), reverse=True)
                    Opens.extend(Open)
                    # 将代价最小的节点存储到 Close 表
                    Close.append(Open.pop())
                    # 如果 pop 后 Open 表不为空,说明存在岔路,将岔路存储到 crossings 中
                    if Open:
                        crossings.extend(Open)
                # 判断是否存在未走过的分叉节点
                elif crossings:
                    next_way = crossings.pop()
                    # 实现路径回退,循环条件为回退节点与分叉节点不相邻
                    while sum((np.array(Close[-1]) - np.array(next_way)) ** 2) != 1:
                        # 当一条路径寻找失败后,是否将该路径岔路后的部分恢复为原地图
                        # i, j = Close[-1]
                        # a[i-1, j-1] = 0
                        # 每次 while 循环路径值 road 减1,并弹出 Close 表中的节点
                        road -= 1
                        Close.pop()
                    # 将 crossings 中最后一个节点添加到 Close 表
                    Close.append(next_way)
                else:
                    print("最短路径寻找失败,失败位置为:%s,路径为:" % Close[-1])
                    break
            else:
                a[endx - 1, endy - 1] = road
                print("最短路径寻找成功,路径为:")
                break
        for r in range(rows):
            for c in range(cols):
                # 0表示format中第一个元素,>表示右对齐输出,4表示占四个字符
                print("{0: >4}".format(a[r, c]), end='')
            print('')
        end = time.time()
        print("\n扩展节点数为:%d, 生成节点数为:%d, 用时为 %.8f" % (len(Opens), len(Close), float(end - start)))

        print('Close表为:%s' % Close)
        print("点的移动轨迹为:")
        for k in range(len(Close)):
            print(Close[k], end='')
            if k < len(Close) - 1:
                print("-->", end='')
    luxian = []
    for i in range(0, len(Close)):
        luxian.append(Point(Close[i][0], Close[i][1]))
    return luxian


print(num)

xianlu = []

while showWindow:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            showWindow = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP and Index(Point(renwu.row - 1, renwu.col)):
                renwu.row -= 1
            elif event.key == pygame.K_DOWN and Index(Point(renwu.row + 1, renwu.col)):
                renwu.row += 1
            elif event.key == pygame.K_LEFT and Index(Point(renwu.row, renwu.col - 1)):
                renwu.col -= 1
            elif event.key == pygame.K_RIGHT and Index(Point(renwu.row, renwu.col + 1)):
                renwu.col += 1

            elif event.key == pygame.K_q:
                print(renwu.row)
                print(renwu.col)
                print(zhongdian.row)
                print(zhongdian.col)
            elif event.key == pygame.K_1:
                xianlu = []
                xianlu_1 = xunlu(num, renwu, zhongdian)
                xianlu = xianlu_1[0:int(len(xianlu_1) / 3)]
            elif event.key == pygame.K_2:
                xianlu = []
                xianlu_1 = xunlu(num, renwu, zhongdian)
                xianlu = xianlu_1[0:int(len(xianlu_1) / 3 * 2)]
            elif event.key == pygame.K_3:
                xianlu = []
                xianlu_1 = xunlu(num, renwu, zhongdian)
                xianlu = xianlu_1
            elif event.key == pygame.K_4:
                xianlu = []

    # jilu_ren.append(renwu)

    jilu_ren.insert(0, renwu.copy())
    if renwu.col == zhongdian.col and renwu.row == zhongdian.row:
        showWindow = False
        while showjiesu:
            font = pygame.font.Font("HYShangWeiShouShuW.ttf", 50)

            text = font.render("游戏胜利,按s键结束", True, (0, 0, 0))
            window.blit(text, (h/2-200, w/2-50))
            pygame.display.flip()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    showjiesu = False
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_s :
                        showjiesu=False



    #image = pygame.image.load("caoyuan.jpg")
    #new0 = pygame.transform.scale(image, (800, 800))
    #window.blit(new0, (0, 0))
    #pygame.draw.rect(window, bak_color, (0, 0, w, h))
    pygame.draw.rect(window, (200, 200, 200), (0, 0, w, h))

    for i in Qiang:
        rect(i, (200, 200, 200))
    for i in lujing:
        rect(i, (255, 255, 255,0))
    for i in lujin:
        rect(i, (255, 255, 255,0))
    for i in jilu_ren:
        rect(i,(110, 255, 110))

    for i in xianlu:
        rect(i, (200, 255, 200))

    rect(Point(1, 1), (0, 255, 255))
    rect(Point(Row - 2, Col - 2), (0, 0, 255))
    #rect(renwu, (100, 100, 100))
    rect2(renwu)
    # font = pygame.font.Font("HYShangWeiShouShuW.ttf", 50)

    # text = font.render("游戏胜利", True, (200, 200, 200))
    # window.blit(text, (0, 0))
    pygame.display.update()  # 更新整个待显示的Surface对象到屏幕上
    clock.tick(100)  # 设置帧频 可以用来控制蛇头移动的速度

login.py

# -*- coding: utf-8 -*-
import os

# Form implementation generated from reading ui file 'login.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets
from matplotlib.backends.backend_qt import MainWindow


class Ui_MainWindow(object):
    a=2

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1000, 1000)

        MainWindow.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        MainWindow.setAttribute(QtCore.Qt.WA_TranslucentBackground)

        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(100, 40, 800, 800))
        self.label.setStyleSheet("border-image: url(:/images/images/caoyuan.jpg);\n"
"border-top-left-radius:5px;\n"
"border-bottom-left-radius:5px;\n"
"border-top-right-radius:5px;\n"
"border-bottom-right-radius:5px;")
        self.label.setText("")
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(440, 150, 171, 61))
        font = QtGui.QFont()
        font.setFamily("Bahnschrift SemiBold Condensed")
        font.setPointSize(27)
        font.setBold(False)
        font.setItalic(True)
        font.setUnderline(True)
        font.setWeight(50)
        font.setStrikeOut(True)
        self.label_2.setFont(font)
        self.label_2.setStyleSheet("color: rgb(85, 85, 127);")
        self.label_2.setObjectName("label_2")
        self.comboBox = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox.setGeometry(QtCore.QRect(540, 310, 101, 71))
        font = QtGui.QFont()
        font.setPointSize(18)
        font.setBold(False)
        font.setItalic(True)
        font.setWeight(50)
        self.comboBox.setFont(font)
        self.comboBox.setStyleSheet("background-color: rgba(255, 255, 255, 80);\n"
"")
        self.comboBox.setFrame(False)
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(330, 310, 171, 71))
        font = QtGui.QFont()
        font.setPointSize(18)
        self.label_3.setFont(font)
        self.label_3.setObjectName("label_3")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(420, 470, 181, 51))
        font = QtGui.QFont()
        font.setPointSize(18)
        font.setBold(False)
        font.setItalic(True)
        font.setWeight(50)
        self.pushButton.setFont(font)
        self.pushButton.setStyleSheet("#pushButton{\n"
"background-color: rgb(255, 255, 255,80);\n"
"color:rgb(0,0,0);\n"
"border:3px solid rgb(255,255,255,80);\n"
"border-radius:7px;\n"
"}\n"
"#pushButton:hover{\n"
"background-color: rgb(0, 0, 0,80);\n"
"color:rgb(255,255,255);\n"
"}\n"
"#pushButton:pressed{\n"
"padding-top:5px;\n"
"padding-left:5px\n"
"}\n"
"\n"
"")
        self.pushButton.setObjectName("pushButton")
        #self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        #self.pushButton_2.setGeometry(QtCore.QRect(420, 560, 181, 51))
        font = QtGui.QFont()
        font.setPointSize(18)
        font.setItalic(True)
        #self.pushButton_2.setFont(font)
#         self.pushButton_2.setStyleSheet("#pushButton_2{\n"
# "background-color: rgb(255, 255, 255,80);\n"
# "color:rgb(0,0,0);\n"
# "border:3px solid rgb(255,255,255,80);\n"
# "border-radius:7px;\n"
# "}\n"
# "#pushButton_2:hover{\n"
# "background-color: rgb(0, 0, 0,80);\n"
# "color:rgb(255,255,255);\n"
# "}\n"
# "#pushButton_2:pressed{\n"
# "padding-top:5px;\n"
# "padding-left:5px\n"
# "}\n"
# "\n"
# "")
        #self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_3.setGeometry(QtCore.QRect(870, 40, 31, 31))
        self.pushButton_3.setStyleSheet("border-image: url(:/icons/icons/close.png);\n"
"background-color: rgba(255, 255, 255, 0);")
        self.pushButton_3.setText("")
        self.pushButton_3.setObjectName("pushButton_3")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        self.pushButton_3.clicked.connect(MainWindow.close) # type: ignore
        self.pushButton_3.clicked.connect(self.Speed)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label_2.setText(_translate("MainWindow", "迷宫"))
        self.comboBox.setItemText(0, _translate("MainWindow", "简单"))
        self.comboBox.setItemText(1, _translate("MainWindow", "中等"))
        self.comboBox.setItemText(2, _translate("MainWindow", "困难"))
        self.label_3.setText(_translate("MainWindow", "难度选择:"))
        self.pushButton.setText(_translate("MainWindow", "开始游戏"))
        #self.pushButton_2.setText(_translate("MainWindow", "排行榜"))

        self.comboBox.currentIndexChanged[str].connect(self.nandu)
        self.pushButton.clicked.connect(self.Kaishi)
        #self.pushButton_2.clicked.connect(self.Paihang)

    def nandu(self, i):
        self.a=9
        if i == "简单":
            self.a = 9
        elif i == "中等":
            self.a = 61
        elif i == "困难":
            self.a = 101
        else:
            self.a = 9
        f = open("speed.txt", mode='w')
        f.writelines(str(self.a))
        f.close()



    def Kaishi(self):
        os.system("my_migong.py")

    # def Paihang(self):
    #     os.system("migong/test.py")

    def Speed(self):
        f = open("speed.txt", mode='w')
        f.writelines(str(9))
        f.close()




import resource_rc

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值