首页 > 编程语言 >类以撒的结合的房间生成算法

类以撒的结合的房间生成算法

时间:2024-03-07 19:23:27浏览次数:20  
标签:10 int create 房间 private 生成 算法 Rooms 类以

类以撒的结合的房间生成算法

原链接
翻译版本

目前本人只实现了房间大小都一样的情况,没有什么2x2,L型,2x1之类的房间

放个效果图
image

算法需要注意的

房间选择

  • 对于当前位置是否有设置房间(是否被占位)
  • 当前房间位置是否越界(超出限定范围)
  • 当前位置的周围4方向的房间量是否大于1个(为什么是1而不是0,因为那一个1是父节点,可以排除掉)
  • 随机一个概率要是以上都满足可以设定一个概率是否抛弃

以下代码是基于在Unity上实现的,也有注释,应该很好理解

using System.Collections.Generic;
using UnityEngine;
//************************************
//创建人:一个人心
//功能说明:地牢生成
//************************************
public class DungeonGeneration : MonoBehaviour {
	public GameObject RoomPref;
	public Transform RoomParent;
	private SpriteRenderer[] Rooms = new SpriteRenderer[100];
	private int[] floorplan = new int[100];

	private Queue<int> cellQueue = new Queue<int>();    // 所有已放置的房间
	private Queue<int> endRoom = new Queue<int>();      // 末尾房间
	private int startRoom = 35;

	public int level = 1;
	public int currentfloorPlan;
	public int maxfloorPlan;

	private void Awake() {
		// 初始化地图
		for (int i = 0; i < Rooms.Length; i++) {
			floorplan[i] = 0;
			var go = Instantiate(RoomPref, RoomParent);
			go.transform.localPosition = new Vector3(i % 10, i / 10, 0);
			Rooms[i] = go.GetComponent<SpriteRenderer>();
			Rooms[i].color = Color.black;
		}

	}

	[ContextMenu("生成地牢")]
	private void BuildRangeRoom() {

		// 初始化
		currentfloorPlan = 0;
		maxfloorPlan = (int)(Random.Range(0, 2) + 5 + level * 2.6);
		cellQueue.Clear();
		endRoom.Clear();
		for (int i = 0; i < Rooms.Length; i++) {
			floorplan[i] = 0;
			Rooms[i].color = Color.black;		// 设置黑色表示是墙 or 空位置
		}

		// 将开始房间入
		visit(startRoom);
		Rooms[startRoom].color = Color.yellow;
		while (cellQueue.Count > 0) {
			int i = cellQueue.Dequeue();
			int x = i % 10;

			bool create = false;		// 标记当前房间是否有扩展出来的房间
			if (x > 1) create = create | visit(i - 1);
			if (x < 9) create = create | visit(i + 1);
			if (i >= 10) create = create | visit(i - 10);
			if (i < 90) create = create | visit(i + 10);

			// 如果当前房间周围都不放置(i房间是末尾房)
			// 末尾房可以设置一些特殊房间,因为末尾房是离起点远的房间
			if (!create && i != startRoom) {
				endRoom.Enqueue(i);
				Rooms[i].color = Color.red;		
			}

			// 当生成的房间数量大于一定时,可以将起点重写传回去
			// 可以激励中心不会那么零散
			if (currentfloorPlan > 16) {
				if (Random.value < 0.25) {
					Debug.Log("startRoom");
					cellQueue.Enqueue(startRoom);
				}
			}
		}

		// 不合法
		if (currentfloorPlan == 1) BuildRangeRoom();
	}

	/// <summary>
	/// 检测是否可行
	/// </summary>
	/// <param name="i"></param>
	/// <returns></returns>
	private bool visit(int i) {
		// 检测当前放置的房间是否已经超出了
		if (currentfloorPlan >= maxfloorPlan) return false;
		// 检测是否被占用
		if (floorplan[i] != 0) return false;
		// 50%舍去
		if (Random.value < 0.5 && i != startRoom) return false;
		// 如果邻居数量大于1,因为1是之前的
		if (nCount(i) > 1) return false;

		// 可行
		cellQueue.Enqueue(i);   // 添加到已放置队列
		floorplan[i] = 1;       // 标记占用
		currentfloorPlan++;     // 总数++
		Rooms[i].color = Color.white;

		return true;
	}

