【Python】生成二维迷宫的算法

news2024/11/24 2:26:07

前言

哈里最近因为一个小插曲打算写一个设计迷宫的算法。为了锻炼脑力,特地没有上网搜索而是自己摸索出一个迷宫设计算法。

概述

1、需求

哈里准备实现下图的迷宫。

2、分析

可以看到,图里凡是x和y坐标为单数时,总是白色。于是哈里得到下图:

我将白色区域定义为房间(room),每个房间有四个方向(上下左右)可以连接其它房间。

我将能从绿色(出发点)到达的房间设置其连通(alive)。上图就只有(1,1)的房间连通。

这里哈里思考,如果每个房间都与出发点连通,最后右下角的房间必然就可以和出发点连通。

实际尝试之后,确实获得了一个还不错的迷宫图像,但是会出现下图的问题:

x=1和y=1总是会有大片的空白。

对此,哈里尝试将房间迭代的顺序打乱,最终得到了可以接受的迷宫图。

3、结语

差不多就是这样了……脑子混沌的时候靠直觉直接猜的……不完美但够用就行。

源码

import random
import sys

from PIL import Image
from pygame import *
import time
import pygame

# 方向向量,用于四个方向:上、右、下、左
dirVector = [
  (0, 1),    # 下
  (1, 0),    # 右
  (-1, 0),   # 左
  (0, -1),   # 上
]

# 房间类,定义房间的位置和是否激活
class Room:
  def __init__(self, pos, alive=False):
    self.pos = pos  # 房间位置
    self.alive = alive  # 房间是否激活

  # 链接房间
  def Link(self):
    if self.alive:
      return  # 如果房间已激活,则返回

    dirs = self.GetCanOpenDirs()  # 获取可以打开的方向
    if not dirs:
      return  # 如果没有可用方向,则返回
    dirs = random.sample(dirs, 1)  # 随机选择一个方向
    for d in dirs:
      img.putpixel((self.pos[0] + d[0], self.pos[1] + d[1]), (255, 255, 255))  # 在图像上绘制房间
    self.alive = True  # 激活房间

  # 获取可以打开的方向
  def GetCanOpenDirs(self):
    r = []
    for d in dirVector:
      _x, _y = self.pos[0] + d[0], self.pos[1] + d[1]  # 计算方向上的位置
      # 检查是否在图像边界内
      if _x < 1 or _y < 1 or _x >= img.width - 1 or _y >= img.height - 1:
        continue
      p2 = (self.pos[0] + d[0] * 2, self.pos[1] + d[1] * 2)  # 计算下一个位置
      if p2 not in allRoom or not allRoom[p2].alive:
        continue
      r.append(d)  # 将有效方向添加到列表
    return r

  @property
  def isColse(self):
    for d in dirVector:
      x, y = self.pos[0] + d[0], self.pos[1] + d[1]  # 计算相邻位置
      if img.getpixel((x, y)) != (0, 0, 0):  # 检查相邻像素是否为黑色
        return False
    return True

# 判断所有房间是否激活
def JudgeAllAlive():
  for _room in allRoom.values():
    if not _room.alive:
      return False
  return True

# 初始化pygame
pygame.init()
pygame.display.set_caption('预览')  # 设置窗口标题
size = (21, 21)  # 图像大小
# screen = pygame.display.set_mode(Vector2(size) * 10)  # 缩放图像
screen = pygame.display.set_mode(Vector2(size))  # 创建显示窗口
img = Image.new('RGB', size, (255, 255, 255))  # 创建新图像,背景为白色
endPos = (size[0] - 2, size[1] - 1)  # 终点位置
rooms = []  # 房间列表
allRoom = {}  # 所有房间字典

# 初始化图像上的黑色网格
for y in range(img.height):
  for x in range(0, img.width, 2):
    img.putpixel((x, y), (0, 0, 0))

for x in range(img.width):
  for y in range(0, img.height, 2):
    img.putpixel((x, y), (0, 0, 0))

# 添加房间到列表和字典
for x in range(1, img.width, 2):
  for y in range(1, img.height, 2):
    rooms.append((x, y))
    allRoom[(x, y)] = Room((x, y))
allRoom[(1, 1)].alive = True  # 激活起点房间

random.shuffle(rooms)  # 打乱房间顺序
for roomPos in rooms:
  allRoom[roomPos].Link()  # 链接所有房间

# 标记起点和终点
img.putpixel((1, 0), (0, 255, 0))  # 起点标记为绿色
img.putpixel(endPos, (255, 0, 0))  # 终点标记为红色
tempImg = img.copy()  # 复制图像用于更新显示

