项目三:使用python pygame模块做基础的迷宫游戏

本文介绍了一个使用Python Pygame模块开发的基础迷宫游戏。游戏包括显示走过的路径、自动追踪最优路径等功能。文章详细讲解了Map类的创建、递归回溯算法生成迷宫、A*算法实现自动寻路以及简单的GUI实现。虽然存在一些不足,如路径无法删除、四领域移动不顺滑等,但提供了进一步完善和学习的思路。
摘要由CSDN通过智能技术生成

入门小白,大佬慎入

讲的比较简单,不是很详细,提供一个思路。

目录:

  1. 成果展示
  2. 代码说明
  3. 完整代码
  4. 其他补充和参考资料

——————分割线————————

1.成果展示

实现功能:

1.显示走过的路径(再次走过可消除)

2.自动追踪并显示最优路径

2.代码说明

(1)创建基础的Map类

import pygame
from random import randint, choice
from enum import Enum
from sys import exit


REC_SIZE = 10
REC_WIDTH = 51  # must be odd number
REC_HEIGHT = 51  # must be odd number
SCREEN_WIDTH = REC_WIDTH * REC_SIZE
SCREEN_HEIGHT = REC_HEIGHT * REC_SIZE


# 创建地图格子种类枚举类
class MAP_ENTRY_TYPE(Enum):
    MAP_EMPTY = 0,
    MAP_BLOCK = 1,
    MAP_TARGET = 2,
    MAP_PATH = 3,
    MAP_DONE = 4

# 创建一个格子方法枚举类
class WALL_DIRECTION(Enum):
    WALL_LEFT = 0,
    WALL_UP = 1,
    WALL_RIGHT = 2,
    WALL_DOWN = 3,

# 用字典存储格子枚举类型
map_entry_types = {0: MAP_ENTRY_TYPE.MAP_EMPTY, 1: MAP_ENTRY_TYPE.MAP_BLOCK,
                   2: MAP_ENTRY_TYPE.MAP_TARGET, 3: MAP_ENTRY_TYPE.MAP_PATH, 4: MAP_ENTRY_TYPE.MAP_DONE}


"""基础MAP类生成并控制格子"""
class Map:
    # 初始化地图长宽
    def __init__(self, width, height):
        self.width = width
        self.height = height
        self.map = [[0 for x in range(self.width)] for y in range(self.height)]

    # 创建一定数量的墙壁
    def createBlock(self, block_num):
        for i in range(block_num):
            x, y = (randint(0, self.width - 1), randint(0, self.height - 1))
            self.map[y][x] = 1

    # 在范围内随机选找到路径
    def generatePos(self, rangeX, rangeY):
        x, y = (randint(rangeX[0], rangeX[1]), randint(rangeY[0], rangeY[1]))
        while self.map[y][x] == 1:
            x, y = (randint(rangeX[0], rangeX[1]), randint(rangeY[0], rangeY[1]))
        return x, y

    # 将整个地图重置为指定类型
    def resetMap(self, value):
        for y in range(self.height):
            for x in range(self.width):
                self.setMap(x, y, value)

    # 将一个格子设置为指定类型
    def setMap(self, x, y, value):
        if value == MAP_ENTRY_TYPE.MAP_EMPTY:
            self.map[y][x] = 0
        elif value == MAP_ENTRY_TYPE.MAP_BLOCK:
            self.map[y][x] = 1
        elif value == MAP_ENTRY_TYPE.MAP_TARGET:
            self.map[y][x] = 2
        elif value == MAP_ENTRY_TYPE.MAP_PATH:
            self.map[y][x] = 3
        else:
            self.map[y][x] = 4

    # 判断一个格子是否可以访问
    def isVisited(self, x, y):
        return self.map[y][x] != 1

    # 判断一个格子是否可移动
    def isMovable(self, x, y):
        return self.map[y][x] != 1

    # 判断格子是否在地图内
    def isValid(self, x, y):
        if x < 0 or x >= self.width or y < 0 or y >= self.height:
            return False
        return True

    # 返回格子类型
    def getType(self, x, y):
        return map_entry_types[self.map[y][x]]

创建Map类,用来生成地图,并操控地图中每个格子(或者点)

