OK, let's try this from the top. {grin} Here's some fresh new code:

class HexArray
=09
Delta=3D[[0,0], [0.5,-1], [1,0], [0.5,1], [-0.5,1], =
[-1,0], [-0.5,-1]]
=09
def initialize(width, height, default=3D"-")
@width =3D width
@height =3D height
@data =3D Array.new(@width){|row| [default] * =
@height}
end
=09
def [](x, y, z)
col, row =3D move(x,y,z)
@data[row][col] unless (row<0 or =
row>(@height-1))
end
=09
def []=3D(x, y, z, value)
col, row =3D move(x,y,z)
@data[row][col] =3D value unless (row<0 or =
row>(@height-1))
end
=09
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 =3D Delta[z]
[(x + deltaX + 0.25 + (0.5 * (y%2)) % =
@width).floor, y + deltaY]
end
=09
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.=20

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  =
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.=20

Let's take it for a spin.

>> a=3DHexArray.new(5,5)
-   -   -   -   -
-   -   -   -   -
-   -   -   -   -
-   -   -   -   -
-   -   -   -   -
=3D>=20
>> a[0,0,0] =3D "A" # upper left
=3D> "A"
>> a[4,4,0] =3D "Z" # lower right
=3D> "Z"
>> a[0,2,0] =3D "J" # center left
=3D> "J"
>> a[2,0,0] =3D "S" # center top
=3D> "S"
>> a[0,2,2] =3D "K" # right of J
=3D> "K"
>> a[2,0,3] =3D "T" # below S and to the right
=3D> "T"
>> a[0,2,5] =3D "I" # left of J (should wrap)
=3D> "I"
>> a[2,0,1] =3D "R" # above & right of S (should be ignored)
=3D> "R"
>> a[4,4,4] =3D "X" # below and left of Z (should be ignored)
=3D> "X"
>> a
A   -   S   -   -
-   -   T   -   -
J   K   -   -   I
-   -   -   -   -
-   -   -   -   Z
=3D>=20

>> a[0,2,4] =3D "M" # left and below J (should wrap)
=3D> "M"
>> a
A   -   S   -   -
-   -   T   -   -
J   K   -   -   I
-   -   -   -   M
-   -   -   -   Z
=3D>=20
>>=20
?> a[4,2,0]    #should be position "I"
=3D> "I"
>> a[4,2,3] =3D "N" # right and below "I", should overwrite "M"
=3D> "N"
>> a
A   -   S   -   -
-   -   T   -   -
J   K   -   -   I
-   -   -   -   N
-   -   -   -   Z
=3D>=20

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 =3D Array2D(5,5,"*")
or=20
a =3D Array2D(5,5,nil)

=09=