added reference ruby room generation script

master
Zac 3 years ago
parent 7a159e6f88
commit 33508afea0
  1. 217
      scripts/room_gen.rb

@ -0,0 +1,217 @@
WIDTH = 8
HEIGHT = 8
ROOM_GEN_PERCENTAGE = 0.87
GEN_TIMES = 4
MIN_WALK_LENGTH = (HEIGHT * WIDTH) / 4
$rooms = []
$marked = []
class Room
attr_reader :exits, :items,
:objects, :coords
def initialize x, y
@exits = []
@items = []
@objects = []
@coords = [x, y]
end
def set_exits exits
@exits = exits
end
def to_s
'X'
end
end
def print_rooms
row = 0
HEIGHT.times do |y|
WIDTH.times do |x|
if $rooms[x][row]
print $rooms[x][row]
else
print ' '
end
end
row += 1
print "\n"
end
end
def walk room, from = nil
$marked.clear if from.nil?
unless room.nil?
count = from.nil? ? 0 : 1
x, y = room.coords
rooms = []
room.exits.each do |e|
rooms << {room: $rooms[x-1][y], dir: 'w'} if e == 'w' and from != 'e'
rooms << {room: $rooms[x+1][y], dir: 'e'} if e == 'e' and from != 'w'
rooms << {room: $rooms[x][y-1], dir: 'n'} if e == 'n' and from != 's'
rooms << {room: $rooms[x][y+1], dir: 's'} if e == 's' and from != 'n'
end
rooms.each do |r|
unless $marked.include? r[:room].coords
$marked << r[:room].coords
count += walk(r[:room], r[:dir])
end
end
count
else
0
end
end
def surrounding_room_count x, y
count = 0
count += 1 if x - 1 >= 0 and $rooms[x-1][y]
count += 1 if y - 1 >= 0 and $rooms[x][y-1]
count += 1 if x + 1 < WIDTH and $rooms[x+1][y]
count += 1 if y + 1 < HEIGHT and $rooms[x][y+1]
return count
end
def needs_bridge x, y
begin
horiz = x-1 >= 0 and x+1 < WIDTH and
(!$rooms[x-1][y].nil? and !$rooms[x+1][y].nil?) and
(walk($rooms[x-1][y]) > MIN_WALK_LENGTH and
walk($rooms[x+1][y]) > MIN_WALK_LENGTH)
vert = y-1 >= 0 and y+1 < HEIGHT and
(!$rooms[x][y-1].nil? and !$rooms[x][y+1].nil?) and
(walk($rooms[x][y-1]) > MIN_WALK_LENGTH and
walk($rooms[x][y+1]) > MIN_WALK_LENGTH)
horiz || vert
rescue
true
end
end
def first_pass
WIDTH.times do |x|
HEIGHT.times do |y|
perc = rand
perc += (0.05 * surrounding_room_count(x, y))
if perc > ROOM_GEN_PERCENTAGE and
$rooms[x][y].nil?
$rooms[x][y] = Room.new x, y
end
end
end
end
def populate_room_data
WIDTH.times do |x|
HEIGHT.times do |y|
if $rooms[x][y]
exits = []
exits << 'w' if x - 1 >= 0 and $rooms[x-1][y]
exits << 'n' if y - 1 >= 0 and $rooms[x][y-1]
exits << 'e' if x + 1 < WIDTH and $rooms[x+1][y]
exits << 's' if y + 1 < HEIGHT and $rooms[x][y+1]
$rooms[x][y].set_exits exits
end
end
end
end
def second_pass
WIDTH.times do |x|
HEIGHT.times do |y|
$marked.clear
if not $rooms[x][y].nil? and
($rooms[x][y].exits.empty? or
($rooms[x][y].exits.length < 2 and
walk($rooms[x][y]) < MIN_WALK_LENGTH))
$rooms[x][y] = nil
end
#$rooms[x][y] = Room.new(x,y) if $rooms[x][y].nil? and needs_bridge(x,y)
#
populate_room_data
end
end
end
def third_pass
WIDTH.times do |x|
HEIGHT.times do |y|
$rooms[x][y] = nil if !$rooms[x][y].nil? and $rooms[x][y].exits.empty?
end
end
end
def init_rooms
WIDTH.times do |x|
$rooms << []
HEIGHT.times do
$rooms[x] << nil
end
end
end
def get_valid_room
checked = []
loop do
x = rand(WIDTH)
y = rand(HEIGHT)
next if checked.include? [x,y]
checked << [x,y]
return $rooms[x][y] unless $rooms[x][y].nil?
end
end
def room_count
count = 0
WIDTH.times do |x|
HEIGHT.times do |y|
count += 1 unless $rooms[x][y].nil?
end
end
count
end
def gen_valid_layout
loop do
init_rooms
GEN_TIMES.times do
first_pass
# second_pass
end
populate_room_data
(GEN_TIMES + 1).times do
second_pass
end
third_pass
populate_room_data
start = get_valid_room
wcount = walk(start)
break if wcount >= room_count - 1 and
wcount <= room_count + 1 and
room_count > (HEIGHT * WIDTH) / 3
end
end
gen_valid_layout
print_rooms
puts room_count
Loading…
Cancel
Save