From 4a5fdb75aa87d167285b693aeb604c66f2163fa2 Mon Sep 17 00:00:00 2001 From: Tyrel Souza Date: Tue, 10 Apr 2018 22:31:01 -0400 Subject: [PATCH] Initial Commit --- Gemfile | 3 ++ binary_tree.rb | 16 ++++++ binary_tree_demo.rb | 9 ++++ cell.rb | 38 +++++++++++++++ grid.rb | 116 ++++++++++++++++++++++++++++++++++++++++++++ sidewinder.rb | 26 ++++++++++ sidewinder_demo.rb | 9 ++++ 7 files changed, 217 insertions(+) create mode 100644 Gemfile create mode 100644 binary_tree.rb create mode 100644 binary_tree_demo.rb create mode 100644 cell.rb create mode 100644 grid.rb create mode 100644 sidewinder.rb create mode 100644 sidewinder_demo.rb diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..7630110 --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gem 'chunky_png' \ No newline at end of file diff --git a/binary_tree.rb b/binary_tree.rb new file mode 100644 index 0000000..b29241f --- /dev/null +++ b/binary_tree.rb @@ -0,0 +1,16 @@ +class BinaryTree + def self.on(grid) + grid.each_cell do |cell| + neighbors = [] + neighbors << cell.north if cell.north + neighbors << cell.east if cell.east + + neighbor = neighbors.sample + + cell.link(neighbor) if neighbor + + end + + grid + end +end \ No newline at end of file diff --git a/binary_tree_demo.rb b/binary_tree_demo.rb new file mode 100644 index 0000000..50e0a3c --- /dev/null +++ b/binary_tree_demo.rb @@ -0,0 +1,9 @@ +require "grid" +require "binary_tree" + +grid = Grid.new(6, 10) +BinaryTree.on(grid) + +puts grid +img = grid.to_png +img.save "bt.png" \ No newline at end of file diff --git a/cell.rb b/cell.rb new file mode 100644 index 0000000..6b6d1c1 --- /dev/null +++ b/cell.rb @@ -0,0 +1,38 @@ +class Cell + attr_reader :row, :column + attr_accessor :north, :south, :east, :west + + def initialize(row, column) + @row, @column = row, column + @links = {} + end + + def link(cell, bidi=true) + @links[cell] = true + cell.link(self, false) if bidi + self + end + + def unlink(cell, bidi=true) + @links.delete(cell) + cell.unlink(self, false) if bidi + self + end + + def links + @links.keys + end + + def linked?(cell) + @links.key?(cell) + end + + def neighbors + list = [] + list << north if north + list << south if south + list << east if east + list << west if west + list + end +end \ No newline at end of file diff --git a/grid.rb b/grid.rb new file mode 100644 index 0000000..e10af68 --- /dev/null +++ b/grid.rb @@ -0,0 +1,116 @@ +require "cell" +require "chunky_png" + +class Grid + attr_reader :rows, :columns + + def initialize(rows, columns) + @rows = rows + @columns = columns + + @grid = prepare_grid + configure_cells + end + + def prepare_grid + Array.new(rows) do |row| + Array.new(columns) do |column| + Cell.new(row, column) + end + end + end + + def configure_cells + each_cell do |cell| + row, col = cell.row, cell.column + + cell.north = self[row - 1, col] + cell.south = self[row + 1, col] + cell.west = self[row, col - 1] + cell.east = self[row, col + 1] + end + end + + def [](row, column) + return nil unless row.between?(0, @rows - 1) + return nil unless column.between?(0, @grid[row].count - 1) + @grid[row][column] + end + + def random_cell + row = rand(@rows) + column = rand(@grid[row].count) + + self[row, column] + end + + def size + @rows * @columns + end + + def each_row + @grid.each do |row| + yield row + end + end + + def each_cell + each_row do |row| + row.each do |cell| + yield cell if cell + end + end + end + + + def to_s + output = "+" + "---+" * columns + "\n" + corner = "+" + + each_row do |row| + top = "|" + bottom = "+" + + row.each do |cell| + cell = Cell.new(-1, -1) unless cell + body = " " + east_boundary = (cell.linked?(cell.east) ? " " : "|") + top << body << east_boundary + + south_boundary = (cell.linked?(cell.south) ? " " : "---") + bottom << south_boundary << corner + end + + output << top << "\n" + output << bottom << "\n" + end + + output + end + + def to_png(cell_size: 10) + img_width = cell_size * columns + img_height = cell_size * rows + + background = ChunkyPNG::Color::WHITE + wall = ChunkyPNG::Color::BLACK + + img = ChunkyPNG::Image.new(img_width + 1, img_height + 1, background) + + each_cell do |cell| + x1 = cell.column * cell_size + y1 = cell.row * cell_size + x2 = (cell.column+1) * cell_size + y2 = (cell.row+1) * cell_size + + img.line(x1, y1, x2, y1, wall) unless cell.north + img.line(x1, y1, x1, y2, wall) unless cell.west + img.line(x2, y1, x2, y2, wall) unless cell.linked?(cell.east) + img.line(x1, y2, x2, y2, wall) unless cell.linked?(cell.south) + end + + img + + end + +end \ No newline at end of file diff --git a/sidewinder.rb b/sidewinder.rb new file mode 100644 index 0000000..0d1ff42 --- /dev/null +++ b/sidewinder.rb @@ -0,0 +1,26 @@ +class Sidewinder + def self.on(grid) + grid.each_row do |row| + run = [] + row.each do |cell| + run << cell + + at_eastern_boundary = (cell.east == nil) + at_northern_boundary = (cell.north == nil) + + should_close_out = at_eastern_boundary || (!at_northern_boundary && rand(2) == 0) + + if should_close_out + member = run.sample + member.link(member.north) if member.north + run.clear + else + cell.link(cell.east) + end + + end + end + + grid + end +end \ No newline at end of file diff --git a/sidewinder_demo.rb b/sidewinder_demo.rb new file mode 100644 index 0000000..29d9212 --- /dev/null +++ b/sidewinder_demo.rb @@ -0,0 +1,9 @@ +require "grid" +require "sidewinder" + +grid = Grid.new(6, 10) +Sidewinder.on(grid) + +puts grid +img = grid.to_png +img.save "sw.png" \ No newline at end of file