From: vanjac12@... (Van Jacques) Date: 2003-11-29T12:52:11+09:00 Subject: New to ruby--trouble with initializing arrays 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