module DungeonGenerator
Public Instance Methods
generate( dungeon_size, party_levels, encounters_difficulty: :medium, rooms_removal_coef: 0.3, lair: nil, output: false )
click to toggle source
# File lib/dungeon/dungeon_generator.rb, line 5 def generate( dungeon_size, party_levels, encounters_difficulty: :medium, rooms_removal_coef: 0.3, lair: nil, output: false ) check_params( dungeon_size, party_levels, encounters_difficulty, rooms_removal_coef ) @dungeon_size = dungeon_size @rooms_removal_coef = rooms_removal_coef @rooms = {} @hallways = HallwaysList.new @dungeon_generated = false @current_room = nil @lair = lair ? lair : Lairs.new( encounters_difficulty, party_levels ) @output = output create_dungeon create_entry connect_hallways delete_rooms generate_treasure @dungeon_generated = true end
Private Instance Methods
assert_dungeon_generated()
click to toggle source
# File lib/dungeon/dungeon_generator.rb, line 27 def assert_dungeon_generated raise "Dungeon hasn't been generated" unless @dungeon_generated end
connect_hallways()
click to toggle source
# File lib/dungeon/dungeon_generator.rb, line 59 def connect_hallways Matrix.build( @dungeon_size ){ |r, c| [ r+1, c+1 ] }.to_a.flatten(1).each do |top, left| @hallways.connect_rooms( @rooms[ [ top, left ] ],@rooms[ [ top, left+1 ] ], HorizontalHallway.new ) unless left == @dungeon_size @hallways.connect_rooms( @rooms[ [ top, left ] ],@rooms[ [ top+1, left ] ], VerticalHallway.new ) unless top == @dungeon_size end end
create_dungeon()
click to toggle source
# File lib/dungeon/dungeon_generator.rb, line 52 def create_dungeon Matrix.build( @dungeon_size ){ |r, c| [ r+1, c+1 ] }.to_a.flatten(1).each do |top, left| @rooms[ [ top, left ] ] = Room.new( top, left, @lair ) @rooms[ [ top, left ] ].id = [ top, left ] end end
create_entry()
click to toggle source
# File lib/dungeon/dungeon_generator.rb, line 42 def create_entry @entry = random_entry_room @entry.set_entry_room @current_room = @entry end
delete_rooms()
click to toggle source
Coef must be a number between 0 -> 1 for example 1/3 mean that we will delete 1/3 of the rooms
# File lib/dungeon/dungeon_generator.rb, line 68 def delete_rooms to_delete_rooms_keys = @rooms.keys.shuffle puts "Current dungeon size = #{@rooms.count}" if @output target_dungeon_size = @rooms.count - ((@dungeon_size**2)*@rooms_removal_coef).ceil puts "Target dungeon size = #{target_dungeon_size}" if @output while @rooms.count > target_dungeon_size && !to_delete_rooms_keys.empty? to_delete_room_key = to_delete_rooms_keys.shift tmp_rooms = @rooms.clone tmp_rooms.delete( to_delete_room_key ) dw = DungeonWalker.new( tmp_rooms, @dungeon_size, @entry ) # If we can walk to all the rooms in the dungeon, then the room deletion is validated if dw.walk_rooms.count == tmp_rooms.count @hallways.disable_hallways!( to_delete_room_key ) @rooms.delete( to_delete_room_key ) end # Otherwise we try with the next room end puts "Final dungeon size = #{@rooms.count}" if @output end
distance_between_rooms_ids( r_id_1, r_id_2 )
click to toggle source
# File lib/dungeon/dungeon_generator.rb, line 48 def distance_between_rooms_ids( r_id_1, r_id_2 ) Math.sqrt( (r_id_1[0] - r_id_2[0])**2 + (r_id_1[1] - r_id_2[1])**2 ).ceil end
external_rooms()
click to toggle source
# File lib/dungeon/dungeon_generator.rb, line 94 def external_rooms @rooms.values.select{ |r| r.top == 1 || r.left == 1 || r.top == @dungeon_size || r.left == @dungeon_size } end
generate_treasure()
click to toggle source
# File lib/dungeon/dungeon_generator.rb, line 31 def generate_treasure rooms_distances = { } @rooms.keys.each do |room_id| rooms_distances[ room_id ] = distance_between_rooms_ids(@entry.id, room_id ) end max_distance = rooms_distances.values.max rooms_distances.delete_if {|_, value| value != max_distance } treasure_room_id = rooms_distances.keys.sample @rooms[treasure_room_id].set_treasure_room end
random_entry_room()
click to toggle source
# File lib/dungeon/dungeon_generator.rb, line 98 def random_entry_room external_rooms.sample end