[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

New to ruby--trouble with initializing arrays

vanjac12

11/29/2003 3:48:00 AM

I am writing a practice program; the Game of Life. Naturally I am having troubles.

This will probably be elementary those with experience in programming with ruby,
so please tell me the right place to post such questions if this is not the place.

The program is not running as I think it should.

I think it may be due to the way I set up the arrays, so that many elements refer to
the same element, and then later in the program when they should be different
they remain the same.

Is this a likely mistake?

This is what I think is causing me problems right now.
I had written
a[1] = a[7] = a[0] = 0 , where a is an array of arrays

My "gameboard" a was 8 x 8, updated by the rules

# If a cell is off and has 3 living neighbors (out of 8), it will become alive
# in the next generation.
# If a cell is on and has 2 or 3 living neighbors, it survives; otherwise, it
# dies in the next generation. Otherwise no change.

I store new values in an 8 x 8 array of arrays b, and then after calculating the new
state b, I dump it into a.
My problem was for some reason I couldn't update a correctly, even after printing
out everything in site to trace down where thing went wrong.
The way the initialization is set up is about all that is left, unless I overlooked
something else, which is quite possible.

Here is a portion of a letter to a friend ( who I have imposed on too much already).
============

> Beware the tempting
>
> a[1] = Array.new( a[0].size, 0 )
> a[5] = Array.new( a[0].size, 0 )
>
> because although it works correctly in this case, if you were
> initializing using some object other than a literal value, you could be
> in for some even more surprising behavior, as the initialization being
> performed in this case is that all the array elements are references to
> the same object. Thus if you had
>
> b = Array.new
> b[1] = Array.new( a[0].size, a[0] )
>
> then whenever you changed the state of a[0], you would change the state
> of every element of b[1]!
=================

Even if you changed a[0] later on in the program?

What about this;

0.upto( nn-1 ) do |i|
a[i] = Array.new( nn, 0 )
b[i] = Array.new( nn, 0 )
end

I see from the manual that this causes every element of a[i]
to refer to the same element, 0, and the same for b[i].

Can this mean that the elements of a[i] can never be different?

You say that with the assignment = , I can make a[i] = anything,
but again, can this mean that the elements of a[i] can never be different?

I am a bit confused.

a[1] = a[0].clone
a[5] = a[0].clone

means that a[0].clone labels a different but identical object
from a[0]. Right? Thus a[1] does not label the same object as a[0].

Here is my program, not very well written--it will be hard to make out,
I should have fixed it up first, but ...

===========
# 0 = off = white ; 1 = on = black = X
# if a[i][j] == 0 print ' '
# else print 'X'
# end

# Size of grid;

nn = 8
nnm = nn - 1
nmm = nnm - 1

# Create and Initialize Grid a

a = Array.new
b = Array.new
0.upto( nnm ) do |i|
a[i] = Array.new( nn )
b[i] = Array.new( nn )
a[i].fill(0)
b[i].fill(0)
end

# Initial state
a[3][2] = 1
a[3][3] = 1
a[3][4] = 1
a[3][5] = 1

0.upto( nnm ) do |i|
print a[i]
puts ""
end
puts ""

# Apply rules to set a[i][j] = 0 or 1
# If a cell is off and has 3 living neighbors (out of 8), it will become alive
# in the next generation.
# If a cell is on and has 2 or 3 living neighbors, it survives; otherwise, it
# dies in the next generation. Otherwise no change.

b[0] = a[0]
b[nnm] = a[nnm]
1.upto( nmm ) do |i|
b[i][0] = a[i][0]
b[i][nnm] = a[i][nnm]
end

1.upto( 10 ) do |k|

1.upto( nmm ) do |i|
1.upto( nmm ) do |j|

# count n = number of black cells around [i][j]

n = a[i-1][j-1] + a[i-1][j] + a[i-1][j+1] + a[i][j-1] + a[i][j+1] + a[i+1][j-1] + a[i+1][j] + a[i+1][j+1]

if n == 3 then b[i][j] = 1
elsif (a[i][j] == 1 and n == 2) then b[i][j] = 1
else b[i][j] = 0
end
print i, " ", j, " ", n, "\n"
print a[i][j], " ", b[i][j], "\n"
end
puts ""
end
puts ""

# set a = b ; b is the new configuration

0.upto( nnm ) do |i|
a[i] = b[i]
print a[i]
puts ""
end
puts ""

0.upto( nnm ) do |i|
0.upto( nnm ) do |j|
if (a[i][j] == 0) then print ' '
else print 'X'
end
end
puts ""
end
print " "
puts k
end
4 Answers

Gavin Sinclair

11/29/2003 4:35:00 AM

0

On Saturday, November 29, 2003, 2:52:11 PM, Van wrote:

> I am writing a practice program; the Game of Life. Naturally I am having troubles.

> This will probably be elementary those with experience in programming with ruby,
> so please tell me the right place to post such questions if this is not the place.

This place is fine, but the text was a bit long for my taste. If you
can break the problem down to a simpler program, then it will be
easier to diagnose.

> [...]

Cheers,
Gavin



Robert Klemme

12/1/2003 8:10:00 AM

0


"Van Jacques" <vanjac12@yahoo.com> schrieb im Newsbeitrag
news:70ae81fd.0311281947.909cec1@posting.google.com...
> I am writing a practice program; the Game of Life. Naturally I am having
troubles.
>
> This will probably be elementary those with experience in programming
with ruby,
> so please tell me the right place to post such questions if this is not
the place.
>
> The program is not running as I think it should.
>
> I think it may be due to the way I set up the arrays, so that many
elements refer to
> the same element, and then later in the program when they should be
different
> they remain the same.

Does this help:

class Board
def initialize(size=8)
@size = 8
@values = Array.new( size * size, 0 )
end

def [](x,y)
@values[x*@size+y]
end

def []=(x,y,v)
@values[x*@size+y]=v
end
end

board = Board.new
tmp = board.dup
# manipulate tmp
board = tmp

If you store something other than integers in the cells you could add this
method:

dup
copy = super
copy.instance_eval {@values.map! {|v| v.dup } }
copy
end

Cheers

robert

Robert Klemme

12/1/2003 1:33:00 PM

0


"Robert Klemme" <bob.news@gmx.net> schrieb im Newsbeitrag
news:bqet0g$21995e$1@ID-52924.news.uni-berlin.de...
>
> "Van Jacques" <vanjac12@yahoo.com> schrieb im Newsbeitrag
> news:70ae81fd.0311281947.909cec1@posting.google.com...
> > I am writing a practice program; the Game of Life. Naturally I am
having
> troubles.
> >
> > This will probably be elementary those with experience in programming
> with ruby,
> > so please tell me the right place to post such questions if this is
not
> the place.
> >
> > The program is not running as I think it should.
> >
> > I think it may be due to the way I set up the arrays, so that many
> elements refer to
> > the same element, and then later in the program when they should be
> different
> > they remain the same.
>
> Does this help:

Slightly improved to tackle the borders.

class Board
def initialize(size=8)
@size = 8
@values = Array.new( size * size, 0 )
end

def [](x,y)
@values[pos(x,y)]=v
end

def []=(x,y,v)
@values[pos(x,y)]=v
end

protected
def pos(x,y)
( x % @size ) * @size + ( y % @size )
end
end

> board = Board.new
> tmp = board.dup
> # manipulate tmp
> board = tmp

robert

vanjac12

12/2/2003 9:55:00 PM

0

"Robert Klemme" <bob.news@gmx.net> wrote in message news:<bqffva$22171v$1@ID-52924.news.uni-berlin.de>...
> >
> > Does this help:
>
> Slightly improved to tackle the borders.
>
> class Board
> def initialize(size=8)
> @size = 8
> @values = Array.new( size * size, 0 )
> end
>
> def [](x,y)
> @values[pos(x,y)]=v
> end
>
> def []=(x,y,v)
> @values[pos(x,y)]=v
> end
>
> protected
> def pos(x,y)
> ( x % @size ) * @size + ( y % @size )
> end
> end
>
> > board = Board.new
> > tmp = board.dup
> > # manipulate tmp
> > board = tmp
>
> robert

This is much more sophiscated than my program (with help from another
poster in a similar thread here in comp.lang.ruby), but I used the

row % size

method for dealing with the edges also. The following initial configuration
goes a long time before oscillating (I think), and I recommend running it
for anyone who is interested.

As a beginner, I'm not used to defining my own classes or def statements,
but that will come with time--I hope :-)
===========

