[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Filling individual cells in a grid

Joop Van den tillaart

9/3/2007 10:13:00 AM

Hi guys,

can someone please lend me a hand in this. I have a piece of code that
generates a grid like structure. All the cells in this grid now have 2
properties namely a celltype and a cell distance (to cells with type 1).

For now the code can only define celltypes to rows and columns. I need
to add a piece of code that will let me define celltypes to individual
cells. Does anyone know how I can achieve this and what pieces of code I
need to add?

I could really use a hand of someone more experienced in Ruby as I am.
Thanks in advance!

Greets tillaart36...

Attachments:
http://www.ruby-...attachment/218/te...

--
Posted via http://www.ruby-....

31 Answers

Todd Benson

9/3/2007 11:12:00 AM

0

On 9/3/07, Joop Van den tillaart <tillaart36@hotmail.com> wrote:
> Hi guys,
>
> can someone please lend me a hand in this. I have a piece of code that
> generates a grid like structure. All the cells in this grid now have 2
> properties namely a celltype and a cell distance (to cells with type 1).
>
> For now the code can only define celltypes to rows and columns. I need
> to add a piece of code that will let me define celltypes to individual
> cells. Does anyone know how I can achieve this and what pieces of code I
> need to add?
>
> I could really use a hand of someone more experienced in Ruby as I am.
> Thanks in advance!
>
> Greets tillaart36...
>
> Attachments:
> http://www.ruby-forum.com/attachment/218/te...

With your current code...

grid[1,1].type = 3
grid[1,1].distance_road = 5

Todd

Joop Van den tillaart

9/3/2007 11:22:00 AM

0

> With your current code...
>
> grid[1,1].type = 3
> grid[1,1].distance_road = 5
>
> Todd

Hey,

thanks for your help. I was working the code myself and found another
way of individual filling but your way is much cleaner I think. Is there
also a way of filling a group of cells (which is not a full column or a
full row)?

All the cells with type 1 are are already defined and then I need to
fill like 60% of the remaining cells with type 3 and the other 40% with
type 4. I think I need to add a method to the code which lets me do that
but I'm don't have much experience with ruby so I don't know how to do
this...

Can anybody help me further on this?
--
Posted via http://www.ruby-....

Joop Van den tillaart

9/3/2007 12:41:00 PM

0

Is there no one else who can help me out a bit?

Thanks...

--
Posted via http://www.ruby-....

Logan Capaldo

9/3/2007 12:54:00 PM

0

On 9/3/07, Joop Van den tillaart <tillaart36@hotmail.com> wrote:
> Is there no one else who can help me out a bit?
>
> Thanks...
>
> --
> Posted via http://www.ruby-....
>
>
it's been less than three hours since you posted your original
question. Patience is a wonderful thing.

Logan Capaldo

9/3/2007 12:59:00 PM

0

On 9/3/07, Joop Van den tillaart <tillaart36@hotmail.com> wrote:
> Is there no one else who can help me out a bit?
>
> Thanks...
>
> --
> Posted via http://www.ruby-....
>
>
it's been less than three hours since you posted your original
question. Patience is a wonderful thing.

Morton Goldberg

9/3/2007 2:24:00 PM

0

On Sep 3, 2007, at 8:40 AM, Joop Van den tillaart wrote:

> Is there no one else who can help me out a bit?

OK, I'll make some suggestions.
1. I think you could make your life a lot easier if you gave your
cell objects more info about where they live.
2. I suggest you fill @grid with cells during initialization.
3. I suggest you include Enumerable in your Grid class. Then you only
have to define Grid#each to get map, collect, and whole more for free.

<code>
class Cell
attr_accessor :type, :distance_road
attr_reader :i
def initialize(grid, i)
@my_grid = grid
@i = i
end
def xy
@i.divmod(@my_grid.width).reverse
end
def inspect
"Cell[#{@i}, #{xy.inspect}, #{type}, #{distance_road}]"
end
end
class Grid
include Enumerable
attr :width, :heigh
def initialize(width, height)
@grid = Array.new(width * height) { |i| Cell.new(self, i) }
@width = width
@height = height
end
def [](x, y)
raise IndexError.new("Index (#{x}, #{y}) out of range") if x < 0 || y < 0 || x >= @width || y >= @width
@grid[y * width + x]
end
def []=(x, y, value)
raise IndexError.new("Index (#{x}, #{y}) out of range") if x < 0 || y < 0 || x >= @width || y >= @width
@grid[y * width + x] = value
end
def each
@grid.each { |cell| yield cell }
end
end

# Now you can do all kinds of neat things.

g = Grid.new(2, 2)
p g
g.map { |cell| cell.type = 0; cell.distance_road = cell.i % 2 }
p g
h = g.select { |cell| cell.distance_road == 1 }
h.each { |cell| cell.type = 42 }
p g
p g.any? { |cell| cell.type == 42 }
p g.all? { |cell| g[*cell.xy] == cell }
</code>

<result>
#<Grid:0x7b128 @width=2,
@grid=[Cell[0, [0, 0], , ], Cell[1, [1, 0], , ],
Cell[2, [0, 1], , ], Cell[3, [1, 1], , ]],
@height=2>
#<Grid:0x7b1a0 @width=2,
@grid=[Cell[0, [0, 0], 0, 0], Cell[1, [1, 0], 0, 1],
Cell[2, [0, 1], 0, 0], Cell[3, [1, 1], 0, 1]],
@height=2>
#<Grid:0x7b1a0 @width=2,
@grid=[Cell[0, [0, 0], 0, 0], Cell[1, [1, 0], 42, 1],
Cell[2, [0, 1], 0, 0], Cell[3, [1, 1], 42, 1]],
@height=2>
true
true
</result>

Regards, Morton



Joop Van den tillaart

9/3/2007 4:04:00 PM

0

Wow, thanks for your help...

Im trying it out right now...
--
Posted via http://www.ruby-....

Joop Van den tillaart

9/6/2007 11:45:00 AM

0

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?

See the attachment for the new generating of the grid.

Thanks in advance!

Attachments:
http://www.ruby-...attachment/233...

--
Posted via http://www.ruby-....

Morton Goldberg

9/6/2007 2:56:00 PM

0

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>

Joop Van den tillaart

9/6/2007 3:39:00 PM

0

hi thanks for your help,

im not sure what you meant with your comments but i will look into
them...again thanks...

And my goal for filling the cells is as you say...the remaining cells
just have to be filled with say 60% type 2 en the remaining 40% of cells
with type 3. This can be done random or just first 60% type2 and the
other type 3.

When this is completed i need to make an algorithm that starts swapping
celltypes depending on neighbour cells and distances to other cells...i
won't go to deep into this but it doesn't matter how the cells in the
first stage are filled...just the types 1 are on a own place because
they characterize a road which is laid in before the algorithm starts
swapping...

So can anyone tell how to define the first 60% as type 2 and the
remaining cells with type 0 to type 3??

thanks!
--
Posted via http://www.ruby-....