RRGGLIB

From RogueBasin
Revision as of 05:15, 22 August 2012 by Deej (talk | contribs) (replaced nonexistant Ruby category link with one to actual Ruby page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Introduction

This library is a set of tools to make easily a Rouguelike game in Ruby.

Usage

It will make a data called Table wich is a two dimensional array with the data of each kind of dungeon. I suggest you should read each kind of dungeon to make sure you are trying to make the one you want.

These are the kind of dungeons:

		#==============================================================================================================
		# ** RGG::Dungeons::grid_based(width, height[,wall_height, cell_width, cell_height])
		#--------------------------------------------------------------------------------------------------------------
		# * Creates a dungeon based on grids
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- width       : The width  (in tiles) for the dungeon
		#	- height      : The height (in tiles) for the dungeon
		#	- wall_height : The wall height (in tiles) of the dungeon, set as 0, if you dont want any.
		#	                (default = DEFAUL_WALL_HEIGHT)
		#	- cell_width  : The width  of each cell (default 9)
		#	- cell_height : the height of each cell (default 9)
		# * Returns:
		# 	- A Table Object(see Table) with sizes width x height containing the generated dungeon.
		#--------------------------------------------------------------------------------------------------------------
		# * Generator Notes:
		# 	Advantages:
		# 		- This system is easy to use, and easy to maintain, since it can create big rooms easier than
		#		  other methods.
		# 		- This system ensures the connections of all rooms.
		#	Disadvantages:
		#		- Maps doesn't have to be completelly filled.
		#		- Not too realisitc for cave layouts.
		#		- Cells are predecible because they are the same size.
		#==============================================================================================================
		#==============================================================================================================
		# ** RGG::Dungeons::maze(width, height[,wall_height])
		#--------------------------------------------------------------------------------------------------------------
		# * Creates a perfect maze, trying to take all the possible space.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- width       : The width  (in tiles) for the dungeon
		#	- height      : The height (in tiles) for the dungeon
		#	- wall_height : The wall height (in tiles) of the dungeon, set as 0, if you dont want any.
		#	                (default = DEFAUL_WALL_HEIGHT)
		# * Returns:
		# 	- A Table Object(see Table) with sizes width x height containing the generated dungeon.
		#--------------------------------------------------------------------------------------------------------------
		# * Generator Notes:
		# 	Advantages:
		# 		- This system ensures that every space is rechable.
		#	Disadvantages:
		#		- Small size to put enemies, obejects, chests.
		#		- Boring arquitecture.
		#		- Quite slow.
		#==============================================================================================================	
		#==============================================================================================================
		# ** RGG::Dungeons::bsp(width, height[,wall_height last_mov])
		#--------------------------------------------------------------------------------------------------------------
		# * Creates a Maze with the BSP method.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- width       : The width  (in tiles) for the dungeon
		#	- height      : The height (in tiles) for the dungeon
		#	- wall_height : The wall height (in tiles) of the dungeon, set as 0, if you dont want any.
		#	                (default = DEFAULT_WALL_HEIGHT)
		#	- last_mov    : The starting maze direction (random by default, 0 = horizontal, else vertical)
		# * Returns:
		# 	- A Table Object(see Table) with sizes width x height containing the generated dungeon.
		#--------------------------------------------------------------------------------------------------------------
		# * Generator Notes:
		# 	Advantages:
		# 		- This system ensures that every space is rechable.
		#		- Easy maintained rooms.
		#		- Better method than a normal cell based.
		#	Disadvantages:
		#		- This method would make easier dungeons than other ones.
		#==============================================================================================================	
		#==============================================================================================================
		# ** RGG::Dungeons::cellular_automata(width, height[,wall_height last_mov])
		#--------------------------------------------------------------------------------------------------------------
		# * Creates a Dungeon with the BSP method.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- width       : The width  (in tiles) for the dungeon
		#	- height      : The height (in tiles) for the dungeon
		#	- wall_height : The wall height (in tiles) of the dungeon, set as 0, if you dont want any.
		#	                (default = DEFAULT_WALL_HEIGHT)
		# * Returns:
		# 	- A Table Object(see Table) with sizes width x height containing the generated dungeon.
		#--------------------------------------------------------------------------------------------------------------
		# * Generator Notes:
		# 	Advantages:
		# 		- This system ensures that every space is rechable.
		#		- Ganarates a great irregular effect. (Specially good for caves)
		#	Disadvantages:
		#		- This method would make easier dungeons than other ones.
		#		- Extremly slow method.
		#		- May create "Big areas" filled with nothing.
		#==============================================================================================================	
		#==============================================================================================================
		# ** RGG::Dungeons::mirrored(dungeon[, mode])
		#--------------------------------------------------------------------------------------------------------------
		# * Creates a Dungeon using a mirror method.
		#   The width and height of the newly created dungeon is automatically recognized.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- dungeon     : The dungeon data to mirror
		#	- mode        : The mirror mode (default is X and Y)
    #	- wall_height : The height of the wall. (default = DEFAULT_WALL_HEIGHT)
		# * Returns:
		# 	- A Table Object(see Table) with sizes width x height containing the generated dungeon.
		#--------------------------------------------------------------------------------------------------------------
		# * Generator Notes:
		# 	Advantages:
		# 		- Great effect for some places.
		#	Disadvantages:
		#		- Needs previous data to work, so it is just
		#==============================================================================================================	

Code

#======================================================================================================================
# ** RANDOM GAME GENERATOR (RGG)
#----------------------------------------------------------------------------------------------------------------------
# * Library for Rouguelike Generation in Ruby.
#----------------------------------------------------------------------------------------------------------------------
# * Author: Ramiro Rojo.
# * Version 1.0
#----------------------------------------------------------------------------------------------------------------------
# * Licence (Free BSD Licence): 
#	Copyright 2011 Ramiro Rojo. All rights reserved.
#
#	Redistribution and use in source and binary forms, with or without modification, are
#	permitted provided that the following conditions are met:
#
#   	1. Redistributions of source code must retain the above copyright notice, this list of
#      	   conditions and the following disclaimer.
#
#   	2. Redistributions in binary form must reproduce the above copyright notice, this list
#      	   of conditions and the following disclaimer in the documentation and/or other materials
#      	   provided with the distribution.
#
#	THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY EXPRESS OR IMPLIED
#	WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
#	FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
#	CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
#	SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
#	ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
#	NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#	ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#	The views and conclusions contained in the software and documentation are those of the
#	authors and should not be interpreted as representing official policies, either expressed
#	or implied, of Ramiro Rojo.
#----------------------------------------------------------------------------------------------------------------------
# * Thanks:
#	- Jim Babcock for the Cellular Automata code and tehory.
#	- Rougue Basin (http://roguebasin.roguelikedevelopment.org) for the BSP Generation, and normal rouguelike information.
#	- Emanuele Feronato(http://www.emanueleferonato.com) for the perfect maze generator. 
#	- Alejandro Marzini (aka vgvgf) for the Table and Color classes.
#======================================================================================================================

#======================================================================================================================
# ** Table Class
#----------------------------------------------------------------------------------------------------------------------
# * A class for two or three dimensional arrays.
#======================================================================================================================
class Table
	#------------------------------------------------------------------------------------------------------------------
	# * Public Instance Variables
	#------------------------------------------------------------------------------------------------------------------
	attr_reader :xsize # the x dimension of the table.
	attr_reader :ysize # the y dimension of the table.
	attr_reader :zsize # the z imension of the table.

	def initialize(x, y = 1, z = 1)
		@xsize, @ysize, @zsize = x, y, z
		@data = Array.new(x * y * z, 0)
	end
	def [](x, y = 0, z = 0)
		@data[x + y * @xsize + z * @xsize * @ysize]
	end
	def []=(*args)
		x = args[0]
		y = args.size > 2 ? args[1] :0
		z = args.size > 3 ? args[2] :0
		v = args.pop
		@data[x + y * @xsize + z * @xsize * @ysize] = v
	end
	def _dump(d = 0)
		s = [3].pack('L')
		s += [@xsize].pack('L') + [@ysize].pack('L') + [@zsize].pack('L')
		s += [@xsize * @ysize * @zsize].pack('L')
		for z in 0...@zsize
			for y in 0...@ysize
			for x in 0...@xsize
				s += [@data[x + y * @xsize + z * @xsize * @ysize]].pack('S')
			end
			end
		end
		s
	end
	def self._load(s)
		size = s[0, 4].unpack('L')[0]
		nx = s[4, 4].unpack('L')[0]
		ny = s[8, 4].unpack('L')[0]
		nz = s[12, 4].unpack('L')[0]
		data = []
		pointer = 20
		loop do
			data.push(*s[pointer, 2].unpack('S'))
			pointer += 2
			break if pointer > s.size - 1
		end
		t = Table.new(nx, ny, nz)
		n = 0
		for z in 0...nz
			for y in 0...ny
				for x in 0...nx
					t[x, y, z] = data[n]
					n += 1
				end
			end
		end
		t
	end
	
end

#======================================================================================================================
# ** Color Class
#----------------------------------------------------------------------------------------------------------------------
# * The class containing color data in RGBA format.
#======================================================================================================================

class Color
	#------------------------------------------------------------------------------------------------------------------
	# * Public Instance Variables
	#------------------------------------------------------------------------------------------------------------------
	attr_reader	 :red   # the red component.
	attr_reader	 :green # the green component.
	attr_reader	 :blue  # the blue component.
	attr_reader	 :alpha # the alpha (transparency) component.

	#==================================================================================================================
	# * Color#initialize(r, g, b[, a])
	#------------------------------------------------------------------------------------------------------------------
	# * Instantiates a new color
	#------------------------------------------------------------------------------------------------------------------
	# * Parameters:
	#	- r : The red component of the color
	#	- g : The green component of the color
	#	- b : The blue component of the color
	#	- a : the alpha component of the color (default = 255)
	#==================================================================================================================
	def initialize(r, g, b, a = 255.0)
		self.red = r.to_f
		self.green = g.to_f
		self.blue = b.to_f
		self.alpha = a.to_f
	end
	
	#==================================================================================================================
	# * Color#set(r, g, b[, a])
	#------------------------------------------------------------------------------------------------------------------
	# * Sets all the data of the color directly
	#------------------------------------------------------------------------------------------------------------------
	# * Parameters:
	#	- r : The red component of the color
	#	- g : The green component of the color
	#	- b : The blue component of the color
	#	- a : the alpha component of the color ( default = 255)
	#==================================================================================================================
	
	def set(r, g, b, a = 255.0)
		self.red = r.to_f
		self.green = g.to_f
		self.blue = b.to_f
		self.alpha = a.to_f
	end
	
	#==================================================================================================================
	# * Color#red =(val)
	#------------------------------------------------------------------------------------------------------------------
	# * Sets the red component of the color
	#------------------------------------------------------------------------------------------------------------------
	# * Parameters:
	#	- val : The red component of the color
	#==================================================================================================================
	def red=(val)
		@red    = [[val.to_f, 0.0].max, 255.0].min
	end
	
	#==================================================================================================================
	# * Color#green =(val)
	#------------------------------------------------------------------------------------------------------------------
	# * Sets the green component of the color
	#------------------------------------------------------------------------------------------------------------------
	# * Parameters:
	#	- val : The green component of the color
	#==================================================================================================================	
	def green=(val)
		@green = [[val.to_f, 0.0].max, 255.0].min
	end
	
	#==================================================================================================================
	# * Color#blue =(val)
	#------------------------------------------------------------------------------------------------------------------
	# * Sets the blue component of the color
	#------------------------------------------------------------------------------------------------------------------
	# * Parameters:
	#	- val : The blue component of the color
	#==================================================================================================================	
	def blue=(val)
		@blue   = [[val.to_f, 0.0].max, 255.0].min
	end
	
	#==================================================================================================================
	# * Color#alpha =(val)
	#------------------------------------------------------------------------------------------------------------------
	# * Sets the alpha component of the color
	#------------------------------------------------------------------------------------------------------------------
	# * Parameters:
	#	- val : The alpha component of the color
	#==================================================================================================================	
	def alpha=(val)
		@alpha = [[val.to_f, 0.0].max, 255.0].min
	end
	#==================================================================================================================
	# * Color#color
	#------------------------------------------------------------------------------------------------------------------
	# * Creates a duplication of the current color
	#------------------------------------------------------------------------------------------------------------------
	# * Parameters:
	#	- none.
	#==================================================================================================================	
	def color
		Color.new(@red, @green, @blue, @alpha)
	end
	#==================================================================================================================
	# * Color::_dump
	#------------------------------------------------------------------------------------------------------------------
	# * Stores the color in a binary file
	#------------------------------------------------------------------------------------------------------------------
	# * Parameters:
	#	- none
	#==================================================================================================================		
	def _dump(d = 0)
		[@red, @green, @blue, @alpha].pack('d4')
	end
	
	#==================================================================================================================
	# * Color::_load
	#------------------------------------------------------------------------------------------------------------------
	# * Loads a color from a binary file
	#------------------------------------------------------------------------------------------------------------------
	# * Parameters:
	#	- none.
	#==================================================================================================================		
	def self._load(s)
		Color.new(*s.unpack('d4'))
	end
	
	#==================================================================================================================
	# * Color#==(other)
	#------------------------------------------------------------------------------------------------------------------
	# * Cheks if the color is the same as other.
	#------------------------------------------------------------------------------------------------------------------
	# * Parameters:
	#	- other: other Color to compare.
	#==================================================================================================================	
	def ==(other)
		(@red == other.red && @green == other.green && @blue == other.blue && @alpha == other.alpha)
	end
	
	#==================================================================================================================
	# * Color#===(other)
	#------------------------------------------------------------------------------------------------------------------
	# * Cheks if the color is the same as other.
	#------------------------------------------------------------------------------------------------------------------
	# * Parameters:
	#	- other: other Color to compare.
	#==================================================================================================================		
	def ===(other)
		(@red == other.red && @green == other.green && @blue == other.blue && @alpha == other.alpha)
	end
	
end

class Point
  
    attr_accessor :x
    attr_accessor :y
  
	MANHATTAN = 0
	HYPOT     = 1
  
    def initialize(x, y)
		@x = x
		@y = y
    end
  
    def effort(x, y, mode = MANHATTAN)
		case mode
		when MANHATTAN; return ((@x - x) + (@y - y)).abs
		when HYPOT;     return Math.hypot((@x - x), (@y - y))
		else;           return ((@x - x) + (@y - y)).abs
		end  
    end
    
    def ==(other)
		other.is_a?(Point) ? (self.x == other.x && self.y == other.y) : false
    end

    def ===(other)
		other.is_a?(Point) ? (self.x == other.x && self.y == other.y) : false
    end    
    
end

#======================================================================================================================
# ** RGG Module (Random Game Generator Module)
#----------------------------------------------------------------------------------------------------------------------
# * The module to control all the ganaration of the library.
#======================================================================================================================
module RGG
	#==================================================================================================================
	# ** RGG::Dungeons Module
	#------------------------------------------------------------------------------------------------------------------
	# * The sub module that controls the dungeon generation.
	#==================================================================================================================
	module Dungeons
	
		#--------------------------------------------------------------------------------------------------------------
		# * Module Constants
		#--------------------------------------------------------------------------------------------------------------
		# the tile id for the "floor of the dungeon"
		FLOOR    = 0
		# the tile id for the wall of the dungeon
		WALL     = 1
		# the tile id for roofs of the dungeons
		ROOF     = 2
		# mirror x and y axis
		BOTH_MIRROR = 1
		# mirror x axis
		X_MIRROR    = 2
		# mirror y axis
		Y_MIRROR    = 3
  
		# The default size of the floors of a dungeon
		DEFAULT_WALL_HEIGHT = 1
    
		# Color codes used for tiled data (for testing orpouses )
		COLORS = {
			ROOF      => Color.new(255, 255, 255),
			WALL      => Color.new(180, 180, 180),
			FLOOR     => Color.new(60, 60, 60),
		}	
		#==============================================================================================================
		# ** RGG::Dungeons::grid_based(width, height[,wall_height, cell_width, cell_height])
		#--------------------------------------------------------------------------------------------------------------
		# * Creates a dungeon based on grids
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- width       : The width  (in tiles) for the dungeon
		#	- height      : The height (in tiles) for the dungeon
		#	- wall_height : The wall height (in tiles) of the dungeon, set as 0, if you dont want any.
		#	                (default = DEFAUL_WALL_HEIGHT)
		#	- cell_width  : The width  of each cell (default 9)
		#	- cell_height : the height of each cell (default 9)
		# * Returns:
		# 	- A Table Object(see Table) with sizes width x height containing the generated dungeon.
		#--------------------------------------------------------------------------------------------------------------
		# * Generator Notes:
		# 	Advantages:
		# 		- This system is easy to use, and easy to maintain, since it can create big rooms easier than
		#		  other methods.
		# 		- This system ensures the connections of all rooms.
		#	Disadvantages:
		#		- Maps doesn't have to be completelly filled.
		#		- Not too realisitc for cave layouts.
		#		- Cells are predecible because they are the same size.
		#==============================================================================================================
		def self.grid_based(width, height,wall_height = DEFAULT_WALL_HEIGHT, cell_width=9, cell_height=9)
			# sets up the data
			data = Table.new(width, height)
			for x in 0...width
				for y in 0...height
					data[x, y] = ROOF 
				end
			end
			# define the numbers of horizontal  and vertical rooms
			h           = data.xsize  / cell_width
			v           = data.ysize / cell_height
			# define an arbitary number of total rooms
			total_rooms = [h * v / 2, rand(h * v) + 1].max
			rooms = 0
			# sets the current room as the midde one.
			current_room = Point.new(h / 2, v / 2)
			first_room = Point.new(current_room.x, current_room.y)
			connections = Table.new(h, v)
			# sets up the connections
			for i in 0...h
				for j in 0...v
					connections[i, j] = 0
				end
			end

			now_x = h / 2
			now_y = v / 2
      
			connections[now_x, now_y] = 1
      
			for x in (now_x * cell_width + 1)...((now_x + 1) * cell_width - 1)
				for y in (now_y * cell_height + 1 + wall_height)...((now_y + 1) * cell_height - 1)
					data[x, y] = FLOOR
				end
			end
      
			last_x = now_x
			last_y = now_y
			can_create_room = true
			next_pos = []
      
			gone_room_count = 4
      
			while can_create_room
				d = []
				d.push("N") if now_y > 0       && connections[now_x, now_y-1] == 0
				d.push("S") if now_y < (v - 1) && connections[now_x, now_y+1] == 0
				d.push("W") if now_x > 0       && connections[now_x-1, now_y] == 0
				d.push("E") if now_x < (h - 1) && connections[now_x+1, now_y] == 0
        
				if d.size == 0
					can_create_room = false
				else
					c1 = [now_x * cell_width + cell_width / 2, now_y * cell_height + (cell_height - 1 - wall_height) / 2 + wall_height ]
					t =  d.size - 1 + rand(2)
					(t).times do |i|
						case d[rand(d.size)]
						when "N"
							temp_y = now_y - 1
							temp_x = now_x
							d.delete("N")
						when "S"
							temp_y = now_y + 1
							temp_x = now_x
							d.delete("S")
							when "E"
							temp_x = now_x + 1
							temp_y = now_y
							d.delete("E")
						when "W"
							temp_x = now_x - 1
							temp_y = now_y
							d.delete("W")
						end  
						connections[temp_x, temp_y] = 1
						c2 = [temp_x * cell_width + cell_width / 2, temp_y * cell_height + (cell_height - 1 - wall_height) / 2 + wall_height ]
          
						if rand(gone_room_count) != 0
							for x in (temp_x * cell_width + 1)...((temp_x + 1) * 9 - 1)
								for y in (temp_y * cell_height + 1 + wall_height)...((temp_y + 1) * cell_height - 1)
									data[x, y] = FLOOR
								end
							end
							gone_room_count -= 1
						else
							gone_room_count += 1
						end
						next_pos.push(Point.new(temp_x, temp_y))
						x1  = [c1[0], c2[0]].min
						x2  = [c1[0], c2[0]].max
						y1  = [c1[1], c2[1]].min
						y2  = [c1[1], c2[1]].max
						for x in x1..x2
							for y in y1..y2
								data[x, y] = FLOOR
							end
						end
					end
          
					point = next_pos[rand(next_pos.size)]
					next_pos.delete(point)
					now_x = point.x
					now_y = point.y
				end  
			end			
			# returns the current data created
			return generate_walls(data, wall_height)
		end
	
		#==============================================================================================================
		# ** RGG::Dungeons::maze(width, height[,wall_height])
		#--------------------------------------------------------------------------------------------------------------
		# * Creates a perfect maze, trying to take all the possible space.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- width       : The width  (in tiles) for the dungeon
		#	- height      : The height (in tiles) for the dungeon
		#	- wall_height : The wall height (in tiles) of the dungeon, set as 0, if you dont want any.
		#	                (default = DEFAUL_WALL_HEIGHT)
		# * Returns:
		# 	- A Table Object(see Table) with sizes width x height containing the generated dungeon.
		#--------------------------------------------------------------------------------------------------------------
		# * Generator Notes:
		# 	Advantages:
		# 		- This system ensures that every space is rechable.
		#	Disadvantages:
		#		- Small size to put enemies, obejects, chests.
		#		- Boring arquitecture.
		#		- Quite slow.
		#==============================================================================================================	
		def self.maze(width, height,wall_height = DEFAULT_WALL_HEIGHT)
			# sets up the data
			data = Table.new(width, height)
			for x in 0...width
				for y in 0...height
					data[x, y] = ROOF 
				end
			end		
			sparcing = (wall_height+2)
			for x in 0...width
				for y in 0...height
					data[x, y] = ROOF 
				end
			end
			moves = []
			moves.push(Point.new(rand(width - 1) + 1,rand(height - 1) + 1))
			last_dir = nil
			while moves.size > 0
				d = []
				case rand(5)
				when 0; moves.sort! {|a, b| a.x<=>b.y}
				when 1; moves.sort! {|a, b| a.y<=>b.x}
				when 2; moves.sort! {|a, b| b.x<=>a.y}
				when 3; moves.sort! {|a, b| b.y<=>a.x}
				end  
				move = moves.pop
				d.push("E") if data[move.x+sparcing, move.y] == ROOF && valid?(move.x+sparcing, move.y, data, wall_height)
				d.push("W") if data[move.x-sparcing, move.y] == ROOF && valid?(move.x-sparcing, move.y, data, wall_height)
				d.push("S") if data[move.x, move.y+sparcing] == ROOF && valid?(move.x, move.y+sparcing, data, wall_height)
				d.push("N") if data[move.x, move.y-sparcing] == ROOF && valid?(move.x, move.y-sparcing, data, wall_height)
				if d.size > 0
					case d[rand(d.size)]
					when "N"
						for i in 0..sparcing
							data[move.x, move.y-+i] = FLOOR if valid?(move.x, move.y-i, data, wall_height)
						end 
						moves.push(Point.new(move.x, move.y-sparcing))
					when "S"
						for i in 0..sparcing
							data[move.x, move.y+i] = FLOOR  if valid?(move.x, move.y+i, data, wall_height)
						end  
						moves.push(Point.new(move.x, move.y+sparcing))            
					when "E"
						for i in 0..sparcing
							data[move.x+i, move.y] = FLOOR  if valid?(move.x+i, move.y, data, wall_height)
						end    
						moves.push(Point.new(move.x+sparcing, move.y)) 
					when "W"
						for i in 0..sparcing
							data[move.x-i, move.y] = FLOOR  if valid?(move.x-i, move.y, data, wall_height)
						end  
						moves.push(Point.new(move.x-sparcing, move.y))             
					end  
				end	
				moves.push(move) if (d.size > 1 && !moves.include?(move))
				moves.uniq!
			end
			return generate_walls(data, wall_height)
		end
		
		#==============================================================================================================
		# ** RGG::Dungeons::bsp(width, height[,wall_height last_mov])
		#--------------------------------------------------------------------------------------------------------------
		# * Creates a Maze with the BSP method.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- width       : The width  (in tiles) for the dungeon
		#	- height      : The height (in tiles) for the dungeon
		#	- wall_height : The wall height (in tiles) of the dungeon, set as 0, if you dont want any.
		#	                (default = DEFAULT_WALL_HEIGHT)
		#	- last_mov    : The starting maze direction (random by default, 0 = horizontal, else vertical)
		# * Returns:
		# 	- A Table Object(see Table) with sizes width x height containing the generated dungeon.
		#--------------------------------------------------------------------------------------------------------------
		# * Generator Notes:
		# 	Advantages:
		# 		- This system ensures that every space is rechable.
		#		- Easy maintained rooms.
		#		- Better method than a normal cell based.
		#	Disadvantages:
		#		- This method would make easier dungeons than other ones.
		#==============================================================================================================			
		
		def self.bsp(width, height,wall_height = DEFAULT_WALL_HEIGHT, last_mov = rand(2))
			return generate_walls(DungeonDivision.new(0,0, width, height, wall_height, last_mov).data, wall_height)	
		end
	
		#==============================================================================================================
		# ** RGG:: DungeonDivision class
		#--------------------------------------------------------------------------------------------------------------
		# * A class to help making a BSP dungeon.
		#==============================================================================================================
	
		class DungeonDivision
			#----------------------------------------------------------------------------------------------------------
			# * Public instance variables
			#----------------------------------------------------------------------------------------------------------
			attr_accessor :x          # the x coordinate of this division.
			attr_accessor :y          # the y coordinate of this division.
			attr_accessor :width      # the width of this division.
			attr_accessor :height     # the height of this division.
			attr_accessor :divisions  # the divisions of this division.
			attr_accessor :data       # the data of this division
      
			#==============================================================================================================
			# ** RGG:: DungeonDivision#initialize(x, y, width, height[,wall_height last_mov])
			#--------------------------------------------------------------------------------------------------------------
			# * Creates a Maze with the BSP method.
			#--------------------------------------------------------------------------------------------------------------
			# * Parameters:
			#	- x           : the x coordinate of the dungeon.
			#	- y           : the y coordinate of the dungeon.
			#	- width       : The width  (in tiles) for the dungeon
			#	- height      : The height (in tiles) for the dungeon
			#	- wall_height : The wall height (in tiles) of the dungeon, set as 0, if you dont want any.
			#	                (default = DEFAULT_WALL_HEIGHT)
			#	- last_mov    : The starting maze direction (random by default, 0 = horizontal, else vertical)
			#==============================================================================================================		  
			def initialize(x, y, width, height,wall_height = 1, last_mov = 0)
				@x = x
				@y = y
				@width = width
				@height = height
				@divisions = []
				@data = Table.new(width, height)
        
				for x in 0...width
					for y in 0...height
						@data[x, y] = ::RGG::Dungeons::ROOF
					end  
				end
        
				iterations = (width > 15) && (height > 14 + wall_height) ? 1 : 0
        
				if (iterations > 0)
					r = rand(3)
					r = 1 - last_mov if r > 1
					case rand(2)
					when 0
						w = width  * (rand(21) + 40) / 100
						@divisions.push(DungeonDivision.new(0, 0, w, height, wall_height, 0))
						w = width - w
						@divisions.push(DungeonDivision.new(w, 0, w, height, wall_height, 0))
            
						for x in 0...@divisions[0].width
							for y in 0...@divisions[0].height
								@data[x, y] = @divisions[0].data[x, y]
							end  
						end
            
						for x in 0...@divisions[1].width
							for y in 0...@divisions[1].height
								@data[x + @divisions[0].width, y] = @divisions[1].data[x, y]
							end  
						end            
            
						y = height / 2
						for x  in (@divisions[0].width / 2)..(@divisions[0].width + @divisions[1].width / 2)
							@data[x, y] = ::RGG::Dungeons::FLOOR
						end
            
					when 1
						h = height * (rand(21) + 40) / 100
						@divisions.push(DungeonDivision.new(0, 0, width, h, wall_height, 1))
						h = height - h
						@divisions.push(DungeonDivision.new(0, h, width, h, wall_height, 1))
						for x in 0...@divisions[0].width
							for y in 0...@divisions[0].height
								@data[x, y] = @divisions[0].data[x, y]
							end  
						end
            
						for x in 0...@divisions[1].width
							for y in 0...@divisions[1].height
								@data[x, y + @divisions[0].height] = @divisions[1].data[x, y]
							end  
						end            
            
						x = width / 2
						for y  in (@divisions[0].height / 2)..(@divisions[0].height + @divisions[1].height / 2)
							@data[x, y] = ::RGG::Dungeons::FLOOR
						end            
					end
				else
					w = [rand(width)  + rand(width  / 2) - rand(width   / 4), width  - 4].min
					h = [rand(height) + rand(height / 2) - rand(height  / 4), height - 6].min
					mx = (width - w) / 2
					my = (height - h) / 2
					for x in mx...mx+w
						for y in my...my+h
							@data[x, y] = ::RGG::Dungeons::FLOOR
						end  
					end
				end  
			end
		end	
	
	
		#==============================================================================================================
		# ** RGG::Dungeons::cellular_automata(width, height[,wall_height last_mov])
		#--------------------------------------------------------------------------------------------------------------
		# * Creates a Dungeon with the BSP method.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- width       : The width  (in tiles) for the dungeon
		#	- height      : The height (in tiles) for the dungeon
		#	- wall_height : The wall height (in tiles) of the dungeon, set as 0, if you dont want any.
		#	                (default = DEFAULT_WALL_HEIGHT)
		# * Returns:
		# 	- A Table Object(see Table) with sizes width x height containing the generated dungeon.
		#--------------------------------------------------------------------------------------------------------------
		# * Generator Notes:
		# 	Advantages:
		# 		- This system ensures that every space is rechable.
		#		- Ganarates a great irregular effect. (Specially good for caves)
		#	Disadvantages:
		#		- This method would make easier dungeons than other ones.
		#		- Extremly slow method.
		#		- May create "Big areas" filled with nothing.
		#==============================================================================================================		
		def self.cellular_automata(width, height,wall_height = DEFAULT_WALL_HEIGHT)
			# sets up the data
			data = Table.new(width, height)
			for x in 0...data.xsize
				for y in 0...data.ysize
					data[x, y] = ROOF 
				end
			end		

			points = data.xsize * data.ysize * 10 / 100
			while points > 0 
				rx = [rand(width ) / 2, 5].min 
				ry = [rand(height) / 2, 5].min 
				x  = rand(width  - 6 - rx * 2) + rx / 2 + 2
				y  = rand(height - 6 - ry * 2) + ry / 2 + 2
				if rand(10) == 0
					add_inverted_circle(x, y, rx, ry, data)
				else
					add_circle(x, y, rx, ry, data)
				end  
				points -= rx * ry
			end    
      
			points = width * height * 30 / 100
			tries = 0
			while points > 0 
				x = rand(data.xsize)
				y = rand(data.ysize)
				if check_walls(x, y,data, 1, wall_height+1) == 0
					for i in y..(y + wall_height+1)
						data[x, i] = ROOF
						points -= wall_height  + 2
						tries = 0
					end  
				end  
				tries += 1
				points = 0 if tries > 10000
			end        
      
			leap = 1
      
			for x in 1...((data.xsize - 1) / leap)
				for y in 1...((data.ysize-1) / leap)
					if data[x * leap, y * leap] == FLOOR
						join_points(Point.new(x * leap, y * leap), data, wall_height) 
					end  
				end
			end 
      
			(2).times do |i|
				for x in 1...(data.xsize - 1)
					for y in 1...(data.ysize - 1)
						wall_count = check_walls(x, y, data)
						if wall_count > 5
							data[x, y] = ROOF if data[x, y]
						elsif wall_count < 4
							data[x, y] = FLOOR if data[x, y]
						end  
					end
				end
			end         
			# returns the current data created
			return generate_walls(data, wall_height)
		end
		
		#==============================================================================================================
		# ** RGG::Dungeons::mirrored(dungeon[, mode])
		#--------------------------------------------------------------------------------------------------------------
		# * Creates a Dungeon using a mirror method.
		#   The width and height of the newly created dungeon is automatically recognized.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- dungeon     : The dungeon data to mirror
		#	- mode        : The mirror mode (default is X and Y)
    #	- wall_height : The height of the wall. (default = DEFAULT_WALL_HEIGHT)
		# * Returns:
		# 	- A Table Object(see Table) with sizes width x height containing the generated dungeon.
		#--------------------------------------------------------------------------------------------------------------
		# * Generator Notes:
		# 	Advantages:
		# 		- Great effect for some places.
		#	Disadvantages:
		#		- Needs previous data to work, so it is just
		#==============================================================================================================	
		def self.mirrored(dungeon, mode= Y_MIRROR, wall_height = DEFAULT_WALL_HEIGHT)
			# sets up the data
			width  = (mode != Y_MIRROR) ? dungeon.xsize * 2 : dungeon.xsize
			height = (mode != X_MIRROR) ? dungeon.ysize * 2 : dungeon.ysize		
			data = Table.new(width, height)
			for x in 0...width
				for y in 0...height
					data[x, y] = ROOF 
				end
			end		
			
			case mode
			when X_MIRROR
				for x in 0...(width / 2)
					for y in 0...(height)
						data[x, y] = dungeon[x, y]  if valid_draw?(x, y, dungeon)
					end  
				end          
        
				case rand(2)
				when 0
					x = width / 2 - 1
					while x > 0
						y = height - 1
						while y > 0
							if data[x, y] == FLOOR
								for i in x..(width / 2)
									data[i, y] = FLOOR
								end             
								y = x = 0
							end
							y -= 1
						end
						x -= 1
					end 
				else  
					x = width / 2 - 1
					while x > 0
						y = 0
						while y < height - 1
							if data[x, y] == FLOOR
								for i in x..(width / 2)
									data[i, y] = FLOOR
								end             
								y = height
								x = 0
							end
							y += 1
						end
						x -= 1
					end 
				end          
        
				for x in 0...(width / 2)
					for y in 0...(height)
						data[width - x - 1, y] = data[x, y]  if valid_draw?(x, y, data)
					end  
				end        
        
			when Y_MIRROR
        
				for x in 0...(width)
					for y in 0...(height / 2)
						data[x, y] = dungeon[x, y]  if valid_draw?(x, y, dungeon)
					end  
				end        
        
				case rand(2)
				when 0
					x = width - 1
					while x > 0
						y = height / 2 - 1
						while y > 0
							if data[x, y] == FLOOR
								for i in y..(height / 2)
									data[x, i] = FLOOR
								end              
								y = x = 0
							end
							y -= 1
						end
						x -= 1
					end        
				else
					x = 0
					while x < width - 1
						y = height / 2 - 1
						while y > 0
							if data[x, y] == FLOOR
								for i in y..(height / 2)
									data[x, i] = FLOOR
								end              
								y = 0
								x = width
							end
							y -= 1
						end
						x += 1
					end    
				end
        
				for x in 0...(width)
					for y in 0...(height / 2)
						data[x,height - y - 2] =  data[x, y] if valid_draw?(x, y, data)
					end  
				end        
			else
				for x in 0...(width / 2)
					for y in 0...(height / 2)
					data[x, y] = dungeon[x, y] = dungeon[x, y] if valid_draw?(x, y, dungeon)
				end  
			end
        
			case rand(2)
			when 0
				x = width / 2 - 1
				while x > 0
					y = height / 2 - 1
					while y > 0
						if data[x, y] == FLOOR
							for i in x..(width / 2)
								data[i, y] = FLOOR
							end             
							y = x = 0
						end
						y -= 1
					end
					x -= 1
				end 
			else  
				x = width / 2 - 1
				while x > 0
					y = 0
					while y < height / 2 - 1
						if data[x, y] == FLOOR
							for i in x..(width / 2)
								data[i, y] = FLOOR
							end             
							y = height
							x = 0
						end
						y += 1
					end
					x -= 1
				end 
			end 
        
			case rand(2)
			when 0
				x = width / 2 - 1
				while x > 0
					y = height / 2 - 1
					while y > 0
						if data[x, y] == FLOOR
							for i in y..(height / 2)
								data[x, i] = FLOOR
							end              
							y = x = 0
						end
						y -= 1
					end
						x -= 1
					end        
				else
					x = 0
					while x < width / 2 - 1
						y = height / 2 - 1
						while y > 0
							if data[x, y] == FLOOR
								for i in y..(height / 2)
									data[x, i] = FLOOR
								end              
								y = 0
								x = width
							end
							y -= 1
						end
						x += 1
					end    
				end         
        
				for x in 0...(width / 2)
					for y in 0...(height / 2)
						data[width - x - 1, y] =  data[x, y] if valid_draw?(x, y, data)
					end  
				end
        
				for x in 0...(width)
					for y in 0...(height / 2)
						data[x,height - y - 1] =  data[x, y] if valid_draw?(x, y, data)
					end  
				end        
			end  
			
			# returns the current data created
			return generate_walls(data, wall_height)     
      
		end
		
		#==============================================================================================================
		# ** RGG::Dungeons::valid_draw?(x, y, data)
		#--------------------------------------------------------------------------------------------------------------
		# * Checks if a point of the map is valid.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- x           : the x coordinate to check.
		#	- y           : the y coordinate to check.
		#	- data        : the data to check.
		# * Returns:
		# 	- true if the position is valid, false elsewhere.
		#==============================================================================================================			
		def self.valid_draw?(x, y, data)
			return false if x > data.xsize - 1 || x < 1 || y > data.ysize || y < 1
			return false if !data[x, y]
			return false if data[x, y] != FLOOR
			return true
		end		
		
		#==============================================================================================================
		# ** RGG::Dungeons::join_points(point, data[, wall_height])
		#--------------------------------------------------------------------------------------------------------------
		# * Join a point to the center of a dungeon.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	  - point       : The point to join.
		# 	- data        : The data where the point is.
    #   - wall_height : The height of the wall. (default = DEFAULT_WALL_HEIGHT)
		#==============================================================================================================			
		def self.join_points(point, data, wall_height= DEFAULT_WALL_HEIGHT)
			center_point = center(data)
			tries = 0
			loop do
				dir = get_tunnel_dir(point, center_point)
				case rand(2)
				when 0
					next_point = Point.new(dir.x + point.x, point.y)
				else
					next_point = Point.new(point.x, point.y + dir.y)
				end
      
				break if stop_drawing(point,next_point, data) || tries > 10000 ||
				next_point.x < 1 || next_point.y < wall_height || next_point.x > (data.xsize - 1) || next_point.y > (data.ysize - 1)
        
				data[next_point.x, next_point.y] = FLOOR if valid?(next_point.x, next_point.y, data)
				point = next_point
				tries += 1
			end 
		end
		
		#==============================================================================================================
		# ** RGG::Dungeons::get_tunnel_dir(p1, p2)
		#--------------------------------------------------------------------------------------------------------------
		# * Checks the direction between a "current point" and a "goal point".
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- p1     : the current point.
		#	- p2     : the goal point.
		# * Returns:
		# 	- a Point with the x and y coordinates of direction.
		#==============================================================================================================			
		def self.get_tunnel_dir(p1, p2)
			dir = Point.new(0, 0)
			if p1.x < p2.x
				dir.x += 1
			elsif p1.x > p2.x 
				dir.x -= 1
			end  
			if p1.y < p2.y
				dir.y += 1
			elsif p1.y > p2.y 
				dir.y -= 1
			end       
			return dir
		end		
		
		#==============================================================================================================
		# ** RGG::Dungeons::stop_drawing(p1, p2, data)
		#--------------------------------------------------------------------------------------------------------------
		# * Determines if a "current point" has not reached a "goal point".
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- p1     : the current point.
		#	- p2     : the goal point.
		#	- data   : the data to check.
		# * Returns:
		# 	- true if it's needed to stop drawing, false elsewhere.
		#==============================================================================================================	
		def self.stop_drawing(p1,p2, data)
			return true if p2 == center(data)
			return true if p1 != p2 && data[p2.x, p2.y] == FLOOR
			return false
		end
    
		#==============================================================================================================
		# ** RGG::Dungeons::check_walls(x, y, data[,distance, wall_height])
		#--------------------------------------------------------------------------------------------------------------
		# * hecks how many walls are arround a determined tile.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- x           : the x coordinate to check.
		#	- y           : the y coordinate to check.
		#	- data        : the data to check.
		#	- distance    : the distance of checking (default = 1)
		#	- wall_height : the height of the wall (default = DEFAULT_WALL_HEIGHT)
		# * Returns:
		# 	- a number representing the number of tiles in area 
		#    [x-distance ... x+distance; y-distance ... y+distance+wall_height] whow many tiles are walls.
		#	 including the centered tile as well.
		#==============================================================================================================		
		def self.check_walls(x, y, data, distance = 1, wall_count = 0)
			sum = 0
			for i in (x-distance)..(x+distance)
				for j in (y-distance)..(y+distance+wall_count)
					if (!valid?(x, y, data) || data[x, y] != FLOOR)
						sum += 1
					end  
				end
			end  
			return sum
		end 		
		
		#==============================================================================================================
		# ** RGG::Dungeons::valid?(x, y, data[, wall_height])
		#--------------------------------------------------------------------------------------------------------------
		# * Checks if a determined point of the dungeon is able tobe drawn.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- x           : the x coordinate to check.
		#	- y           : the y coordinate to check.
		#	- data        : the data to check.
		#	- wall_height : the height of the wall (default = DEFAULT_WALL_HEIGHT)
		# * Returns:
		# 	- true if the position is valid, false elsewhere.
		#==============================================================================================================			
		def self.valid?(x, y, data, wall_height = DEFAULT_WALL_HEIGHT)
			return (x > 0 && y > wall_height + 1 && x < data.xsize - 1 && y < data.ysize - 1)
		end
		
		#==============================================================================================================
		# ** RGG::Dungeons::center(data)
		#--------------------------------------------------------------------------------------------------------------
		# * Gets the center position of the data.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- data : The data to check.
		# * Returns:
		# 	- a Point with the positions of the center of the data.
		#==============================================================================================================	
		def self.center(data)
			return Point.new(data.xsize / 2, data.ysize / 2)
		end		
		
		#==============================================================================================================
		# ** RGG::Dungeons::generate_walls(data[, wall_height])
		#--------------------------------------------------------------------------------------------------------------
		# * Generates the walls of a dungeon.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- x           : the x coordinate to check.
		#	- y           : the y coordinate to check.
		#	- data        : the data to check.
		#	- wall_height : the height of the wall (default = DEFAULT_WALL_HEIGHT)
		# * Returns:
		# 	- true if the position is valid, false elsewhere.
		#==============================================================================================================			
		def self.generate_walls(data, wall_height = DEFAULT_WALL_HEIGHT)
			for x in 0...data.xsize
				for y in 0...data.ysize
          
					if data[x, y] == FLOOR
						need_wall = true
						for i in 1..(wall_height + 1)
							if !data[x, y-i] || data[x, y-i] != ROOF
								need_wall = false 
								break
							end
						end
            
						if need_wall
							for i in 1..wall_height
								data[x, y-i] = WALL if data[x, y-i]
							end
						end
            
					end  
				end
			end
			return revise_walls(data)
		end
		
		#==============================================================================================================
		# ** RGG::Dungeons::wall_complete?(x, y, data)
		#--------------------------------------------------------------------------------------------------------------
		# * Checks if a wall can exist in that position.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- x           : the x coordinate to check.
		#	- y           : the y coordinate to check.
		#	- data        : the data to check.
		# * Returns:
		# 	- true if the wall has to be there, false elsewhere.
		#==============================================================================================================			
		def self.wall_complete?(x, y, data)
			for i in  y...data.ysize
				return true if data[x, i] == WALL
				return false if data[x, i] != ROOF
			end
			return true
		end
		
		#==============================================================================================================
		# ** RGG::Dungeons::revise_walls(data)
		#--------------------------------------------------------------------------------------------------------------
		# * Correct impossible walls.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- data : The data to check.
		# * Returns:
		# 	- the data with the corrections.
		#==============================================================================================================			
		def self.revise_walls(data)
			for x in 0...data.xsize
				for y in 0...data.ysize
					if data[x, y] == ROOF
            data[x, y] = FLOOR if !wall_complete?(x, y, data)
          end
				end  
			end
			return data
    end		
		
		
		#==============================================================================================================
		# ** RGG::Dungeons::revise_walls(data)
		#--------------------------------------------------------------------------------------------------------------
		# * Creates an inverted circular randomized space in a chunk of data.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- x    : the x coordinate.
		#	- y    : the y coordinate.
		#	- rx   : the x radious of the circle.
		#	- ry   : the y radious of the circle.
		#	- data : The data to add the circle.
		#==============================================================================================================	
		
		def self.add_inverted_circle(x, y, rx, ry, data)
			cx = x + rx
			cy = y + ry
			x1 = (x - rx)
			x2 = (x + 2 * rx)
			y1 = (y - ry)
			y2 = (y + 2 * ry)
			r = Math.sqrt((rx * ry).abs)
			for i in x1..x2
				for j in y1..y2
					data[i, j] = FLOOR if valid?(i, j, data) &&  Math.hypot(i - cx, j - cy) >= r
				end
			end  
		end
    
		#==============================================================================================================
		# ** RGG::Dungeons::revise_walls(data)
		#--------------------------------------------------------------------------------------------------------------
		# * Creates a circular randomized space in a chunk of data.
		#--------------------------------------------------------------------------------------------------------------
		# * Parameters:
		#	- x    : the x coordinate.
		#	- y    : the y coordinate.
		#	- rx   : the x radious of the circle.
		#	- ry   : the y radious of the circle.
		#	- data : The data to add the circle.
		#==============================================================================================================		
		def self.add_circle(x, y, rx, ry, data)
			cx = x + rx
			cy = y + ry
			x1 = (x - rx)
			x2 = (x + 2 * rx)
			y1 = (y - ry)
			y2 = (y + 2 * ry)
			r = Math.sqrt(rx * ry)
			for i in x1..x2
				for j in y1..y2
					data[i, j] = FLOOR if valid?(i, j, data) && Math.hypot(i - cx, j - cy) < r
				end
			end  
		end		
		
	end
end


If you want to use it with the RPG Maker XP/VX program, rmemeber to delete the Color and Table classes. You can take a view with that maker with this:

class Sprite_MapTest < Sprite
  
  TILE_SIZE = 4
  
  def initialize(data)
    super()
    @data = data
    draw_bitmap
  end
  
  def draw_bitmap
    self.bitmap.dispose if self.bitmap
    self.bitmap = Bitmap.new(@data.xsize * TILE_SIZE, @data.ysize * TILE_SIZE)
    for i in 0...@data.xsize
      for j in 0...@data.ysize
        x = i * TILE_SIZE
        y = j * TILE_SIZE
        self.bitmap.fill_rect(x,y, TILE_SIZE, TILE_SIZE, RGG::Dungeons::COLORS[@data[i, j]])
      end
    end
  end
  
  def dispose
    self.bitmap.dispose if self.bitmap
    super
  end
  
end

Sprite_MapTest.new(RGG::Dungeons.cellular_automata(80,80))

loop do
  Graphics.update
end