我正在玩NetHack,因为我正在为自己编写简化版本。我的问题是,走廊是如何实施的?我一直试图想出一种方法,但现在却无法提出任何合理的方法。
答案 0 :(得分:8)
Nethack中的地图生成发生在mkmap.c中。方法join_map
确定应连接哪些房间。 sp_lev.c中的方法dig_corridor
进行实际挖掘。
感兴趣的行:
if (tx > xx) dx = 1;
else if (ty > yy) dy = 1;
else if (tx < xx) dx = -1;
else dy = -1;
将“当前X和Y”与“目标X和Y”进行比较,以确定我们最初将要挖掘的方向。
while(xx != tx || yy != ty) {
/* loop: dig corridor at [xx,yy] and find new [xx,yy] */
if(cct++ > 500 || (nxcor && !rn2(35)))
return FALSE;
我们将继续前进,直到达到目标为止,除了少数例外情况:如果“走廊数”cct
为500,那么我们已经挖了很长时间并想放弃。如果nxcor为真,则允许走廊走到尽头。 rn2
是一个随机数生成器,所以如果死角是可能的,那么在每个循环中我们放弃的可能性很小。
crm = &levl[xx][yy];
if(crm->typ == btyp) {
if(ftyp != CORR || rn2(100)) {
crm->typ = ftyp;
if(nxcor && !rn2(50))
(void) mksobj_at(BOULDER, xx, yy, TRUE, FALSE);
} else {
crm->typ = SCORR;
}
crm是我们目前所在的瓷砖。大多数时候,我们将瓷砖制成普通的走廊。有时候,我们会将瓷砖变成SCORR或秘密走廊,只有在您通过搜索找到它之后才能遍历。如果路径可能是死胡同,我们也会放置巨石。
/* do we have to change direction ? */
if(dy && dix > diy) {
register int ddx = (xx > tx) ? -1 : 1;
crm = &levl[xx+ddx][yy];
if(crm->typ == btyp || crm->typ == ftyp || crm->typ == SCORR) {
dx = ddx;
dy = 0;
continue;
}
} else if(dx && diy > dix) {
register int ddy = (yy > ty) ? -1 : 1;
crm = &levl[xx][yy+ddy];
if(crm->typ == btyp || crm->typ == ftyp || crm->typ == SCORR) {
dy = ddy;
dx = 0;
continue;
}
}
如果在当前位置和目标位置之间绘制的线的“斜率”明显远离45度,我们试图改变方向;如果我们沿着X轴移动,我们就开始沿着Y轴移动;反之亦然。这导致连接两个对角房间的典型波浪形楼梯形走廊。如果改变方向会导致我们遇到障碍(其他房间,熔岩等),那么我们将继续朝着我们前进的方向前进。
答案 1 :(得分:2)
您可以自己查看来源! Link
我记得很久以前就已经完成了源代码。内存有点生疏,但我认为这是一个非常简单的顺序过程。房间的盒子将被绘制成一定比例的可用瓷砖,然后它们会产生走廊并掩盖房间对着它们。我认为他们有一个通行证,他们寻找无法进入的区域(使用洪水填充?)。
然后填充楼梯/门/等。
您要找的是Maze generation algorithm。有吨。