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>