document.write('
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. # Class to produce random map layouts
  2. # based on this code: http://www.roguebasin.com/index.php?title=Dungeon_builder_written_in_Python
  3. # Original author: Steve Wallace
  4. # Ruby-version author: DeadElf79
  5. # e-mail me deadelf@gmail.com if you found error
  6. class DungeonMap
  7.     # Initialize
  8.     #
  9.     def initialize
  10.         @room_list=[]
  11.         @cor_list=[]
  12.     end
  13.    
  14.     # Generate random layout of rooms, corridors and
  15.     # other features
  16.     # This method can be modified to accept arguments for
  17.     # values of failed, and percentile of features.
  18.     #
  19.     def make_map(xs, ys, fail, b1, mrooms)
  20.         # Create first room
  21.         @xsize = xs
  22.         @ysize = ys
  23.         # initialize map to all walls
  24.         @mapArr= []
  25.         @ysize.times{
  26.             @mapArr<<Array.new(@xsize,1)
  27.         }
  28.        
  29.         w,l,t=make_room
  30.         while @room_list.size==0
  31.             x=rand(@xsize-1-w)+1
  32.             y=rand(@ysize-1-l)+1
  33.             p=place_room(l,w,x,y,@xsize,@ysize,6,0)
  34.         end
  35.         failed=0
  36.         while failed<fail # The lower the value that failed<, the smaller the dungeon
  37.             choose_room=rand(@room_list.size)
  38.             ex,ey,ex2,ey2,et=make_exit(choose_room)
  39.             feature=rand(100)
  40.             if feature<b1 # Begin feature choosing (more features to be added here)
  41.                 w,l,t=make_corridor
  42.             else
  43.                 w,l,t=make_room
  44.             end
  45.            
  46.             room_done=place_room(l,w,ex2,ey2,@xsize,@ysize,t,et)
  47.             case room_done
  48.             when 0 # If placement failed increase possibility map is full
  49.                 failed+=1
  50.             when 2 # If Possibility of linking rooms
  51.                 if @mapArr[ey2][ex2]==0
  52.                     if rand(100)<7
  53.                         make_portal(ex,ey)
  54.                     end
  55.                     failed+=1
  56.                 end
  57.             else # Otherwise, link up the 2 rooms
  58.                 make_portal(ex,ey)
  59.                 failed=0
  60.                 if t<5
  61.                     tc=[@room_list.size-1,ex2,ey2,t]
  62.                     @cor_list<<tc
  63.                     join_corridor(@room_list.size-1,ex2,ey2,t,50)
  64.                 end
  65.             end
  66.             failed=fail if @room_list.size==mrooms
  67.         end
  68.         final_joins
  69.         @mapArr
  70.     end
  71.    
  72.     # Randomly produce room size
  73.     #
  74.     def make_room
  75.         rtype=5
  76.         rwide=rand(8)+3
  77.         rlong=rand(8)+3
  78.         return rtype,rwide,rlong
  79.     end
  80.    
  81.     # Randomly produce corridor length and heading
  82.     #
  83.     def make_corridor
  84.         clength=rand(18)+3
  85.         heading=rand(3)
  86.         case heading
  87.         when 0 # North
  88.             wd=1
  89.             lg=-clength
  90.         when 1 # East
  91.             wd=clength
  92.             lg=1
  93.         when 2 # South
  94.             wd=1
  95.             lg=clength
  96.         when 3 # West
  97.             wd=-clength
  98.             lg=1
  99.         end
  100.         return wd,lg,heading
  101.     end
  102.    
  103.     # Place feature if enough space and return:
  104.     # 0 - if no space
  105.     # 1 - add room
  106.     # 2 - linking rooms
  107.     def place_room(ll,ww,xposs,yposs,xsize,ysize,rty,ext)
  108.         # Arrange for heading
  109.         xpos=xposs
  110.         ypos=yposs
  111.         if ll<0 then
  112.             ypos+=ll+1
  113.             ll=ll.abs
  114.         end
  115.         if ww<0 then
  116.             xpos+=ww+1
  117.             ww=ww.abs
  118.         end
  119.         # Make offset if type is room
  120.         if rty==5 then
  121.             if ext==(0||2) then
  122.                 offset=rand(ww)
  123.                 xpos-=offset
  124.             else
  125.                 offset=rand(ll)
  126.                 ypos-=offset
  127.             end
  128.         end
  129.         # Then check if there is space
  130.         if (ww+xpos+1>xsize-1)||(ll+ypos+1>ysize)
  131.             return 0
  132.         elsif xpos<1 or ypos<1
  133.             return 0
  134.         else
  135.             ll.times{|j|
  136.                 ww.times{|k|
  137.                     return 2 if @mapArr[(ypos-1)+j][(xpos-1)+k]!=1
  138.                 }
  139.             }
  140.         end
  141.         # If there is space, add to list of rooms
  142.         temp=[ll,ww,xpos,ypos]
  143.         @room_list<<temp
  144.         (ll+2).times{|j|# Then build walls
  145.             (ww+2).times{|k|
  146.                 @mapArr[(ypos-1)+j][(xpos-1)+k]=2
  147.             }
  148.         }
  149.         ll.times{|j|# Then build floor
  150.             ww.times{|k|
  151.                 @mapArr[ypos+j][xpos+k]=0
  152.             }
  153.         }
  154.         return 1
  155.     end
  156.    
  157.     # Pick random wall and random point along that wall
  158.     #
  159.     def make_exit(rn)
  160.         room=@room_list[rn]
  161.         rx,ry,rx2,ry2,rw=0,0,0,0,0
  162.         loop do
  163.             rw=rand(3)
  164.             case rw
  165.             when 0 # North wall
  166.                 rx=rand(room[1])+room[2]
  167.                 ry=room[3]-1
  168.                 rx2=rx
  169.                 ry2=ry-1
  170.             when 1 # East wall
  171.                 ry=rand(room[0])+room[3]
  172.                 rx=room[2]+room[1]
  173.                 rx2=rx+1
  174.                 ry2=ry
  175.             when 2 # South wall
  176.                 rx=rand(room[1])+room[2]
  177.                 ry=room[3]+room[0]
  178.                 rx2=rx
  179.                 ry2=ry+1
  180.             when 3 # West wall
  181.                 ry=rand(room[0])+room[3]
  182.                 rx=room[2]-1
  183.                 rx2=rx-1
  184.                 ry2=ry
  185.             end
  186.             break if @mapArr[ry][rx]==2 # If space is a wall, exit
  187.         end
  188.         return rx,ry,rx2,ry2,rw
  189.     end
  190.    
  191.     # Create doors in walls
  192.     #
  193.     def make_portal(px,py)
  194.         ptype=rand(100)
  195.         if ptype>90 # Secret door
  196.             @mapArr[py][px]=5
  197.         elsif ptype>75 # Closed door
  198.             @mapArr[py][px]=4
  199.         elsif ptype>40 # Open door
  200.             @mapArr[py][px]=3
  201.         else # Hole in the wall door
  202.             @mapArr[py][px]=0
  203.         end
  204.     end
  205.    
  206.     # Check corridor endpoint and make an exit if it links to another room
  207.     #
  208.     def join_corridor(cno,xp,yp,ed,psb)
  209.         cArea=@room_list[cno]
  210.         if xp!=cArea[2] or yp!=cArea[3] # Find the corridor endpoint
  211.             endx=xp-(cArea[1]-1)
  212.             endy=yp-(cArea[0]-1)
  213.         else
  214.             endx=xp+(cArea[1]-1)
  215.             endy=xp+(cArea[0]-1)
  216.         end
  217.         check_exit=[]
  218.         case ed
  219.         when 0 # North corridor
  220.             if endx>1
  221.                 coords=[endx-2,endy,endx-1,endy]
  222.                 check_exit<<coords
  223.             end
  224.             if endy>1
  225.                 coords=[endx,endy-2,endx,endy-1]
  226.                 check_exit<<coords
  227.             end
  228.             if endx<@xsize-2
  229.                 coords=[endx+2,endy,endx+1,endy]
  230.                 check_exit<<coords
  231.             end
  232.         when 1 # East corridor
  233.             if endy>1
  234.                 coords=[endx,endy-2,endx,endy-1]
  235.                 check_exit<<coords
  236.             end
  237.             if endx<@xsize-2
  238.                 coords=[endx+2,endy,endx+1,endy]
  239.                 check_exit<<coords
  240.             end
  241.             if endy<@ysize-2
  242.                 coords=[endx,endy+2,endx,endy+1]
  243.                 check_exit<<coords
  244.             end
  245.         when 2 # South corridor
  246.             if endx<@xsize-2
  247.                 coords=[endx+2,endy,endx+1,endy]
  248.                 check_exit<<coords
  249.             end
  250.             if endy<@ysize-2
  251.                 coords=[endx,endy+2,endx,endy+1]
  252.                 check_exit<<coords
  253.             end
  254.             if endx>1
  255.                 coords=[endx-2,endy,endx-1,endy]
  256.                 check_exit<<coords
  257.             end
  258.         when 3 # West corridor
  259.             if endx>1
  260.                 coords=[endx-2,endy,endx-1,endy]
  261.                 check_exit<<coords
  262.             end
  263.             if endy>1
  264.                 coords=[endx,endy-2,endx,endy-1]
  265.                 check_exit<<coords
  266.             end
  267.             if endy<@ysize-2
  268.                 coords=[endx,endy+2,endx,endy+1]
  269.                 check_exit<<coords
  270.             end
  271.         end
  272.         for xxx,yyy,xxx1,yyy1 in check_exit # Loop through possible exits
  273.             if @mapArr[yyy][xxx]==0 # If joins to a room
  274.                 if rand(100)<psb # Possibility of linking rooms
  275.                     make_portal(xxx1,yyy1)
  276.                 end
  277.             end
  278.         end
  279.     end
  280.    
  281.     # Final stage, loop through all the corridors to see if any can be joined to other rooms
  282.     #
  283.     def final_joins
  284.         @cor_list.each{|x|
  285.             join_corridor(x[0],x[1],x[2],x[3],10)
  286.         }
  287.     end
  288. end
  289.  
  290. # TEST ZONE
  291. begin
  292.     MAPWIDTH=40
  293.     MAPHEIGHT=25
  294.     FAILS=110
  295.     B1=20
  296.     MAPROOMS=20
  297.     dung=DungeonMap.new
  298.     map=dung.make_map(MAPWIDTH,MAPHEIGHT,FAILS,B1,MAPROOMS)
  299.     tilemap=[]
  300.     MAPHEIGHT.times{
  301.         tilemap<<Array.new(MAPWIDTH,0)
  302.     }
  303.     MAPHEIGHT.times{|y|
  304.         MAPWIDTH.times{|x|
  305.             case map[y][x]
  306.             when 0
  307.                 tilemap[y][x]=\'.\'
  308.             when 1
  309.                 tilemap[y][x]=\' \'
  310.             when 2
  311.                 tilemap[y][x]=\'#\'
  312.             when 3,4,5
  313.                 tilemap[y][x]=\'=\'
  314.             end
  315.         }
  316.     }
  317.     MAPHEIGHT.times{|y|
  318.         puts tilemap[y].to_s
  319.     }
  320. end
');