您的位置:首页 > 其它

虚拟的随机迷宫创造器

2004-07-06 13:40 281 查看
/******************************************************
* 迷宫是一个游戏里经常要用到的东西,以前的迷宫都需要 *
* 巫师一个房间一个房间地手工绘制,费时费力,而且一旦 *
* 被玩家找出正确的线路,迷宫格局被泄漏,迷宫就不称其 *
* 为迷宫了,所以巫师们都绞尽脑汁把迷宫设计的尽量复杂,*
* 但再复杂的迷宫早晚也会被找到正确的路线,而且过于复 *
* 杂难走的迷宫也使玩家感觉过于繁琐,降低乐趣。因此产 *
* 生此想法。 *
* 随机迷宫的产生算法尽量简单,迷宫的储存尽量节省记忆 *
* 体,迷宫房间采用虚拟物件,处理灵活,迷宫房间只有在 *
* 玩家走到时才会装进内存,而且迷宫房间也象普通的ROOM *
* 一样当一段时间没有被参考到可以销毁节省记忆体,当整 *
* 个迷宫一段时间没有被参考到可以被完全摧毁,下次再需 *
* 要的时候会重新建立,又会产生一个新的迷宫。区域巫师 *
* 写作随机迷宫只需规定一些预设的参数如迷宫的单边长、 *
* 房间描述、出入口描述,几十个乃至几千个房间、路线时 *
* 时不同的随机迷宫就建立好了,大大提高了区域写作效率 *
* 和游戏的可玩性。 *
* 此物件目前适合于随机的迷宫,即:迷宫内房间的描述基 *
* 本相同,比如一片树林、一片坟地等,如要此物件创作完 *
* 整的随机区域即有一定的情节、一定格局的区域,则需要 *
* 根据自己的情况规定出迷宫内房间描述的一些规则,使相 *
* 邻房间的描述变化合理,房间内物件与描述协调。如果愿 *
* 意巫师可以只***迷宫间的连接部分,而用几个迷宫组合 *
* 成一个完全随机的区域,哈,那以后做巫师可轻松多了。 *
* 目前本游戏使用的迷宫一般为单边长10至40,到底能做多 *
* 大的迷宫我也不知道,下面对此有一个说明,要根据自己 *
* 的服务器性能来讲,不过我想最普通的机器***一个面积 *
* 为100x100的迷宫应该也是一件轻松的事情。 *
* 由于采用 virtual object,牵涉到一点安全问题,需要根*
* 据自己的系统考量调整。 *
******************************************************/

#pragma optimize

#define N 8
#define S 4
#define W 2
#define E 1
#define ALL 15

/****************************************************
* 迷宫的单边长最大值目前暂定为 100,由于随机迷宫的
* 创造和操作比较耗费资源单边长 100 的迷宫'面积'就是
* 100x100 等于 10000 个房间的一个迷宫,一般恐怕是用
* 不到。一般的实时迷宫(实时迷宫是指在游戏运行过程
* 中随时被 destruct 随着需要又会随时被创建的迷宫)的
* 单边长以 10 到 50 之间为宜。如需创造巨型迷宫如有几
* 万乃至十几万个房间的迷宫,应将创建工作放置于游戏启
* 动时做,游戏启动的一段时间(比如20秒)禁止玩家登入。
* 游戏通过定期重新启动来更新此迷宫。
* 不知谁会用到这么大的迷宫。。。。。。
****************************************************/
#define MAX_LONG 100

// 只要能与其他房间相连的房间就肯定有一个入口.
// 而可能的出口有三个.
// define 这项规定房间最多只能有两个出口.
// 也就是对于有三个出口的房间会随机关闭一个.
// 不会使玩家由于看到四个方向都有出口很烦
// 降低游戏乐趣。
#define TWO_VALID_LE***ES

inherit F_CLEAN_UP;

class coordinate{ int x; int y; }
class coordinate *newpath = ({}),/*待处理队列*/
enter,/* 入口坐标 */
leave;/* 出口坐标 */

private string *valid_dirs = ({ "south","north","west","east" });
private mapping reverse_dir = ([
"north" : "south",
"south" : "north",
"west" : "east",
"east" : "west",
]);

// 全迷宫出口阵列.
private mixed *all;

/***************** 迷宫的一些预设特性:*****************/
private int l; // 迷宫的单边长
private string *inherit_rooms = ({}); // 迷宫允许继承的档案名称
private string entry_dir; // 迷宫入口方向
private string link_entry_dir; // 迷宫入口与区域的连接方向
private string link_entry_room; // 迷宫入口所连接区域档案的文件名
private string link_exit_dir; // 迷宫出口与区域的连接方向
private string link_exit_room; // 迷宫出口所连接区域档案的文件名
private string entry_short; // 迷宫入口的短描述
private string entry_desc; // 迷宫入口的长描述
private string exit_short; // 迷宫出口的短描述
private string exit_desc; // 迷宫出口的长描述
private string *maze_room_desc = ({}); // 迷宫房间的长描述
private string maze_room_short; // 迷宫房间的短描述
private int is_outdoors = 0; // 迷宫房间是否为户外
private string *maze_npcs = ({}); // 迷宫中的怪物
/******************* ---- END ---- *********************/

// 建立标记.
private int maze_built = 0;

// 重置全域变量.
private void refresh_vars();

// 建立迷宫
private void create_maze();

// 选择随机出口.
private int random_out(int x,int y,int n);

// 处理连接.
private void link_to_north(int x,int y);
private void link_to_south(int x,int y);
private void link_to_west(int x,int y);
private void link_to_east(int x,int y);

// 绘制已建成迷宫的地图.
private void paint_vrm_map();

private string mroom_fname(int x,int y)
{ return sprintf("%s/%d/%d",base_name(this_object()),x,y);}

private void refresh_vars() // 重置全域变量.
{
newpath = ({});
all = 0;
}

// 对一些必设参数的合法性检查
private int check_vars()
{
int i,n;

if( (l < 5) || l > MAX_LONG )
return 0;

inherit_rooms -=({0});
if( !n = sizeof(inherit_rooms) )
return 0;

for(i=0;i

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: