0

I am writing a mastermind game in Ruby. So far I have the code located here on github.

The problem I am running into is this: when I run the function below, the instance variable @code which is generated at the beginning of the game returns empty after the first run of the function.

I have assigned a local variable, tempcode, the value of @code, and all the operations are done to tempcode within the function. I have also assigned an attr_reader to @code, instead of an attr_accessor. So @code shouldn't change!

def compare_guess_to_code()
        correct_color = "1"
        correct_color_and_pos = "2"
        incorrect_color = "0"
        tempcode = @code
        a = 0
        @guess.length.times do #maybe a for loop that goes through both arrays simultaneously?
            case
            when @guess[a] == tempcode[a]
                feedback.push(correct_color_and_pos)
                tempcode.delete_at[a]
                @guess.delete_at[a]
            when guess[a] != tempcode[a]  && tempcode.include?(guess[a])
                feedback.push(correct_color)
                tempcode.delete_at[a]
                @guess.delete_at[a]
            when !(tempcode.include?(guess[a]))             
                feedback.push(incorrect_color)
                tempcode.delete_at[a]
                @guess.delete_at[a]
            else
                puts "Error"
            end             
        end
        feedback.sort!
        feedback.reverse!
        print "Feedback: #{feedback}"

    end

The feedback returns properly, everything seems to be working fine, I just can't do the comparison function more than one time before @code empties out. How can I hold the value consistent?

If you want to run the program to test it, use mastermind/lib/mastermind.rb.

Will Wilson
  • 335
  • 2
  • 9

2 Answers2

0

You assign array tempcode = @code and modify it with tempcode.delete_at[a] which will change @code as well. To fix it, you can use

tempcode = @code.clone

This way @code won't be affected by tempcode's change

Vu Minh Tan
  • 526
  • 4
  • 6
  • Thank you, this works, but why? My understanding of variables is that if you do a = 8 b = a a = "eight" b will return 8 So why the difference here? – Will Wilson Dec 08 '14 at 03:50
  • what happen is that variable only store the reference to the object, not the object itself. Here code and tempcode both point to the same array object, changing tempcode will update the object code points to. In your example, a point to 8, b = a => b points to 8 too, a = "eight" => a now points to "eight" and b still points to 8. – Vu Minh Tan Dec 08 '14 at 04:21
  • Thanks for this. Can you suggest some reading on this? None of the texts or tutorials I have taken so far mention this behavior. – Will Wilson Dec 11 '14 at 23:10
  • I think this illustrate quite well about it http://stackoverflow.com/questions/1872110/is-ruby-pass-by-reference-or-by-value I can't find any other tutorials, I know about it from my experience with Java actually – Vu Minh Tan Dec 12 '14 at 02:58
0

when you assign one array it just copies the reference and both of them point to the same reference. so a change in one is reflected when you print either of them.

orig_array = [1,2,3,4]<br>
another_array = orig_array

puts orig_array.unshift(0).inspect
puts another_array.inspect

Output:

[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]

To avoid this you can use Marshal to copy from original array without impacting the object to which it is copied. Any changes in the original array will not change the object to which it is copied.

orig_array = [1,2,3,4]<br>
another_array = Marshal.load(Marshal.dump(orig_array))

puts orig_array.unshift(0).inspect
puts another_array.inspect

Output:

[0, 1, 2, 3, 4]
[1, 2, 3, 4]