Double layer cave generator

From RogueBasin
Revision as of 08:24, 3 April 2012 by Korumuda (talk | contribs) (Sorry for my bad grammar. I'm not native english speaker.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This dungeon generator is mainly based on Cellular Automata Method, so I suggest to read that article first. With my this generator modification, you will generate absolutely random caves, and there will not be any unreachable disconnected space.


Algorithm

In words there are only 3 (or 4, if you want less open space) steps:

  • Generate one map by Cellular Automata method.
  • Generate another one map with that method.
  • Fuse both maps: that means check both map arrays if first map's square is "wall", and second map's is "wall", then, invert and make "stepable" square, else, do not invert and keep "wall". If first map's square is "stepable" and second map's square too, then invert and make "wall", else, keep "stepable square".
  • (Optional step) Generate random walls: like, if there is 3 or less "walls" in 3 square radius around another square, make that square also "wall". Or something like that.


Also, there is dirty(we can join some loops) code in Pascal language:

  program Map_Gen;
   uses crt;
   var x, y: array [1..116,1..50,1..5] of char;
   xx: array[1..116,1..50] of integer;
   i, j, q, qq, ii, jj, ax, ay, k:integer;
begin
   Randomize;
   
   for i:=1 to 50 do
       for j:=1 to 116 do begin
           If (i=1) or (i=50) or (j=1) or (j=116) then xx[j,i]:=-1
           else xx[j,i]:=0;
       end;
   for i:=1 to 50 do
       for j:=1 to 116 do begin
           If (i=1) or (i=50) or (j=1) or (j=116) then begin
               x[j,i,1]:='#';
               x[j,i,5]:='#';
               y[j,i,1]:='#';
           end
           else begin
               q:=random(100);
               if q<45 then x[j,i,1]:='#'
               else x[j,i,1]:='.';
               qq:=random(100);
               if qq<45 then y[j,i,1]:='#'
               else y[j,i,1]:='.';
           end;
       end;
   
   for k:=2 to 5 do begin
       TextColor(k);
       for i:=2 to 49 do begin
           for j:=2 to 115 do begin
               ax:=0;
               ay:=0;
               for ii:=(i-1) to (i+1) do begin
                   for jj:=(j-1) to (j+1) do begin
                       If (x[jj,ii,k-1]='#') then ax:=ax+1;
                       If (y[jj,ii,k-1]='#') then ay:=ay+1;
                   end;
               end;
               If ((x[j,i,k-1]='#') and (ax>3)) or (ax>4) then begin
                   x[j,i,k]:='#';
               end
               else begin
                   x[j,i,k]:='.';
               end;
               If ((y[j,i,k-1]='#') and (ay>3)) or (ay>4) then begin
                   y[j,i,k]:='#';
               end
               else begin
                   y[j,i,k-1]:='.';
               end;
           end;
       end;
   end;
   
   for i:=2 to 49 do begin
       for j:=2 to 115 do begin
           Case x[j,i,5] of
           '#':    if x[j,i,5]=y[j,i,5] then begin
                       x[j,i,5]:='.';
                       xx[j,i]:=0;
                   end
                   else begin
                       x[j,i,5]:='#';
                       xx[j,i]:=-1;
                   end;
           '.':    if x[j,i,5]=y[j,i,5] then begin
                       x[j,i,5]:='#';
                       xx[j,i]:=-1;
                   end
                   else begin
                       x[j,i,5]:='.';
                       xx[j,i]:=0;
                   end;
           end;
       end;
   end;
   
   for i:=22 to 28 do
       for j:=55 to 61 do begin
           x[j,i,5]:='.';
           xx[j,i]:=0;
       end;
       
   xx[58,25]:=1;
   for k:=1 to 50 do
       for i:=2 to 49 do
           for j:=2 to 115 do begin
               if xx[j,i]=k then begin
                   for ii:=(i-1) to (i+1) do begin
                       for jj:=(j-1) to (j+1) do begin
                           if (xx[jj,ii]=0) then xx[jj,ii]:=k+1;
                       end;
                   end;
               end;
           end;
   for i:=2 to 49 do
       for j:=2 to 115 do begin
           if (xx[j,i]=0) and (x[j,i,5]='.') then begin
           x[j,i,5]:='#';
           end;
       end;
   for i:=1 to 50 do
       for j:=1 to 116 do begin
           GoToXY(j,i);
           Write(x[j,i,5]);
       end;
   Readln;
end.