```Here is my solution.
Pastie: http://pastie.org/377536
The pastie still has the comment on the distances function as
returning the distance between two hexes, but I changed this to return
an array of all distances from some position, since the breadth-first
search was already calculating this anyway.

class Hex
attr_accessor :neighbours,:distance
def initialize(row,col,rows,cols)
@neighbours =
[[-1,-1],[-1,0],[0,-1],[0,1],[1,0],[1,1]].map{|r,c|[row+r,col+c]}.select{|r,c|
r>=0 && c>=0 && r<rows && c<cols}
@obstructed = col==3 && row!=rows-1  ||  col==6 && row!=0 # double barrier
end
def obstructed?; @obstructed ;end
end

class HexBoard < Array
def initialize(rows=9, cols=9)
super(rows) {|row| Array.new(cols) {|col| Hex.new(row,col, rows,cols) }}
end
# Distance from position to each hex
def distances(position,&block)
each{|row| row.each{|hex| hex.distance = nil } }
bfs_distance([position],0, &block);
map{|row| row.map &:distance }
end
def bfs_distance(hexes,dist, &block)
q = []
hexes.map{|r,c| self[r][c] }.each{|hex|
next if hex.distance || block_given? && yield(hex)
hex.distance = dist
q += hex.neighbours
}
bfs_distance(q.uniq,dist+1, &block) unless hexes.empty?
end
# Draw solution
def draw(from=[4,4],&block)
distances(from,&block).each_with_index{|dists,row| puts "#{row}:#{'
'*(size - row)}#{dists.map{|x|x||'#'}.join ' '}\n" }
end
end

board = HexBoard.new
board.draw
board.draw([0,0],&:obstructed?)

```