From: Dave Howell Date: 2010-07-17T11:44:24+09:00 Subject: Re: Return nothing when looking outside the bounds of 2D array? OK, let's try this from the top. {grin} Here's some fresh new code: class HexArray Delta=[[0,0], [0.5,-1], [1,0], [0.5,1], [-0.5,1], [-1,0], [-0.5,-1]] attr_reader :width, :height def initialize(width, height, default="-") @width = width @height = height @data = Array.new(@width){|row| [default] * @height} end def [](x, y, z) col, row = move(x,y,z) @data[row][col] unless (row<0 or row>(@height-1)) end def []=(x, y, z, value) col, row = move(x,y,z) @data[row][col] = value unless (row<0 or row>(@height-1)) end def inspect @height.times{|rownum| print (" " * (rownum % 2) + @data[rownum].join(" ") + "\n")};nil end private def move(x, y, z) # returns an array with the row and column of the new position deltaX, deltaY = Delta[z] [(x + deltaX + 0.25 + (0.5 * (y%2)) % @width).floor, y + deltaY] end end Instead of repeating the math for figuring out the row and column, I moved it to the "move" method. I also created an 'inspect' method so we can see what we're doing. The math in the 'move' method is all packed together, but it's just what I talked about earlier, except with all the parentheses in the right places to make it work correctly. Note that @data is no longer defined as "Array.new(@width) { Array.new(@height) }". I think I copied that from your code? but discovered that it gave each row the SAME array, so that changing [1][3] caused every cell in that column to have the same value. Useless! Not the first time that feature of Ruby (and it is a feature, wacky though it sometimes seems) has surprised me. Let's take it for a spin. >> a=HexArray.new(5,5) - - - - - - - - - - - - - - - - - - - - - - - - - => >> a[0,0,0] = "A" # upper left => "A" >> a[4,4,0] = "Z" # lower right => "Z" >> a[0,2,0] = "J" # center left => "J" >> a[2,0,0] = "S" # center top => "S" >> a[0,2,2] = "K" # right of J => "K" >> a[2,0,3] = "T" # below S and to the right => "T" >> a[0,2,5] = "I" # left of J (should wrap) => "I" >> a[2,0,1] = "R" # above & right of S (should be ignored) => "R" >> a[4,4,4] = "X" # below and left of Z (should be ignored) => "X" >> a A - S - - - - T - - J K - - I - - - - - - - - - Z => >> a[0,2,4] = "M" # left and below J (should wrap) => "M" >> a A - S - - - - T - - J K - - I - - - - M - - - - Z => >> ?> a[4,2,0] #should be position "I" => "I" >> a[4,2,3] = "N" # right and below "I", should overwrite "M" => "N" >> a A - S - - - - T - - J K - - I - - - - N - - - - Z => Also, I set it up so that a new HexArray gets filled with dashes. If you want to fill it will asterisks, or nils, just do this: a = Array2D(5,5,"*") or a = Array2D(5,5,nil)