两个枚举类是便于后面操作格子,便于理解

(2)创建迷宫生成函数

"""迷宫生成算法"""
# 找到四个相位中没有被遍历过的格子
# 随机遍历一个,将其放入遍历过的方格列表
def checkAdjacentPos(map, x, y, width, height, checklist):
    directions = []
    if x > 0:
        if not map.isVisited(2 * (x - 1) + 1, 2 * y + 1):
            directions.append(WALL_DIRECTION.WALL_LEFT)

    if y > 0:
        if not map.isVisited(2 * x + 1, 2 * (y - 1) + 1):
            directions.append(WALL_DIRECTION.WALL_UP)

    if x < width - 1:
        if not map.isVisited(2 * (x + 1) + 1, 2 * y + 1):
            directions.append(WALL_DIRECTION.WALL_RIGHT)

    if y < height - 1:
        if not map.isVisited(2 * x + 1, 2 * (y + 1) + 1):
            directions.append(WALL_DIRECTION.WALL_DOWN)

    if len(directions):
        direction = choice(directions)
        # print("(%d, %d) => %s" % (x, y, str(direction)))
        if direction == WALL_DIRECTION.WALL_LEFT:
            map.setMap(2 * (x - 1) + 1, 2 * y + 1, MAP_ENTRY_TYPE.MAP_EMPTY)
            map.setMap(2 * x, 2 * y + 1, MAP_ENTRY_TYPE.MAP_EMPTY)
            checklist.append((x - 1, y))
        elif direction == WALL_DIRECTION.WALL_UP:
            map.setMap(2 * x + 1, 2 * (y - 1) + 1, MAP_ENTRY_TYPE.MAP_EMPTY)
            map.setMap(2 * x + 1, 2 * y, MAP_ENTRY_TYPE.MAP_EMPTY)
            checklist.append((x, y - 1))
        elif direction == WALL_DIRECTION.WALL_RIGHT:
            map.setMap(2 * (x + 1) + 1, 2 * y + 1, MAP_ENTRY_TYPE.MAP_EMPTY)
            map.setMap(2 * x + 2, 2 * y + 1, MAP_ENTRY_TYPE.MAP_EMPTY)
            checklist.append((x + 1, y))
        elif direction == WALL_DIRECTION.WALL_DOWN:
            map.setMap(2 * x + 1, 2 * (y + 1) + 1, MAP_ENTRY_TYPE.MAP_EMPTY)
            map.setMap(2 * x + 1, 2 * y + 2, MAP_ENTRY_TYPE.MAP_EMPTY)
            checklist.append((x, y + 1))
        return True
    else:
        # 如果没有找到相邻的未遍历方格
        return False


# 递归回溯实现
def recursiveBacktracker(map, width, height):
    startX, startY = (randint(0, width - 1), randint(0, height - 1))
    print("start(%d, %d)" % (startX, startY))
    map.setMap(2 * startX + 1, 2 * startY + 1, MAP_ENTRY_TYPE.MAP_EMPTY)

    checklist = []
    checklist.append((startX, startY))
    while len(checklist):
        # 将检查列表用作堆栈,从栈顶获取元素
        entry = checklist[-1]
        if not checkAdjacentPos(map, entry[0], entry[1], width, height, checklist):
            # 格子四周没有可以未遍历的路径,则将这个格子从栈顶删除
            checklist.remove(entry)

# 迷宫生成
def doRecursiveBacktracker(map):
    # 将所以有格子设为墙壁
    map.resetMap(MAP_ENTRY_TYPE.MAP_BLOCK)
    # 用算法产生迷宫
    recursiveBacktracker(map, (map.width - 1) // 2, (map.height - 1) // 2)

这里我使用的是以深度优先为主的递归回溯算法

随机选择一个空白方格开始,然后随机选择一个不在checklist内的相邻空白方格,将它们之间的墙壁格子转换为空白格子,然后把选择的空白方格放入checklis列表里。

递归上面的步骤没有可选择的空白方格,就删除这个方格,继而遍历前一个方格。如此往复,直到checklist列表里没有元素(即所有的方格都被遍历完),停止。

(3)实现A*算法自动寻路

"&#
  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值