【游戏开发算法每日一记】使用随机prime算法生成错综复杂效果的迷宫(C#和C++)

news2025/1/12 3:00:13

在这里插入图片描述


👨‍💻个人主页:@元宇宙-秩沅

👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍💻 本文由 秩沅 原创

👨‍💻 收录于专栏:Unity基础实战

🅰️



文章目录

    • 🅰️
    • 前言
    • 🎶(==1==)简单的prime算法——十字检测
    • c#版本的十字Prim
    • c++版本的十字Prim
    • 🎶(==2==)prime算法生成的效果
    • 🅰️


前言


🎶(1简单的prime算法——十字检测


在这里插入图片描述

在这里插入图片描述

  • 1.首先全部判定为墙,最外的为路包裹墙(类似于防止数组越界
    在这里插入图片描述
  • 2.红色为它的检测范围(假设检测点在如图所示的位置)———(可先忽略此步骤)

——————在这里插入图片描述

  • 3.该检测点(紫色)需要在起点的旁边或者外墙旁边,已保证它可以生成主路线而不是死迷宫
    在这里插入图片描述
    在这里插入图片描述
  • 4.生成后是这样的,没有出口,它不会自动打破墙
    在这里插入图片描述
  • 5,所以需要我们自己检测一波打出一个出口

在这里插入图片描述

  • 运行结果
    在这里插入图片描述

c#版本的十字Prim

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace algorithm
{
    /// <summary>
    /// 该Prom算法,初始化时全部是墙
    /// </summary>
    class PrimOfAlgorithm
    {

        public const int max = 40;
        int[,] Maze = new int[max  , max ];  //默认全为0 ,全为墙
        Random random = new Random();
        //X和Y方向的队列
        List<int> X = new List<int>();
        List<int> Y = new List<int>();

        /// <summary>
        /// 生成迷宫
        /// </summary>
        public  void CreatMap()
        {
            //设置迷宫进口
            Maze[2, 1] = 1;
         
        
            //将最外围设置为路,包裹最外层的的墙,防止出界
            for (int i = 0; i < max; i++)
            {
                Maze[i ,0]= 1;
                Maze[i, max - 1] = 1;
                Maze[0, i] = 1;
                Maze[max - 1, i] = 1;  
            }

            //设置一个坐标.该检测点需要在起点的旁边,或者旁边是外围路

            X.Add (2);
            Y.Add (2);

            while( Y.Count > 0)
            {
               
                int index = random.Next(0, X.Count - 1); //随机性则有错综复杂的效果
            
                int xPosition=  X[index];
                int yPosition = Y[index];

                //判断上下左右是否有路
                int count = 0;
               
                for (int i = xPosition - 1; i <= xPosition + 1; i++) //左右位置
                {
                    for (int j = yPosition - 1; j <= yPosition + 1; j++) //上下位置
                    {
                        //判断它是不是十字检测中的点,和判断它是否为路
                        if (Math.Abs(xPosition - i) + Math.Abs(yPosition - j) == 1 && Maze[i,j] > 0) 
                         {
                            ++count; //路++  
                         }
                    }
                }

                //如果十字检测的路标记少于或等于1条?(为甚不直接小于1呢,因为它要保证生成一条主路)
                if (count <= 1)
                {
                    //将此刻的位置变成路
                    Maze[xPosition, yPosition] = 1;

                    for (int i = xPosition - 1; i <= xPosition + 1; i++)
                    {
                        for (int j = yPosition - 1; j <= yPosition + 1; j++)
                        {
                            //判断它是不是十字检测中的点并且是墙
                            if (Math.Abs(xPosition - i) + Math.Abs(yPosition - j) == 1 && Maze[i, j] == 0)
                            {
                                //把十字检测到的墙放入XY墙列表
                                X.Add(i);
                                Y.Add(j);
                            }
                        }

                    }
                }
           
                //删除列表中已经变成路的点
                X.RemoveAt(0 + index );
                Y.RemoveAt(0 + index ); //记住不能是Remove
                              
            }

            //设置迷宫出口(出口不可能是四个底脚)
            for (int i = max - 3; i >= 0; i--)
            {
                if (Maze[i, max - 3] == 1)
                {
                    Maze[i, max - 2] = 1;
                    break;
                }
            }
            //画迷宫
            for (int i = 0; i < max; i++)
            {
                for (int j = 0; j < max; j++)
                {
                    if (Maze[i, j] == 1)
                        Console.Write("  ");
                    else
                        Console.Write("囚");
                }
                Console.WriteLine();
            }

        }


        static void Main(string[] args)
        {
            PrimOfAlgorithm aa = new PrimOfAlgorithm();
         
             aa.CreatMap();
           
        }
    }


    
}

c++版本的十字Prim


#include <iostream>
#include<vector>
#include <windows.h>
using namespace std;
static const int L = 44;
void CreateMaze();
int main()
{
	CreateMaze();
}
 void CreateMaze() {
	int Maze[L][L] = { 0 };
 

	vector<int> X;
	vector<int> Y;

	//最外围设置为路,可以有效的保护里面一层墙体,并防止挖出界
	for (int i = 0; i < L; i++) {
		Maze[i][0] = 1;
		Maze[0][i] = 1;
		Maze[L - 1][i] = 1;
		Maze[i][L - 1] = 1;
	}

	//设置迷宫进口
	Maze[2][1] = 1;
	
	//任取初始值
	X.push_back(2);
	Y.push_back(2);
 
	//当墙队列为空时结束循环
	while (X.size()) {
		//在墙队列中随机取一点
		int r = rand() % X.size();
		int x = X[r];
		int y = Y[r];
 
		//判读上下左右四个方向是否为路
		int count = 0;
		for (int i = x - 1; i < x + 2; i++) {	
			for (int j = y - 1; j < y + 2; j++) {
				if (abs(x - i) + abs(y - j) == 1 && Maze[i][j] > 0) {
					++count;
				}
			}
		}
 
		if (count <= 1) {

			Maze[x][y] = 1;

			
			//在墙队列中插入新的墙
			for (int i = x - 1; i < x + 2; i++) {
				for (int j = y - 1; j < y + 2; j++) {
					
					if (abs(x - i) + abs(y - j) == 1 && Maze[i][j] == 0) {
						X.push_back(i);
						Y.push_back(j);
					}
				}
			}
		}
 
		//删除当前墙
		X.erase(X.begin() + r);
		Y.erase(Y.begin() + r);
	}
 
	//设置出口 (从最下往上面判断)
	for (int i = L - 3; i >= 0; i--) {
		if (Maze[i][L - 3] == 1) {
			Maze[i][L - 2] = 1;
			break;
		}
	}
 
	//画迷宫
	for (int i = 0; i < L; i++){
		for (int j = 0; j < L; j++) {
			if (Maze[i][j] == 1) printf("  ");
			else printf("囚");
		}
		printf("\n");
	}

	
}

🎶(2prime算法生成的效果


迷宫相对比较自然,但迷宫的分岔路会比较多,适合生成错综复杂的地图效果,主路不是特别明显

  • 初始化大地图,0代表墙,1代表道路,墙为地图边缘包裹

  • 靠近地图边缘随机选取状态为1的道路点,作为出生点a

  • 然后将 a 点周围所有的墙体点标记为待检测点,加入到待检测集合

  • 从待检测集合随机取一个点 b ,判断顺着它方向的下一个点 c,是否是道路

  • 如果是,则将这个待检测点墙体打通,将其移出待检测集合;将下一个点 c作为新的起点,重新执行第3步

  • 如果不是就把这个待检测点移出待检测集合,重新作为墙体点
    不断重复,直到待检测集合全部检查过,重新为空
    在这里插入图片描述

🅰️


⭐【Unityc#专题篇】之c#进阶篇】

⭐【Unityc#专题篇】之c#核心篇】

⭐【Unityc#专题篇】之c#基础篇】

⭐【Unity-c#专题篇】之c#入门篇】

【Unityc#专题篇】—进阶章题单实践练习

⭐【Unityc#专题篇】—基础章题单实践练习

【Unityc#专题篇】—核心章题单实践练习


你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!


在这里插入图片描述


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

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

相关文章

【01】Istio-1.17 部署

1.1 部署Istio控制平面 部署方法 istioctl istio的专用管理工具&#xff0c;支持定制控制平面和数据平面通过命令行的选项支持完整的IstioOperator API命令行各选项可用于单独设置&#xff0c;以及接收包含IstioOperator自定义资源(CR)的yaml文件 Istio Operator Istio相关的自…

哪些东西可以用超声波清洗机洗?这四款超声波清洗机可别错过

自从去眼镜店老板用超声波清洗机给我清洗过眼镜之后&#xff0c;我就发现&#xff0c;其实很多智能家居都可以帮我们大大解决一些清洁上面的问题&#xff0c;不仅方便还很高效&#xff01;这种一举两得的事情不得安排上&#xff01;现在市面上超声波清洗机可以清洗的东西是越来…

【OpenCV(4)】使用opencv编写mp4格式和avi格式

在之前的文章《【摄影与图像】444&#xff0c;422&#xff0c;420&#xff0c;10bit&#xff0c;8bit&#xff0c;RGB,YCrCb,场序&#xff0c;h264编码,封装&#xff0c;码率&#xff0c;PR常用配置》 说到了视频&#xff1a; 1、一个视频里面包含了什么&#xff1f; 图像音频…

通过百度翻译API完成Java中的中英文翻译

因为要做英文文献索引分词&#xff0c;所以对于索引词汇必须得是英文&#xff0c;将表中的中文都转换成英文 这里用到百度的翻译API 首先需要注册成为百度翻译开发者&#xff1a;百度翻译开放平台 注册成为个人开发者就可以&#xff0c; 这里可以完善相关信息&#xff0c;要记…

关于C++链接的一些理解

无论是.h还是.cpp&#xff0c;都可以写声明或者实体&#xff0c;而且.h和.cpp的前面的名字相同不相同没有任何的影响 最终一系列要连接的程序中&#xff0c;必须有且只有一个源文件有main函数&#xff0c;然后从这个main函数开始运行 include的作用其实是跟define一样的&#x…

高效筛选的秘密武器:JVS智能BI的‘and’与‘or’逻辑

在这个信息爆炸的时代&#xff0c;数据被誉为新时代的黄金和石油&#xff0c;蕴含着无尽的价值和潜力。然而&#xff0c;随着数据的爆炸式增长&#xff0c;如何高效、准确地从海量数据中提取出真正有价值的信息&#xff0c;成为摆在我们面前的一大挑战。我们需要用数据筛选工具…

app软件开发多少钱?功能会影响价格吗?

随着智能手机的普及&#xff0c;app开发市场日益繁荣&#xff0c;很多人都有开发app的梦想&#xff0c;但开发一款app需要多少钱呢?功能是否会影响价格?本文将为你揭开这个谜团。 一、app开发费用的影响因素 app开发费用受到多种因素的影响&#xff0c;例如开发难度、功能复…

垂直领域对话系统架构

垂直领域对话系统是指针对特定领域或行业的需求而构建的对话系统。这种系统通常需要具备高度的专业知识和对特定领域的知识库进行深入的学习和训练&#xff0c;以便能够提供准确、高效、实用的服务。 垂直领域对话系统的构建通常包括以下步骤&#xff1a; 确定目标领域或行业…

OpenCV:图像噪点消除与滤波算法

人工智能的学习之路非常漫长&#xff0c;不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心&#xff0c;我为大家整理了一份600多G的学习资源&#xff0c;基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…

飞天使-template模版相关知识

遇到报错django.template.exceptions.TemplateSyntaxError: ‘staticfiles’ is not a registered tag library. Must ROOT_URLCONF TEMPLATES [{BACKEND: django.template.backends.django.DjangoTemplates,DIRS: [os.path.join(BASE_DIR, templates)],APP_DIRS: True,OPTI…

css实现进度条

预期样式 方法一 <script setup> import { ref } from "vue"; // import ScreenLeft from "./ScreenLeft/index.vue"; const width ref("76.5%"); </script><template>Screen<div class"progress-contain">…

RT-DETR算法优化改进: 一种新颖的可扩张残差(DWR)注意力模块,加强不同尺度特征提取能力

💡💡💡本文全网首发独家改进:一种新颖的可扩张残差(DWR)注意力模块,加强不同尺度特征提取能力,创新十足,独家首发适合科研 1)代替RepC3进行使用; 2)DWR直接作为注意力进行使用; 推荐指数:五星 RT-DETR魔术师专栏介绍: https://blog.csdn.net/m0_63774211/…

Mysql-库的操作

1.创建数据库 CREATE DATABASE [IF NOT EXISTS] name name后可以加 CHARACTER SET 或者是 charsetname COLLATE collation_name &#xff08;mysql数据库不区分大小写&#xff09; 说明&#xff1a; name表示想创建的库的名字大写的表示关键字 [] 是可选项 CHARACTER SET…

linux openlab搭建web网站

网站需求&#xff1a; 1.基于域名 www.openlab.com 可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c; 1、基于 www.openlab.com/student 网站访问学生信息&#xff0c; 2、基于 www.openlab…

Chrome版本对应Selenium版本

1.获得浏览器版本号和驱动 访问 https://vikyd.github.io/download-chromium-history-version/ 2. 安装selenium pip install selenium3.141.0 -i http://pypi.mirrors.ustc.edu.cn/simple/ --trusted-host pypi.mirrors.ustc.edu.cn 3.解压chromedriver到python目录下 4.设…

通讯协议学习之路(实践部分):SPI开发实践

通讯协议之路主要分为两部分&#xff0c;第一部分从理论上面讲解各类协议的通讯原理以及通讯格式&#xff0c;第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN&#xff1b;视频会发布在bilibili(UID:399951374) 本文…

xinput1_3.dll丢失的详细解决步骤办法和比较,五种有效的解决办法

今天想和大家分享一个电脑中经常出现的问题——xinput1_3.dll丢失。这个文件丢失是一件常见的问题。不知道小伙伴们有没有遇到过这样的问题&#xff0c;如果你遇到这样的问题今天就教大家xinput1_3.dll丢失的详细解决步骤办法和比较&#xff0c;五种有效的解决办法。 一.xinput…

本地跑项目解决跨域问题

跨域问题&#xff1a; 指的是浏览器不能执行其他网站的脚本&#xff0c;它是由浏览器的同源策略造成的&#xff0c;是浏览器对 javascript 施加的安全限制。 同源策略&#xff1a; 是指协议&#xff08;protocol&#xff09;、域名&#xff08;host&#xff09;、端口号&…

开源7合一万能DIY小程序源码系统 一个后台整合7端 轻松搭建小程序 带完整搭建教程

随着移动互联网的快速发展&#xff0c;小程序已经成为了一个炙手可热的领域。但是&#xff0c;对于很多开发者来说&#xff0c;搭建一个小程序并不容易。为了解决这个问题&#xff0c;罗峰来给大家介绍一款开源的7合一万能DIY小程序源码系统&#xff0c;它可以将7个端整合到一个…

如何利用大模型蒸馏出小模型实现降本

如何让小模型的推理效果在某些领域比 ChatGPT 这样的大模型还要更强&#xff1f;这篇论文提供了一个思路&#xff1a;https://arxiv.org/abs/2212.10071&#xff0c;借助思维链&#xff08;CoT&#xff09;逐步解决复杂推理任务的能力&#xff0c;可以使用大模型作为推理教师&a…