Search code examples
rubyvariablesif-statementrandomputs

Ruby wont print variable


I've been trying to work on a fake little pin-cracking script, but somethings wrong and it's making me frustrated. It randomizes 4 numbers and checks them against 4 other numbers, but for some reason, after the numbers are guessed, it won't print them anymore.

#RubyCodeStart

pass1 = 4
pass2 = 9
pass3 = 2
pass4 = 8
guess = 0
flag1 = 0
flag2 = 0
flag3 = 0
flag4 = 0
loop do
    if flag1 == 0
        crack1 = rand(0..9)
    end
    if flag2 == 0
        crack2 = rand(0..9)
    end
    if flag3 == 0
        crack3 = rand(0..9)
    end
    if flag4 == 0
        crack4 = rand(0..9)
    end
    if crack1 == pass1
        crack1 = pass1
        flag1 = 1
    end
    if crack2 == pass2
        crack2 = pass2
        flag2 = 1
    end
    if crack3 == pass3
        crack3 = pass3
        flag3 = 1
    end
    if crack4 == pass4
        crack4 = pass4
        flag4 = 1
    end
    guess += 1
    puts "#{crack1} \| #{crack2} \| #{crack3} \| #{crack4} === Guess \# #{guess}"
#   if crack == pass
#       break
#   end
end
sleep(30)

Nothing I do works, and it refuses to print it pass it being found. I'll add data if needed.

Output:

8 | 0 | 6 | 1 === Guess # 1
4 | 6 | 1 | 8 === Guess # 2
 | 1 | 3 |  === Guess # 3
 | 1 | 5 |  === Guess # 4
 | 3 | 9 |  === Guess # 5
 | 3 | 3 |  === Guess # 6
 | 5 | 4 |  === Guess # 7
 | 3 | 4 |  === Guess # 8
 | 4 | 3 |  === Guess # 9
 | 0 | 6 |  === Guess # 10
 | 3 | 8 |  === Guess # 11
 | 4 | 5 |  === Guess # 12
 | 2 | 4 |  === Guess # 13
 | 8 | 7 |  === Guess # 14
 | 8 | 4 |  === Guess # 15
 | 9 | 5 |  === Guess # 16
 |  | 7 |  === Guess # 17
 |  | 5 |  === Guess # 18
 |  | 7 |  === Guess # 19
 |  | 7 |  === Guess # 20
 |  | 7 |  === Guess # 21
 |  | 1 |  === Guess # 22
 |  | 2 |  === Guess # 23
 |  |  |  === Guess # 24
 |  |  |  === Guess # 25
 |  |  |  === Guess # 26
 |  |  |  === Guess # 27
 |  |  |  === Guess # 28
 |  |  |  === Guess # 29
 |  |  |  === Guess # 30
 |  |  |  === Guess # 31
 |  |  |  === Guess # 32
 |  |  |  === Guess # 33
 |  |  |  === Guess # 34
 |  |  |  === Guess # 35
 |  |  |  === Guess # 36
 |  |  |  === Guess # 37
 |  |  |  === Guess # 38
 |  |  |  === Guess # 39
 |  |  |  === Guess # 40

Solution

  • You need to declare your crack variables outside your loop:

    # other variables
    
    crack1 = 0
    crack2 = 0
    crack3 = 0
    crack4 = 0
    
    loop do
        # loop code
    end
    

    Why your code was not working?

    Because in each loop, al crack variables get wiped out, because of their original scope. On every iteration, each crack variable is set to either rand(0..9) or nil.

    So, after

    if flag1 == 0
      crack1 = rand(0..9)
    end
    

    crack1 will be set to some random number, and thus you will be able to print its value later on, but once flag1 is not 0, then crack1 will be set to nil.


    Taking into account the comments on your question (and adding some other tips), here's one option that will DRY your code a bit:

    pass   = [4, 9, 2, 8]
    flag   = [0, 0, 0, 0]
    crack  = [0, 0, 0, 0]
    guess  = 0
    
    until crack == pass do
      (0..3).each do |i|
        crack[i] = rand(0..9) if flag[i] == 0
        flag[i] = 1 if crack[i] == pass[i]
      end
    
      guess += 1
      puts "#{crack.join(" | ")} === Guess \# #{guess}"
    end
    

    This creates the exact same output, except that it exits the loop once the password has been cracked.