On Sep 6, 2007, at 7:44 AM, Joop Van den tillaart wrote:

> Joop Van den tillaart wrote:
>> Wow, thanks for your help...
>>
>> Im trying it out right now...
>
> Hey all you guys...
>
> me and someone of my university have set up a new way of generating  
> the
> grid.
>
> For now it generates a grid of 20x20 with 2 columns and 1 row filled
> with celltype 1. The other cells are set to value 0.
>
> I want the remaining cells with value 0 to be divided in say 60%  
> type 2
> and the remaining 40% (of the remaining 0 cells) to be valued as  
> type 3.
>
> Does anyone know how to do this in a neat way (from a programmers  
> point
> 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.

2. Look at how I rewrote Grid#[] below.

3. 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

<code>
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#[](x))).[](y)
   # 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)
</code>