Russian Roulette, Reloaded

Ruby, 51 bytes

[*['*click*']*rand(6),'*BANG!*'].map{|x|gets;$><<x}

Ungolfed:

[
  *(                        # Unwrap the following array into the outer one
    ['*click*'] * rand(6)   # An array of 0-5 clicks, see Array#*
  ),
  '*BANG!*'                 # The End
].map do |x| # Shortest way to iterate I was able to find
  gets       # Await input
  $> << x    # Shove the output string to `stdout`
end          # Return value is an array of several (0-5) `stdout`s. Who cares.

or

(['*click*']*rand(6)<<'*BANG!*').map{|x|gets;$><<x}

Ungolfing left for the readers. Not that difficult

  • Again, kudos to Martin, this time for a trick with $><< as a puts replacement.
  • Doesn't output newlines, but that was not required.
  • The shorter, the simpler. The gist of the required behaviour is to do 0-5 clicks and then fire. For that, outputs are accumulated inside the array.
  • 2 more bytes can be shaved off if outputs like "*click*" are okay (what's required is printed in the end), by replacing $><< with . I wasn't sure if this would still follow the rules.

68 64 bytes

(another approach)

[*0..5].shuffle.find{|x|gets;x<1||puts('*click*')};puts'*BANG!*'
  • Kudos to Martin Büttner for -4 extra bytes.

I didn't put much thought into the algorithm (it can possibly be even more compact, but not so clear), but I really like the model inside it:

  • An array emulates a barrel with its elements being chambers' contents. Since only one element is a bullet, rotating it and shuffling it are equivalent.
  • 0 is a bullet. Other numbers are not.
  • find finds a first return value for which the block is neither false nor nil.
  • ||-expression is implicitly returned from the block. It's a short-circuit: it returns its first operand (unless it's nil or false) or a second one (otherwise). So it either returns true (if x<1 or, clearer but longer x == 0) or the return value of puts, while...
  • puts always returns nil. Yep.
  • gets requests input. Merely hitting Enter suffices.
  • Ctrl+C terminates the program

JavaScript, 64 bytes

for(i=6;i<7&&prompt();)alert(new Date%i--?"*click*":i="*BANG!*")

Explanation

To pull the trigger enter any text into the prompt. Enter nothing or click cancel to terminate.

for(
  i=6;             // i = number of chambers
  i<7              // i equals "*BANG!*" (not less than 7) if we lost
    &&prompt();    // see if we should do another shot
)
  alert(           // alert the result
    new Date%i--   // use the current time in milliseconds as a random number, this is safe
                   //     to use because the gap between shots is greater than i (max 6ms)
      ?"*click*"   // on win pass "*click*" to alert
      :i="*BANG!*" // on lose alert "*BANG!*" and set i to not less than 7
  )

Lua, 82 75 bytes

Pretty long, but there's lot of verbose in lua.

for a=math.random(6),1,-1 do io.read()print(a>1 and"*click*"or"*BANG!*")end