1

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
Pixelz
  • 171
  • 1
  • 2
  • 8
  • FYI: It makes no sense to set `crack1 = pass1` inside a test for `if crack1 == pass1`. If they're already equal, making them equal again doesn't do anything. – user229044 Jun 01 '17 at 00:59
  • You may want to use arrays instead of variable names with incrementing numbers. For example, `pass = [4,9,2,8]` and refer to them as `pass[0]` through `pass[3]`. – Mark Thomas Jun 01 '17 at 01:01

1 Answers1

1

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.

Gerry
  • 10,337
  • 3
  • 31
  • 40