NN = 20 ; N = NN - 1
n_steps = 100

tos = Array.new
tng = Array.new

0.upto(N) { |row|
tos[row] = Array.new(NN, 0)
tng[row] = Array.new(NN, 0)
}


tos[4][4] = tos[5][6] = tos[6][3] = tos[6][4] = 1
tos[6][7] = tos[6][8] = tos[6][9] = 1

0.upto(N) do |row|
print tos[row], "\n"
end
puts

1.upto(n_steps) do |generation|
0.upto(N) do |row|
0.upto(N) do |column|
neighbors = 0
-1.upto(1) do |row_offset|
-1.upto(1) do |column_offset|
unless row_offset == 0 and column_offset == 0
i = (row+row_offset) % NN
j = (column+column_offset) % NN
neighbors += tos[i][j]
end
end
end
if tos[row][column] == 0
tng[row][column] = (neighbors == 3) ? 1 : 0
else
tng[row][column] = (neighbors == 2 or neighbors == 3) ? 1 : 0
end
end
end

0.upto(N) do |row|
0.upto(N) do |column|
tos[row][column] = tng[row][column]
end
print tos[row], "\n"
end
puts
puts generation
puts

0.upto(N) do |row|
0.upto(N) do |column|
print (tos[row][column] == 0 ? ' ' : 'X')
end
puts
end
end
#done