On Sep 12, 2007, at 3:51 PM, Joop Van den tillaart wrote: > Well i'll try to explain very very short what i need... <snip> > Sorry for the size of my reply, but when I start typing I have the > tendacy to get a bit abundant :D:D... Your reply is really quite concise and very clear. Now I think I fully understand what you are trying to accomplish. And as you will see, you were already very close to a solution. With the information you supplied above, I took a shot at completing your code. There was really very little I had to add. Here is what I coded: <code> require 'ostruct' class Grid include Enumerable 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 each @grid.each do |row| row.each do |cell| yield cell end end end def [](x, y) begin @grid[y][x] rescue raise IndexError 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 def each_with_remaining each do |cell| next if cell.locked x, y = cell.x, cell.y (x+1...width).each do |col| _cell = cell.grid[col, y] yield cell, _cell unless _cell.locked end (y+1...height).each do |row| (0...width).each do |col| _cell = cell.grid[col, row] yield cell, _cell unless _cell.locked end end end end end DELTAS = [ [-1, -1], [0, -1], [1, -1], [-1, 0], [1, 0], [-1, 1], [0, 1], [1, 1] ] def neighbors(cell) result = [] x, y = cell.x, cell.y DELTAS.each do |dx, dy| begin _cell = cell.grid[x+dx, y+dy] p [x+dx, y+dy] if _cell.nil? result << _cell unless _cell.locked rescue IndexError next end end result end HOUSING_TABLE = {1=>12, 2=>12, 3=>8} GREEN_TABLE = {1=>3, 2=>8, 3=>12} def score(type, neighbors) score = 0 case type when 2 neighbors.each { |cell| score += HOUSING_TABLE[cell.cell_type] } when 3 neighbors.each { |cell| score += GREEN_TABLE[cell.cell_type] } end score 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 zero_cells = grid.select { |cell| cell.cell_type == 0 } n = zero_cells.size k = (0.6 * n).round (0...k).each { |i| zero_cells[i].cell_type = 2 } (k...n).each { |i| zero_cells[i].cell_type = 3 } grid.print_field_values puts n = 3 n.times do grid.each_with_remaining do |cell, other| cn, on = neighbors(cell), neighbors(other) before_score = score(cell.cell_type, cn) + score(other.cell_type, on) after_score = score(other.cell_type, cn) + score(cell.cell_type, on) if after_score <= before_score cell.cell_type, other.cell_type = other.cell_type, cell.cell_type end end grid.print_field_values puts end </code> I ran the script for three iterations. I'm not sure how to interpret the results. I'm not even sure it the loop is converging. I leave it to you to work that out. It may be working as you expect it to, it may be that your scoring function needs adjustment, or may be that there's a bug in my code. One thought that occurs to me: would it be better to start out with a random distribution of housing and green space? <results> # 1st iteration 03 03 03 03 03 03 03 03 03 01 03 03 03 03 03 03 03 03 03 01 03 03 03 03 03 03 03 03 03 01 03 03 03 03 03 03 03 03 03 01 03 03 03 03 03 03 03 03 03 01 03 03 03 03 03 03 03 03 03 01 03 03 03 03 03 03 03 03 03 01 03 03 03 03 03 03 03 03 03 01 03 02 03 02 03 02 03 02 03 01 03 02 03 02 03 02 03 02 02 01 03 02 03 02 03 02 03 02 02 01 02 02 03 02 03 02 03 02 02 01 02 02 03 02 03 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 03 03 02 02 01 02 03 02 03 02 03 02 03 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 03 02 03 02 03 02 03 02 01 02 03 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 # 2nd iteration 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 02 03 03 02 01 02 03 02 03 02 03 03 03 02 01 02 03 03 02 03 02 03 02 03 01 02 03 02 03 02 03 02 03 02 01 02 03 03 02 03 03 03 03 03 01 03 03 02 03 02 03 02 03 03 01 03 02 03 02 03 02 03 02 03 01 02 03 02 03 02 03 02 03 02 01 03 02 03 02 03 02 03 02 03 01 03 03 02 03 02 03 02 03 02 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 03 03 02 03 02 03 02 02 03 01 03 03 02 02 03 02 03 02 03 01 02 03 03 03 03 03 03 03 03 01 02 02 03 03 03 02 03 02 03 01 03 02 02 02 02 02 02 02 02 01 03 03 03 02 02 02 03 02 03 01 03 02 03 03 03 03 03 03 03 01 02 02 02 03 03 03 03 02 03 01 03 02 03 02 03 02 03 02 03 01 03 03 03 03 02 02 03 02 03 01 # 3rd iteration 03 03 03 03 03 03 03 03 03 01 03 03 03 03 03 03 03 03 03 01 03 03 03 03 03 03 03 03 03 01 03 03 02 03 03 02 03 02 03 01 03 02 03 02 03 02 02 02 02 01 02 03 02 03 02 03 03 02 03 01 03 02 03 02 03 02 03 03 03 01 02 03 02 02 02 02 02 02 02 01 03 02 03 02 03 02 03 02 02 01 03 02 02 03 03 03 02 03 02 01 03 02 03 02 03 02 02 02 03 01 03 02 03 02 02 02 02 03 02 01 02 02 03 02 03 02 03 03 02 01 02 02 02 02 03 03 02 03 02 01 03 02 03 02 03 02 02 03 02 01 03 02 03 02 02 02 02 03 02 01 02 02 02 02 02 02 02 02 02 01 02 02 02 02 02 03 02 02 02 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 02 02 02 02 02 02 02 02 02 01 02 02 03 02 02 02 02 02 02 01 02 03 02 03 02 03 02 03 02 01 02 02 02 02 03 03 03 03 02 01 02 03 02 02 02 02 02 02 02 01 02 03 03 02 02 02 02 02 02 01 02 03 02 03 02 03 03 03 02 01 02 02 02 02 03 03 03 03 02 01 02 02 02 02 02 02 02 02 02 01 02 02 03 02 02 02 02 02 02 01 </results> Regards, Morton