On Sep 6, 2007, at 7:44 AM, Joop Van den tillaart wrote:
of view) and if so can anyone share some techniques with me?
Are you asking for a random 40% of the cells to be assigned type 3
state while the remaining 60% is assigned type 2? Or is there some
other criterion?
See the attachment for the new generating of the grid.
I looked at your code and here are some comments:
!. I think you got x and y interchanged. You won’t see the problem as
long you are using square grids. So try it with 20-wide by 15-high
grid. The way you have set it up, it is impossible to traverse the
grid from top to bottom, right-to-left, with Grid#each, which is
something you are going to want to do. Compare print_field_values to
print_grid in the code below.
-
Look at how I rewrote Grid#[] below.
-
Since you are using OpenStructs to model your cells, I can’t see
how you going to write a useful Grid#[]=, but the one you have now
can’t possibly work.
Regards, Morton
require 'ostruct'
class Grid
include Enumerable
def initialize(width, height)
@grid = Array.new(width) do |x|
Array.new(height) do |y|
OpenStruct.new(:x => x, :y => y, :grid => self)
end
end
end
def initialize(width, height)
@grid = Array.new(height) do |row|
Array.new(width) do |col|
OpenStruct.new(:x => col, :y => row, :grid => self)
end
end
end
def width
@grid.first.size
end
def height
@grid.size
end
def width
@grid.size
end
def height
@grid.first.size
end
def each
@grid.each do |row|
row.each do |cell|
yield cell
end
end
end
def [](x, y)
@grid[y][x] if @grid[y]
end
def [](x, y)
return @grid[x][y] if @grid[x]
nil
end
This can’t work – super[x][y] means (self.(Object#)).
which can’t possibly be what is wanted.
def []=(x, y, value)
if @grid[x] && @grid[x][y]
super[x][y] = value
else
raise IndexError.new
end
end
def print_field_values(field_name = :cell_type)
each_with_index do |cell, i|
print "%02d " % cell.send(field_name)
puts if i % width == width - 1
end
end
end
def print_grid(grid, field_name = :cell_type)
grid.height.times do |y|
grid.width.times do |x|
print "%02d " % grid[x,y].send(field_name)
end
puts
end
end
def calculate_distance(grid, field_name)
updated = true
while updated do
updated = false
grid.each do |cell|
for x in (cell.x - 1)…(cell.x + 1)
for y in (cell.y - 1)…(cell.y + 1)
neighbour = grid[x, y]
next if neighbour.nil? || cell == neighbour || x<0 || y< 0
if neighbour.send(field_name) && (cell.send
(field_name).nil? || neighbour.send(field_name) + 1 < cell.send
(field_name))
cell.send(field_name.to_s + “=”, neighbour.send
(field_name) + 1)
updated = true
end
end
end
end
end
end
grid = Grid.new(20, 15)
grid.each { |cell| cell.cell_type = 0 }
grid.height.times { |y| grid[19,y].cell_type = 1 }
grid.height.times { |y| grid[9,y].cell_type = 1 }
grid.width.times { |x| grid[x,9].cell_type = 1 }
grid.each do |cell|
if cell.cell_type == 1
cell.distance_road = 0
cell.locked = true
end
end
grid.each do |cell|
if cell.cell_type == 0
cell.cell_type = 2
end
end
print_grid(grid, :cell_type)
puts
grid.print_field_values(:cell_type)