2013-02-26 2 views
7

Ich spielte gerade mit NetHack herum, während ich gerade daran war, eine vereinfachte Version für mich selbst zu programmieren. Meine Frage ist, wie werden Korridore umgesetzt? Ich habe schon seit ein paar Tagen versucht, an einen Ansatz zu denken und kann mir nichts vernünftiges einfallen lassen.NetHack-Korridor-Implementierung

Antwort

7

Die Kartengenerierung in Nethack erfolgt in mkmap.c. Die Methode join_map legt fest, welche Räume verbunden werden sollen. Die Methode dig_corridor in sp_lev.c erledigt das eigentliche Graben.

Linien von Interesse.

if (tx > xx)  dx = 1; 
else if (ty > yy) dy = 1; 
else if (tx < xx) dx = -1; 
else   dy = -1; 

Diese "aktuellen X und Y" durch "Ziel-X und Y" vergleicht, die Richtung zu bestimmen, die man zunächst in Wir

while(xx != tx || yy != ty) { 
    /* loop: dig corridor at [xx,yy] and find new [xx,yy] */ 
    if(cct++ > 500 || (nxcor && !rn2(35))) 
    return FALSE; 

graben Ich werde weitermachen, bis wir das Ziel erreichen, mit ein paar Ausnahmen: Wenn "Korridoranzahl" cct 500 ist, dann haben wir einen langen Weg gegraben und wollen aufgeben. Wenn nxcor wahr ist, darf der Korridor in eine Sackgasse enden. rn2 ist ein Zufallszahlengenerator, also wenn eine Sackgasse möglich ist, dann gibt es eine kleine Chance während jeder Schleife, die wir aufgeben werden.

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 ist die Kachel, auf der wir uns gerade befinden. Die meiste Zeit machen wir die Fliese zu einem normalen Korridor. Manchmal machen wir die Kachel zu einem SCORR oder Secret Corridor, der nur durchsucht werden kann, nachdem Sie ihn gefunden haben. Wir setzen auch Felsbrocken, wenn der Weg eine Sackgasse ist.

/* 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; 
    } 
    } 

Wenn die „Steigung“ der Linie zwischen der aktuellen Position und der Zielposition von 45 Grad deutlich weit gezogen wird, versuchen wir, die Richtung zu ändern; wenn wir uns entlang der X-Achse bewegen, bewegen wir uns stattdessen entlang der Y-Achse; und umgekehrt. Dies führt zu den typischen verzierten treppenförmigen Korridoren, die zwei diagonale Räume verbinden. Wenn wir die Richtung ändern würden, würden wir auf ein Hindernis treffen (andere Räume, Lava, etc.), dann gehen wir weiter in die Richtung, in die wir gingen.

+0

Danke, dass du herausgefunden hast, wo der Code tatsächlich war! Ich wollte, aber ich wurde von Faulheit zurückgehalten. – MrLeap

2

Sie könnten die Quelle für sich selbst auschecken! Link

Ich erinnere mich daran, den Quellcode vor langer Zeit einmal durchlaufen. Die Erinnerung ist ein bisschen rostig, aber ich denke, es war ein ziemlich einfacher sequenzieller Prozess. Boxen wurden für Räume mit einem bestimmten Verhältnis von verfügbaren Kacheln gezeichnet, dann erzeugten sie die Korridore und maskierten die Räume gegen sie. Ich glaube, sie hatten einen Pass, wo sie nach Gebieten suchten, die nicht zugänglich waren (mit einer Flutfüllung?).

Dann wurden Treppen/Türen/etc bevölkert.

Was Sie suchen, ist ein Maze generation algorithm. Es gibt Tonnen.