# 游戏主循环
while 1:
  for event in pygame.event.get():  # 从Pygame的事件队列中取出事件,并从队列中删除该事件
    if event.type == pygame.QUIT:  # 检查退出事件
      sys.exit()  # 退出程序
  screen.fill((255, 255, 255))  # 填充背景为白色
  tempImg = img.copy()  # 复制图像用于更新显示
  if not JudgeAllAlive():  # 检查是否所有房间都激活
    random.shuffle(rooms)  # 打乱房间顺序
    for roomPos in rooms:
      allRoom[roomPos].Link()  # 链接房间
      if not allRoom[roomPos].alive:
        tempImg.putpixel(roomPos, (255, 125, 0))  # 未激活的房间标记为橙色
  else:
    break  # 如果所有房间都激活,退出循环
  pygameImg = pygame.image.frombuffer(tempImg.tobytes(), size, 'RGB')  # 将图像转换为Pygame格式
  # pygameImg = pygame.transform.scale(pygameImg, Vector2(size) * 10)  # 缩放图像
  screen.blit(pygameImg, (0, 0))  # 绘制图像到屏幕
  # time.sleep(0.05)  # 延时
  pygame.display.flip()  # 更新显示

img.save('mg.png')  # 保存图像为文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2046098.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二分查找专题(总)

