On Thu, 2004-09-23 at 14:34, Warren Brown wrote: > Graham, > > You can save yourself an enormous number of headaches by simply > adding two more rows and columns to your array. For example, if you > wanted the world to be 80x24, make your array 82x26 and then make your > loops from 1..80 and 1..24. That way you can safely reference > cell[x-1][y-1] and cell[x+1][y+1] and you don't need all of your special > cases. I agree with the spirit, but I would take it even farther. Why bound the board at all? It should be a lot easier to just have an infinite board (or at least, limited to Bignum#"max", whatever that is). Easier, that is, after you reach in one ear, grab your brain, and give it a sharp twist (about 0.76 radians to the NW should do it if you've been coding in C). A sketch: WARNING: THIS CODE WAS TYPE IN MAIL AND HAS NEVER BEEN RUN class A_cell attr_accessor( :state, # :filled or :empty :neighbors, # 0..8 :loc # [x,y] ) def initialize(x,y) @state = :empty @neighbors = 0 @loc = [x,y] end def fate #depending on @state & @neighbors, return :filled or :empty end end class A_board attr_reader :cells # a hash of [x,y] => A_cell def initialize @cells = Hash.new end def step update_neighbor_count update_states end def update_neighbor_counts @cells.keys.each { |x,y| if @cells[[x,y]].state.filled ((x-1)..(x+1)).each { |x0| ((y-1)..(y+1)).each { |y0| @cells[[x0,y0]] ||= A_cell.new(x0,y0) @cells[[x0,y0]].neighbors += 1 unless x0 == x and y0 == y } } end } end def update_states @cells.keys.each { |x,y| case @cells[[x,y]].fate when :filled @cells[[x,y]].state = :filled @cells[[x,y]].neighbors = 0 when :empty @cells.delete_at [x,y] end end end This has some fat & may be missing some details, but at least it should give you the idea. -- Markus