On Sep 11, 2007, at 4:34 PM, Morton Goldberg wrote: > As is not unusual for me, I've had second thoughts. Here is a > better version. > > <code> > def each_with_neighbor > each do |cell| > next if cell.locked > neighbors(cell).each { |other| yield cell, other } > end > end > > DELTAS = [[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] > result << _cell unless _cell.locked > rescue IndexError > next > end > end > result > end > </code> Third thoughts. I solved the wrong problem. On further consideration, I think this is want you are looking for: <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) @grid[y][x] if @grid[y] 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 end # I'm setting up a small grid here to reduce the amount of output. grid = Grid.new(5, 4) grid.each { |cell| cell.cell_type = 0 } grid.height.times { |y| grid[4, y].cell_type = 1 } grid.height.times { |y| grid[2, y].cell_type = 1 } grid.width.times { |x| grid[x, 3].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 # Example showing how to use each_with_remaining. Shows where your code # would go. Also prints outs what cell pairs get processed. grid.each_with_remaining do |cell, other| # # calculate score for two cells together # a_before = scoreA(cell) + scoreA(other) # # swap cells # cell.cell_type, other.cell_type = other.cell_type, cell.cell_type # # calculate score for two cells together # a_after = scoreA(cell) + scoreA(other) # # if last score is lower or even as the score before swap, # # then swap cells back to first situation # if a_after <= a_before # cell.cell_type, other.cell_type = other.cell_type, cell.cell_type # end p [[cell.x, cell.y, cell.cell_type], [other.x, other.y, other.cell_type]] end </code> Regards, Morton