1、经典二分查找模板 int search(vector<int>& nums, int target) {int right nums.size() - 1;int left 0;while(left < right){int mid (left right)/2;if(nums[mid] > target){right mid-1;}else if(nums[mid] < target){left mid1;}else {return…

c语言-经典例题

C语言-经典例题 一、单项选择题 1、 -- A 2、 -- C y<5 --是关系运算符的优先级大于&& -- 是逻辑运算符 3、 -- B - D选项&#xff1a;c是float类型&#xff0c;所以c/2是1.5 4、 -- C 从后往前执行&#xff08;先算后面的&a…

【uniapp】vue3+vite配置tailwindcss

安装 npm install autoprefixer tailwindcss uni-helper/vite-plugin-uni-tailwind -Dautoprefixer &#xff1a;自动管理浏览器前缀的插件&#xff0c;可以解析css文件并且添加前缀到css内容里。uni-helper/vite-plugin-uni-tailwind: 将 Tailwind CSS 框架集成到使用 Vite 作…

linux系统编程:多任务编程(进程1)

1.进程 进程:(进行中的程序)--正在运行的程序 (动态的) ---内存 程序的一次执行过程&#xff01; 一个程序一个程序 可以 对应多个进程 程序 -- a.out (可执行程序) ---静态的 程序 加载 到内存 运行起来 成为了 进程。 进程是 程序运行的实体。 程序 数据代码 2.进…

背包九讲(求方案数,求具体方案数,有依赖背包)

文章目录 求方案数基本思路代码 背包问题求具体方案基本思路代码 有依赖背包基本思路代码 求方案数 问题描述&#xff1a; 给定n nn个物品&#xff0c;以及一个容量大小为m mm的背包&#xff0c;然后给出n nn个物品的体积及价值&#xff0c;求背包最大价值是多少&#xff0c;也…

递归排序 归并排序 快排

递归 求中点 midL(R-L)/2 midL((R-L)>>1)右移一位更快 子问题等量 mast er公式 T(N) a*T(N/b)O(N^d) T(N):母 T(N/b)&#xff1a;子 &#xff08;是否等量&#xff09; a&#xff1a;调用多少次 O(N^d)&#xff1a;除去子变量之外的时间复杂度 子问题等量 上面…

sqli-labs-master靶场通关

目录 一、sqli-labs第一关 1.判断是否存在sql注入 &#xff08;1&#xff09;提示输入数字值的ID作为参数&#xff0c;输入?id1 &#xff08;2&#xff09;通过数字值不同返回的内容也不同&#xff0c;所以我们输入的内容是带入到数据库里面查询了 &#xff08;3&#xff0…

信号量和管道

一、信号量 实现模拟售票问题&#xff1a; 1、信号量的机制&#xff1a;描述可使用资源的个数。 &#xff08;1&#xff09;P操作&#xff1a;表示使用这个资源&#xff0c;资源个数减一 逻辑&#xff1a;尝试获取资源——有资源可用直接使用 | 无资源可用等待 如果信号量的…

面向新人的 Java 面试问题(101-150)

101.什么是多态&#xff1f; 多态性被定义为能够采用多种形式的能力。它有两种类型&#xff0c;即编译时多态性或方法重载 - 在编译时调用的函数。例如&#xff0c;以“面积”类为例。根据参数数量&#xff0c;它可以计算正方形、三角形或圆形的面积。运行时多态性或方法覆盖 …

【详细】linux 打包QT程序

【详细】linux 打包QT程序 一. 安装linuxdeployqt1.1 下载linuxdeployqt源码并修改如下 二. 安装patchelf三. 打包appimage四. 打包成 Debian包4.1 control文件内容4.2 postinst文件内容4.3 postrm文件内容4.4 打包命令4.4 安装命令4.5 卸载命令 一. 安装linuxdeployqt 下载地…

【Redis】Redis 数据类型与结构—(二)

Redis 数据类型与结构 一、值的数据类型二、键值对数据结构三、集合数据操作效率 一、值的数据类型 Redis “快”取决于两方面&#xff0c;一方面&#xff0c;它是内存数据库&#xff0c;另一方面&#xff0c;则是高效的数据结构。 Redis 键值对中值的数据类型&#xff0c;也…

被极氪“背刺”新能源汽车车主,你可以说不

文 魏强 导语&#xff1a;谁也改变不了不断被“背刺”的命运。 8月13日晚&#xff0c;极氪召开发布会主推两款改款车——2025款极氪007升级了第二代金砖电池&#xff08;磷酸铁锂&#xff09;、标配了激光雷达和两颗Orin X芯片、全系降价2-3万元。2025款极氪001智驾芯片从Mob…

Artifactory集成LDAP示例

LDAP在企业软件身份认证中起到了非常关键的作用&#xff0c;给企业内用户带来了非常多的便利&#xff0c;JFrog 平台支持针对开箱即用的 LDAP 服务器对用户进行身份验证。下面我们一起看下Artifactory如何集成LDAP&#xff0c;本示例以OpenLDAP为例。 1.快速安装OpenLDAP doc…

SqlSugar详解-国产ORM框架

ORM (Object-Relational Mapping) 概念 ORM 是一种程序技术&#xff0c;用于将关系型数据库中的数据映射到对象上。 主要目的是简化数据库操作&#xff0c;使得开发人员可以像操作对象一样来操作数据库。 原理 数据表与类的映射&#xff1a;数据库中的表对应为类。 记录与对象…

灵办AI助手Chrome插件全面评测:PC Web端的智能办公利器

探索灵办AI助手在Mac OS上的高效表现&#xff0c;支持多款主流浏览器&#xff0c;助你轻松应对办公挑战 文章目录 探索灵办AI助手在Mac OS上的高效表现&#xff0c;支持多款主流浏览器&#xff0c;助你轻松应对办公挑战摘要引言开发环境介绍核心功能评测1. 网页翻译与双语对照 …

【祖孙询问】

问题 代码 #include <bits/stdc.h> using namespace std; const int N 4e410; vector<int> edge[N]; int p[N][20], d[N]; void dfs(int from, int u) {for(auto to : edge[u]){if(to from) continue;d[to] d[u] 1;p[to][0] u;dfs(u, to);}} void init() {fo…

mysql主从同步遇到的问题

1&#xff0c;主库data文件复制到从库&#xff0c;之后主库要同步的实例data一定不要在修改&#xff1b; 1.1&#xff0c;修改之后就要重新覆盖一遍 2&#xff0c;如果状态不对&#xff1a;一定要查看日志&#xff1b;比如slave_io_state是空时&#xff0c;需要查看日志 2.1&a…

使用百度文心智能体创建AI旅游助手

百度文心智能体平台为你开启。百度文心智能体平台&#xff0c;创建属于自己的智能体应用。百度文心智能体平台是百度旗下的智能AI平台&#xff0c;集成了先进的自然语言处理技术和人工智能技术&#xff0c;可以用来创建属于自己的智能体应用&#xff0c;访问官网链接&#xff1…

查看电脑连接过的wifi密码

netsh wlan show profiles netsh wlan show profile name"8821" keyclear

用Python实现9大回归算法详解——01. 线形回归算法

1. 线性回归的基本概念 线性回归是一种最基本的监督学习算法&#xff0c;用于预测因变量&#xff08;目标变量&#xff09;和一个或多个自变量&#xff08;特征变量&#xff09;之间的关系。线性回归假设因变量与自变量之间的关系是线性的&#xff0c;即可以用以下形式的线性方…