NetHack走廊实施

zbu*_*s12 8 c++ nethack

我正在玩NetHack,因为我正在为自己编写简化版本.我的问题是,走廊是如何实施的?我一直试图想出一种方法,但现在却无法想出任何合理的方法.

Kev*_*vin 8

Nethack中的地图生成发生在mkmap.c中.该方法join_map确定应连接哪些房间.dig_corridorsp_lev.c中的方法进行实际挖掘.

兴趣点:

if (tx > xx)        dx = 1;
else if (ty > yy)   dy = 1;
else if (tx < xx)   dx = -1;
else            dy = -1;
Run Code Online (Sandbox Code Playgroud)

这将"当前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;
Run Code Online (Sandbox Code Playgroud)

我们将继续前进,直到我们达到目标,除了少数例外:如果"走廊数" 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;
    }
Run Code Online (Sandbox Code Playgroud)

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;
    }
    }
Run Code Online (Sandbox Code Playgroud)

如果在当前位置和目标位置之间绘制的线的"斜率​​"明显远离45度,我们试图改变方向; 如果我们沿着X轴移动,我们就开始沿着Y轴移动; 反之亦然.这导致连接两个对角房间的典型波浪形楼梯形走廊.如果改变方向会导致我们遇到障碍(其他房间,熔岩等),那么我们将继续朝着我们前进的方向前进.