From: Shawn W_ Date: 2010-07-19T12:47:24+09:00 Subject: Re: Return nothing when looking outside the bounds of 2D array? Dave Howell wrote: > OK, let's try this from the top. {grin} Here's some fresh new code: Thx again - very instructive. I have managed to get the capping working in isolation as per the following code: --- class Array2D Delta=[[0,0], [0,-1], [1,-1], [1,0], [1,1], [0,1], [-1,1], [-1,0], [-1,-1]] attr_reader :width, :height attr_accessor :cell_content def initialize(width, height, cell_content) @width = width @height = height @data = Array.new(@height) {Array.new(@width){|i| cell_content} } end def [](x, y, z) deltaX, deltaY = *Delta[z] x = (x + deltaX) % @width y = (y + deltaY) @data[y][x] unless y<0 or y>(@height-1) end def []=(x, y, z, value) deltaX, deltaY = *Delta[z] x = (x + deltaX) % @width # modulus % allows wrapping y = (y + deltaY) @data[y][x] = value unless y<0 or y>(@height-1) end def display @height.times {|rownum| print(@data[rownum].join(" ") + "\n")};nil end end a=Array2D.new(10,5,"X") m = rand(10) n = rand(5) a[m,n,0] = "A" a[m,n,1] = "H" a[m,n,2] = "H" a[m,n,3] = "H" a[m,n,4] = "A" a[m,n,5] = "A" a[m,n,6] = "A" a[m,n,7] = "A" a[m,n,8] = "A" puts a.display --- However, it still falls over when I try to insert the above into my main program, as below: --- class Array2D Delta=[[0,0], [0,-1], [1,-1], [1,0], [1,1], [0,1], [-1,1], [-1,0], [-1,-1]] attr_reader :width, :height def initialize(width, height) @width = width @height = height @data = Array.new(@height) {Array.new(@width) {|i|"X"}} end def [](x, y, z) deltaX, deltaY = *Delta[z] x = (x + deltaX) % @width y = (y + deltaY) @data[y][x] unless y<0 or y>(@height-1) end def []=(x, y, z, value) deltaX, deltaY = *Delta[z] x = (x + deltaX) % @width # modulus % allows wrapping y = (y + deltaY) @data[y][x] = value unless y<0 or y>(@height-1) end def display @height.times {|rownum| print(@data[rownum].join(" ") + "\n")};nil end end class World < Array2D attr_reader :size def initialize(size) @rows = size @cols = @rows * 2 @world = Array2D.new(@cols, @rows) end def populate_array_cells_with_hash (0...@rows).each do |b| (0...@cols).each do |a| @world[a,b,0] = { "hex_col_no" => a, "hex_row_no" => b, "hex_id_A" => "X ", "hex_id_B" => nil, "hex_id_C" => nil, "hex_id_D" => nil, "hex_id_E" => nil, } end end end def insert_teleporting_square m = rand(@cols) n = rand(@rows) @world[m,n,0]["hex_id_A"] = "A " @world[m,n,1]["hex_id_A"] = "H " @world[m,n,2]["hex_id_A"] = "H " @world[m,n,3]["hex_id_A"] = "H " @world[m,n,4]["hex_id_A"] = "A " @world[m,n,5]["hex_id_A"] = "A " @world[m,n,6]["hex_id_A"] = "A " @world[m,n,7]["hex_id_A"] = "A " @world[m,n,8]["hex_id_A"] = "A " end def print_world(type) (0...@rows).each do |b| puts (0...@cols).each do |a| print @world[a,b,0][type] end end end end first_world = World.new(5) first_world.populate_array_cells_with_hash first_world.insert_teleporting_square first_world.print_world("hex_id_A") puts --- It falls over when it hits one of these two lines: @world[m,n,1]["hex_id_A"] = "H " @world[m,n,4]["hex_id_A"] = "A " With error as before: undefined method `[]=' for nil:NilClass (NoMethodError) What my program does is generate an array, then populates each cell of that array with a hash. It looks like when it tries to access the hash values outside the array boundary it runs into problems? Do I need another method inside the Array2D class to deal with hash access? If so, how can this be done? If not, can anyone see any other reason for the error? -- Posted via http://www.ruby-forum.com/.