0

I'm trying to make a loop that when the random number matches the same index of the input the value is changed and stays that way for each following loop.

input = gets.chomp
tries_left = 12
while(tries_left > 0)
tries_left -= 1
computer = 4.times.map do rand(0..6) end.join

  if computer[0] == input[0]
    computer[0] = input[0]
 end
end

in the code above after the first loop the value stored to input[0] resets.

computer = 4.times.map do rand(0..6) end.join
 input = gets.chomp
  tries_left = 12
    while(tries_left > 0)
    tries_left -= 1

      if computer[0] == input[0]
        computer[0] = input[0]
     end

if I take computer out of the loop like this, it will have the same random number generated each time. Once again I need it to generate new numbers each time besides what was already a match.

Jacob Moore
  • 277
  • 2
  • 12
  • This seems to be a code guessing game. What is the above code supposed to do? What works and what does not work? Can you show an example session with user input and expected output? – Stefan Aug 11 '17 at 07:59

2 Answers2

1

It’s not quite clear what you are trying to accomplish, but this:

if computer[0] == input[0]
  computer[0] = input[0]
end

is obviously a noop. Nothing gets updated, since the computer[0], whatever it is, is being set to the same value it was. I believe you wanted to somehow use an index in the array:

4.times.map do |index|
  value = rand(0..6)
  # somehow check the similarity, e.g.:
  if input[index] == value
    # do something
  end
end

I beg your pardon for the very vague answer, but it is really hard to understand the goal you are trying to achieve.

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
1

If you make the computer an array of strings, you can freeze it to prevent further modifications to it, and then replace the contents in computer when it doesn't match the index:

input = gets.chomp
tries_left = 12

computer = Array.new(4) { '' }
# setting the srand to 1234, the next 48 calls to 'rand(0..6)' will always
# result in the following sequence:
# 3, 6, 5, 4, 4, 0, 1, 1, 1, 2, 6, 3, 6, 4, 4, 2, 6, 2, 0, 0, 4, 5, 0, 1,
# 6, 6, 2, 0, 3, 4, 5, 2, 6, 2, 3, 3, 0, 1, 3, 0, 3, 2, 3, 4, 1, 3, 3, 3
# this is useful for testing things are working correctly,
# but take it out for 'live' code
srand 1234
while tries_left > 0
  # no need to keep iterating if we've generated all the correct values
  if computer.all?(&:frozen?)
    puts "won #{computer.inspect} in #{12 - tries_left} tries"
    break
  end

  tries_left -= 1
  computer.each.with_index do |random, index|
    # generate a new random number here unless they guessed correctly previously
    random.replace(rand(0..6).to_s) unless random.frozen?

    # if they've guessed the new random number, mark the string so they we
    # don't update it
    random.freeze if random == input[index]
  end

  puts "#{computer.inspect} has #{computer.count(&:frozen?)} correct numbers"
end

and then when you run the script:

$ echo 3654 | ruby example.rb 
# ["3", "6", "5", "4"] has 4 correct numbers
# won ["3", "6", "5", "4"] in 1 tries
$ echo 3644 | ruby example.rb 
# ["3", "6", "5", "4"] has 3 correct numbers
# ["3", "6", "4", "4"] has 4 correct numbers
# won ["3", "6", "4", "4"] in 2 tries
$ echo 3555 | ruby example.rb 
# ["3", "6", "5", "4"] has 2 correct numbers
# ["3", "4", "5", "0"] has 2 correct numbers
# ["3", "1", "5", "1"] has 2 correct numbers
# ["3", "1", "5", "2"] has 2 correct numbers
# ["3", "6", "5", "3"] has 2 correct numbers
# ["3", "6", "5", "4"] has 2 correct numbers
# ["3", "4", "5", "2"] has 2 correct numbers
# ["3", "6", "5", "2"] has 2 correct numbers
# ["3", "0", "5", "0"] has 2 correct numbers
# ["3", "4", "5", "5"] has 3 correct numbers
# ["3", "0", "5", "5"] has 3 correct numbers
# ["3", "1", "5", "5"] has 3 correct numbers
Simple Lime
  • 10,790
  • 2
  • 17
  • 32
  • Awesome, exactly what I was looking for. I may figure it out before you get a chance to answer, but now I'm trying to add a counter += 1 for each element that's frozen one time. Can I also use freeze in this situation also? In other words I'm trying to have something like "Correct numbers: 2" or whatever the amount is after each iteration. – Jacob Moore Aug 11 '17 at 22:46
  • You can just [`count`](https://ruby-doc.org/core-2.4.0/Array.html#method-i-count) the number of frozen elements (`computer.count(&:frozen?)`) or just move the `if random == input[index]` into a full blown block instead of a single line if statement and increment a counter inside that block – Simple Lime Aug 11 '17 at 22:57
  • Last question. Why does (&:frozen) have the ":"? : is a constant right? I don't understand what it is doing. – Jacob Moore Aug 11 '17 at 23:01
  • [This question](https://stackoverflow.com/a/1217114/8255744) seems to do a decent job of explaining it – Simple Lime Aug 11 '17 at 23:09