Created
October 14, 2016 15:27
-
-
Save misternu/fe71c653a93f9d60abfa066ced528bb3 to your computer and use it in GitHub Desktop.
Prim's Algorithm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Data structure for square | |
| class Square | |
| attr_accessor :in, :frontier | |
| attr_reader :walls | |
| def initialize | |
| @walls = (0..3).to_a | |
| @in = false | |
| @frontier = false | |
| end | |
| def open_wall(i) | |
| @walls.delete(i) | |
| end | |
| end | |
| def neighbors(x, y, grid) | |
| [x - 1, x + 1] | |
| .select { |n| (0...grid[0].length).include?(n) } | |
| .product([y]) + | |
| [x].product([y - 1, y + 1] | |
| .select { |n| (0...grid.length).include?(n) }) | |
| # n = [] | |
| # n << [x - 1, y] if x > 0 | |
| # n << [x + 1, y] if x + 1 < grid[0].length | |
| # n << [x, y - 1] if y > 0 | |
| # n << [x, y + 1] if y + 1 < grid.length | |
| # n | |
| end | |
| def neighbors_in(x, y, grid) | |
| neighbors(x, y, grid).select { |nx, ny| grid[ny][nx].in } | |
| end | |
| def expand_frontier(x, y, grid, frontier) | |
| neighbors(x, y, grid).select { |nx, ny| !grid[ny][nx].frontier } | |
| .each do |nx, ny| | |
| frontier << [nx, ny] | |
| grid[ny][nx].frontier = true | |
| end | |
| end | |
| def connect(x, y, nx, ny, grid) | |
| if y > ny | |
| # grid[y][x].open_wall(0) | |
| grid[ny][nx].open_wall(2) | |
| elsif x < nx | |
| grid[y][x].open_wall(1) | |
| # grid[ny][nx].open_wall(3) | |
| elsif y < ny | |
| grid[y][x].open_wall(2) | |
| # grid[ny][nx].open_wall(0) | |
| elsif x > nx | |
| # grid[y][x].open_wall(3) | |
| grid[ny][nx].open_wall(1) | |
| end | |
| end | |
| def display_maze(grid) | |
| maze_string = "\e[2J\e[H" + '.' + '_.' * grid[0].length + "\n" | |
| grid.each do |row| | |
| row_string = '|' | |
| row.each do |square| | |
| row_string << (square.walls.include?(2) ? '_' : ' ') | |
| row_string << (square.walls.include?(1) ? '|' : '.') | |
| end | |
| row_string << "\n" | |
| maze_string += row_string | |
| end | |
| puts maze_string | |
| end | |
| HEIGHT = 20 | |
| WIDTH = 30 | |
| grid = Array.new(HEIGHT) { Array.new(WIDTH) { Square.new } } | |
| frontier = [[rand(WIDTH), rand(HEIGHT)]] | |
| x, y = frontier.first | |
| p grid | |
| grid[y][x].frontier = true | |
| display_maze(grid) | |
| while frontier.length > 0 | |
| sleep 0.002 | |
| x, y = frontier.delete_at(rand(frontier.length)) | |
| nx, ny = neighbors_in(x, y, grid).sample | |
| connect(x, y, nx, ny, grid) if nx | |
| grid[y][x].in = true | |
| expand_frontier(x, y, grid, frontier) | |
| display_maze(grid) | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment