Return nothing when looking outside the bounds of 2D array?

On Jul 20, 2010, at 22:00 , Shawn W_ wrote:

Shawn W_ wrote:

I think I got it. I did away with storing my cell data in a hash; rather
I will put an array in each cell of the 2D array, and add another
parameter to the def [] and def []= methods to access it.

I don’t recommend scrapping working code, but in the future, you might
want to think about doing something a little more ruby-flavored.
Something like, oh, maybe this…

def HexCell < Array
blah blah
end

ary = HexArray(3,4)
=> (Array of HexCells)

ary[2,3].neighbor(:upperleft)
=> HexCell at [2,2]

Delta would be defined like this:

Delta={:center => [0,0], :upperright => [0.5,-1], :right => [1,0],
:lowerright => [0.5,1], :lowerleft => [-0.5,1], :left => [-1,0],
:upperleft => [-0.5,-1]]

On Jul 18, 2010, at 20:47 , Shawn W_ wrote:

However, it still falls over when I try to insert the above into my main
program, as below:

@world[m,n,6][“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?

I think I got it. I did away with storing my cell data in a hash; rather
I will put an array in each cell of the 2D array, and add another
parameter to the def [] and def []= methods to access it.

Forgive me, but this looks like you’re just being too lazy, and your
code’s starting to really suffer. Instead of trying to make it work no
matter how much stuff you throw at the array, start checking to make
sure that you’re not doing something illegal or irrational before trying
to do it.

a[3,3,2]
=> “-”

a[4,3,2]
=> nil

Because a[5,1] is out of bounds

So

a[3,3,2]=“Q”
=>“Q”

a[4,3,2]=“Q”
=> undefined method `[]=’ for nil:NilClass (NoMethodError)

Because that’s like saying
nil=“Q”

One way you could check would be
@world[m,n,1][“hex_id_A”] = "H " if @world[m,n,1]

Or, to put it in context:

def insert_teleporting_square
m = rand(@cols)
n = rand(@rows)
(0…8).each {|index| @world[m,n,index][“hex_id_A”] = "A " if
@world[m,n,index]}
(1…3).each {|index| @world[m,n,index][“hex_id_A”] = "H " if
@world[m,n,index]}
end

Here’s another way:

class HexArray
def neighbors(x,y)
(1…6).collect{|index| index if self[x,y,index]}.compact
end
end

a = HexArray.new(5,5)
a.neighbors(2,2)
=> [1, 2, 3, 4, 5, 6]

a.neighbors(4,4)
=> [1, 5, 6]

a.neighbors(2,2).each{|n| a[2,2,n]=“x”}
=> [1, 2, 3, 4, 5, 6]

a.neighbors(4,4).each{|n| a[4,4,n]=“y”}
=> [1, 5, 6]

a


  • x x - -
  • x - x -
  • x x y y
      • y -