	/// <summary>
	/// 检测周围邻居数
	/// </summary>
	/// <param name="i"></param>
	/// <returns></returns>
	private int nCount(int i) {
		int sum = 0;
		if (i + 10 < 100) sum += floorplan[i + 10];
		if (i - 10 >= 0) sum += floorplan[i - 10];
		if (i % 10 + 1 <= 9) sum += floorplan[i + 1];
		if (i % 10 - 1 >= 0) sum += floorplan[i - 1];
		return sum;
	}

}

标签:10,int,create,房间,private,生成,算法,Rooms,类以
From: https://www.cnblogs.com/onepeopleheart/p/18059559

相关文章

  • oracle11g awr手动生成快照
    您可以手动生成一个快照,以收集Oracle数据库的AWR(AutomaticWorkloadRepository)数据。请按照以下步骤生成一个快照:登录到Oracle数据库实例所在的服务器。切换到具有适当权限的Oracle用户。打开SQL*Plus或其他OracleSQL客户端。运行以下命令来生成快照:EXECDBM......
  • day57 动态规划part14 代码随想录算法训练营 53. 最大子数组和
    题目:53.最大子数组和我的感悟:理解难点:递推公式想错了。听课笔记:我的错误的代码:通过截图:代码易错点:老师代码:扩展写法:资料:......
  • day57 动态规划part14 代码随想录算法训练营 1035. 不相交的线
    题目:1035.不相交的线我的感悟:换汤不换药理解难点:换了个壳子听课笔记:多理解这个题意我的代码:classSolution:defmaxUncrossedLines(self,nums1:List[int],nums2:List[int])->int:#因为强调顺序,所以跟1143最长公共子序列是一样的dp......
  • 使用BPF之前和之后生成直方图过程的对比
    以bitehist为例:使用BPF之前:1、在内核中:开启磁盘IO事件的插桩观测。2、在内核中,针对每个事件:向perf缓冲区写入一条记录。如果使用了跟踪点技术(推荐方式),记录中会包含关于磁盘IO的几个元数据字段。3、在用户空间:周期性地将所有事件的缓冲区内容复制到用户空间4。在用户空间:......
  • 代码随想录算法训练营第三十九天|● 62.不同路径 ● 63. 不同路径 II
    不同路径 题目链接:62.不同路径-力扣(LeetCode)思路:由于不能回退,因此每一格只能来自上一格或左边一格,因此dp数组中每个格子只要将这两个格子的值相加即可。classSolution{public:intuniquePaths(intm,intn){vector<vector<int>>dp(m,vector<int>(n));......
  • day57 动态规划part14 代码随想录算法训练营 1143. 最长公共子序列
    题目:1143.最长公共子序列我的感悟:你永远不知道自己有多厉害!加油!理解难点:递推公式如何想,通过图,来记忆。听课笔记:我的代码:classSolution:deflongestCommonSubsequence(self,text1:str,text2:str)->int:#假设text1为内层,text2为外层n......
  • 代码随想录算法训练营第三十七天 | 62.不同路径 ,63. 不同路径 II
    63.不同路径II 已解答中等 相关标签相关企业 提示 一个机器人位于一个 mxn 网格的左上角(起始点在下图中标记为“Start”)。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。现在考虑......
  • 文心一言 VS 讯飞星火 VS chatgpt (209)-- 算法导论15.4 6题
    六、设计一个O(nlgn)时间的算法,求一个n个数的序列的最长单调递增子序列。(提示:注意到,一个长度为i的候选子序列的尾元素至少不比一个长度为i-1候选子序列的尾元素小。因此,可以在输入序列中将候选子序列链接起来。)要写代码的时候,请用go语言。文心一言,代码正常运行:要设计一......
  • 代码随想录算法训练营第二天| 977.有序数组的平方、 209.长度最小的子数组、 59.螺旋
    977.有序数组的平方https://leetcode.cn/problems/squares-of-a-sorted-array/description/publicstaticint[]sortedSquares(int[]nums){intleft=0;intright=nums.length-1;int[]result=newint[nums.length];intwrite=......
  • Python根据坐标半径生成测试点数据
    一、代码#-*-coding:UTF-8-*-importcsvimportrandomimportmathimportdatetimefromfakerimportFaker#定义语言faker_data=Faker(locale='zh_CN')#获取当前时间current_time=datetime.datetime.now()#格式化时间formatted_time=current_time.strft......