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

入门小白,大佬慎入

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

目录:

  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列表里没有元素(即所

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是实现自动随机生成一个迷宫,并能用键盘控制小球完成走迷宫游戏Python代码。这里我们同样使用pygame和随机数模块random。 ```python import pygame import random # 定义迷宫的大小和单元格的大小 MAZE_WIDTH = 20 MAZE_HEIGHT = 15 CELL_SIZE = 30 # 定义迷宫的二维数组 maze = [[0 for y in range(MAZE_HEIGHT)] for x in range(MAZE_WIDTH)] # 定义迷宫的起点和终点 start_pos = (0, 0) end_pos = (MAZE_WIDTH - 1, MAZE_HEIGHT - 1) # 随机生成迷宫 def generate_maze(): # 初始化迷宫的基本结构 for x in range(MAZE_WIDTH): for y in range(MAZE_HEIGHT): if x == 0 or x == MAZE_WIDTH - 1 or y == 0 or y == MAZE_HEIGHT - 1: maze[x][y] = 0 else: maze[x][y] = 1 # 随机打通迷宫的墙壁 for x in range(1, MAZE_WIDTH - 1): for y in range(1, MAZE_HEIGHT - 1): if random.randint(0, 2) == 0: maze[x][y] = 0 # 设置起点和终点 maze[start_pos[0]][start_pos[1]] = 1 maze[end_pos[0]][end_pos[1]] = 1 # 绘制迷宫 def draw_maze(screen): for x in range(MAZE_WIDTH): for y in range(MAZE_HEIGHT): color = (255, 255, 255) if maze[x][y] == 0: color = (0, 0, 0) pygame.draw.rect(screen, color, (x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE)) # 绘制小球 def draw_ball(screen, pos): x, y = pos pygame.draw.circle(screen, (255, 0, 0), (x * CELL_SIZE + CELL_SIZE // 2, y * CELL_SIZE + CELL_SIZE // 2), CELL_SIZE // 2) # 判断小球是否能够移动 def can_move(pos, direction): x, y = pos if direction == pygame.K_UP: if y > 0 and maze[x][y - 1] == 1: return True elif direction == pygame.K_DOWN: if y < MAZE_HEIGHT - 1 and maze[x][y + 1] == 1: return True elif direction == pygame.K_LEFT: if x > 0 and maze[x - 1][y] == 1: return True elif direction == pygame.K_RIGHT: if x < MAZE_WIDTH - 1 and maze[x + 1][y] == 1: return True return False # 判断小球是否到达终点 def is_end(pos): return pos == end_pos # 主函数 def main(): pygame.init() screen = pygame.display.set_mode((MAZE_WIDTH * CELL_SIZE, MAZE_HEIGHT * CELL_SIZE)) pygame.display.set_caption("Maze Game") generate_maze() ball_pos = start_pos while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() return elif event.type == pygame.KEYDOWN: if event.key == pygame.K_UP and can_move(ball_pos, pygame.K_UP): ball_pos = (ball_pos[0], ball_pos[1] - 1) elif event.key == pygame.K_DOWN and can_move(ball_pos, pygame.K_DOWN): ball_pos = (ball_pos[0], ball_pos[1] + 1) elif event.key == pygame.K_LEFT and can_move(ball_pos, pygame.K_LEFT): ball_pos = (ball_pos[0] - 1, ball_pos[1]) elif event.key == pygame.K_RIGHT and can_move(ball_pos, pygame.K_RIGHT): ball_pos = (ball_pos[0] + 1, ball_pos[1]) screen.fill((255, 255, 255)) draw_maze(screen) draw_ball(screen, ball_pos) pygame.display.flip() if is_end(ball_pos): font = pygame.font.Font(None, 36) text = font.render("You Win!", True, (0, 255, 0)) text_rect = text.get_rect(centerx=screen.get_width() // 2, centery=screen.get_height() // 2) screen.blit(text, text_rect) pygame.display.flip() pygame.time.delay(2000) generate_maze() ball_pos = start_pos # 启动主函数 if __name__ == "__main__": main() ``` 运行代码后,你可以使用方向键来控制小球移动,完成走迷宫的游戏。希望对你有帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值