Let's play Russian Roulette!

Normally, this would be a race to write the shortest MOD 6 program, but that's not very realistic, as the chance of winning decreases with each click. Here are the rules:

1. Emulate a real six-shooter:
• A single bullet is placed into one of the six chambers, and the barrel is spun once, only before playing.
• The chance of losing on the nth try is 1/6.
• The chance of losing after n tries is 1/(6-n)
• You are guaranteed to lose in, at most, 6 tries.
2. Losing:
• Display the text *BANG!*
• Terminate the program.
3. Winning:
• "Winning" means the gun does not fire, but the bullet is one chamber closer to the hammer.
• Display the text *click*
• Present a "trigger" to the user, along with the ability to terminate the program (e.g. "ctrl+c", see below).
4. Program specific:
• Pulling the trigger is some form of user input, including the first try. (This can be a keystroke, a mouse click, whatever; text prompts are not required.)
• Only one instance of the program is allowed until it is terminated. (Running a new instance of the program is akin to giving the barrel a good spin, i.e. the probability of losing on the next click is reset to 1/6.)

Shortest code wins!

• Your assumptions are wrong - the chance of losing on the n'th try is only ⅙ if you respin the bullets after each shot. Without respinning the chance of losing is ⅙ on the first shot, ⅕ on the second, ¼ on the third... ending in 1 on the 6th. You recognise this with "You are guaranteed to lose in, at most, 6 tries". Dec 16, 2015 at 21:52
• @user2956063 you are forgetting that there is a (n-1)/6 chance that you never reach the n:th try, and thus cannot lose. They balance out to a uniform 1/6. Dec 17, 2015 at 10:26
• maybe that's a difference in the way computer scientists and statisticians express probability then - to me "The chance of losing on the nth try is ⅙" say's it's constant - whether n is 1 or 100. Dec 17, 2015 at 11:53
• @user2956063: Your probabilities are conditional. P(lose on shot 2) = ⅙, but P(lose on shot 2 | didn't lose on shot 1) = ⅕. Also, n is (implicitly, I'll grant you) limited to [1,6], so 100 is out. Dec 19, 2015 at 5:04

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) stdouts. 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!*' 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 • Crossed out 64 is normal 64? Dec 18, 2015 at 5:06 • @Cyoce uhm... yes. Should be, probably. It's been superceded by the above entry, but it is based on a different idea, so I left them, crossed out. Dec 18, 2015 at 7:51 • it was a pun on this Dec 19, 2015 at 7:22 • @Cyoce oh, pardon me, first post and all that, not aware of the local lore :) Dec 19, 2015 at 21:27 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 ) • "*Bang!*" is not greater than 7. But NaN is not smaller than 7. Dec 16, 2015 at 12:38 • @Bergi That's true. I reworded the explanation to make it a bit clearer. Dec 16, 2015 at 12:43 • @Bergi only in Javascript does that statement come even close to making sense. Dec 16, 2015 at 16:03 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 LabVIEW, 46 LabVIEW Primitives Creates an Array of 0s and one 1, has a loop to wait for clicks and outputs the string. It initially says BANG becuase i forgot to reset the indicator before starting it. Also note that this is a gif, if if does not play/load for you please reopen the page. • I don't see where you do the output of "*click*" in case the gun didn't shoot. Also, does it output "bang" or "*BANG!*"? Dec 16, 2015 at 10:04 • this should be a gif but for me it doesnt play, that might be the problem. And yes it only puts bang, that was me not reading properly i change that in a sec Dec 16, 2015 at 10:15 • stupid me forgot to reinitialize the string to empty before starting so thats why it showes BANG at the start... Dec 16, 2015 at 10:25 • No problem, I saw the gif now, looks like it works pretty well :) Dec 16, 2015 at 10:26 Pyth, 3130 28 bytes FN.S6 EI!N"*BANG!*"B"*click* Almost certainly can be improved. Input any number to pull the trigger, blank input to terminate early (with an error). Explanation: FN for N in... .S6 shuffle(range(6))... E get a line of input I!N if N is falsy (i.e. 0) "*BANG!*" implicit output B break "*click* else, print click • Your first one is actually shorter, you don't need the trailing". Dec 16, 2015 at 14:06 • @FryAmTheEggman Oh, right, forgot about that. Thanks! Dec 16, 2015 at 14:31 • Also, I've just noticed something silly, FN<any> is still entirely identical to V<any>, that should probably be changed to not confuse new golfers... :P Dec 16, 2015 at 14:38 • You can simply remove the chars .?. There is no need for an else. Dec 16, 2015 at 17:57 • @FryAmTheEggman confusing people is awesome. It can be amazing at filtering out the scrubs. Dec 18, 2015 at 8:40 Seriously, 27 25 bytes "*BANG!*"6J"*click*"nW,X. No online link because there is no way to do a prompt with piped input. The program can be CTRL-C'd at any time to chicken out terminate. Explanation: "*BANG!*"6J"*click*"nW,X. "*BANG!*" push "*BANG!*" 6J push a random integer in [0,6) (n) "*click*"n push "*click*" n times W while loop (implicitly closed at EOF): ,X. get input and discard, pop and print top of stack Pyth, 23 bytes VO6"*click*" w;"*BANG!* Really simple. A random number of iterations 0 - 5 display click and request a line of input, followed by a bang at the end. • damn you, pyth! Dec 18, 2015 at 1:55 • +3 bytes: the last string should be *BANG!*, not BANG Dec 18, 2015 at 5:34 PHP, 52 bytes *<?=$n=&rand(0,6-$argi)?click:"BANG!*";$n||@\n?>*

Requires the -F command line option, counted as three. The trigger is pulled by pressing Enter.

Because -F literally runs the script again for every input (I kid you not), die and the like won't actually terminate, so we exit via suppressed runtime error instead, @\n.

Sample Usage

$php -F primo-roulette.php *click* *click* *BANG!*$

Perl 5, 43 bytes

Run with perl -p. Stable bullet variant - i.e. bullet position is decided only once in very beginning.

$i//=0|rand 6;$_=$i--?'*click*':die'*BANG*' • Nice! I would change the header to "Perl 5.10+", since you're using //=. Also, don't forget to count -p in your score. Dec 17, 2015 at 4:46 C, 11074 72 bytes Thanks to Dennis for getting rid of the includes and a lot less bytes. main(r){for(r=time(0)%6;getchar(),r--;)puts("*click*");puts("*BANG!*");} main(r) { for(r=time(0)%6;getchar(),r--;) puts("*click*"); puts("*BANG!*"); } Candy, 36 bytes About half the program is the text to print out :( :6H_(=b"*click*"(;):=)"*BANG!*\n"(;) long form: getc digit6 rand range0 # build a range from 0 .. rand# while popA # these are the *click* instances stack2 "*click*" while printChr endwhile getc popA endwhile "*BANG!*\n" # out of luck while printChr endwhile Python, 81 Bytes import time for i in["*click*"]*(int(time.time())%6)+["*BANG!*"]:input();print(i) inspired by the Ruby(51) and Python solutions PlatyPar, 26 25 bytes 6#?;wT"*click*"O;"*BANG!* Explanation: 6#?; ## random integer [0,6) w ; ## while stack.last T ## stack.last-- "*click*"O ## alert "*click*" "*BANG!* ## alert "*BANG!*" Emacs Lisp, 94 89 bytes (set'b(%(random)6))(dotimes(a(+ b 1))(read-string"")(message(if(eq a b)"BANG""*click*"))) Ungolfed: (set 'b (% (random) 6)) (dotimes (a (+ b 1)) (read-string"") (message (if (eq a b) "BANG" "*click*"))) R, 8680 77 bytes As usual, R has awesome features to code golfing but looooooong function names. sapply(sample(0:5),function(n){!n&&{cat('*BANG!*');q()};readline('*click*')}) Python 2, 108104102100 98 bytes My first attempt at golfing: from random import* a=[1]+[0]*5 shuffle(a) for i in a:input();print("*click*","*BANG!*")[i];" "[i] Maybe I should add that the program doesn't terminate correctly when you lose, it just throws an exception (which results in termination): Traceback (most recent call last): File "russian_roulette.py", line 4, in <module> for i in a:input();print("*click*","*BANG!*")[i];" "[i] IndexError: string index out of range • Welcome to Programming Puzzles & Code Golf! When you post a code golf answer, please include the language name and the byte count (I edited it in for you here). Thanks! Dec 16, 2015 at 16:58 • Yes, thanks a lot! I was actually trying to resolve that issue, didn't get to edit it correctly before you did. Dec 16, 2015 at 17:02 • I get your byte count as 112, what did you use? Dec 16, 2015 at 17:22 • Also, you can save 2 bytes by doing a=shuffle([1,0,0,0,0,0]) Dec 16, 2015 at 17:22 • As far as I know shuffle changes the underlying data structure and doesn't return anything. I tried that, thanks anyways. The headline (language and byte count) was written by ProgramFOX. But when I use wc it gives me 109 which one too much, so it's right. How do you count? Dec 16, 2015 at 17:33 Python 3, 95 bytes Also my first golf attempt, also in Python 3. I swear Bruce and I aren't the same person. from random import* for a in range(randint(0,5)):input();print("*click*") input();print("*bang*") Ungolfed: from random import* for a in range(randint(0,5)): input() print("*click*") input() print("*bang*") Generate a random number between 0 and 5 inclusive, print click that many times, then print bang. Press enter/return to pull the trigger. • Following Bruce's example, you can save a few bytes with from random import* Dec 16, 2015 at 17:25 • Unless there's something else I'm missing, it's one byte of savings. But I'll take it! Thanks! Dec 16, 2015 at 17:30 • Nice attempt, I used your solution as an inspiration for my python 2 solution ^^ Dec 16, 2015 at 17:52 Perl 5, 40 bytes <>,print"*$_*"for(click)x rand 5,'BANG!'

Run without command line options, the trigger is pulled by pressing Enter.

C, 96 bytes (Without counting comment)

#define R 4//chosen by playing russian roulette, guaranteed to be random
int main(){for(;c++<R&&puts(c<R?"Fire?":"☠Bang!☠");getchar(),puts("*click*"));}

Formatted :

#define R 4 // chosen by playing russian roulette, guaranteed to be random
int main(int c) {
for( ; c++ < R && puts(c < R ? "Fire?" : "☠Bang!☠") ; getchar(), puts("*click*") );
}

Explanation :

There also is a click when it fires, that's the sound of the hammer being released.

After the bang you need to hit enter to take the gun out of the dead man's hand, rigor mortis squeezed his finger around the trigger. While you are prying his hand open you hear another click as the trigger snaps back into normal position.

Common Lisp, 109

(do(g(b(nthcdr(random 6)#1='(t()()()()() . #1#))))(g)(read-char)(princ(if(setf g(pop b))"*BANG!*""*click*")))

Not very competitive, but I like circular lists:

(do (;; auxiliary variable x
x
;; initialize infinite barrel, rotate randomly
(b (nthcdr (random 6) #1='(t()()()()() . #1#))))

;; we end the loop when x is T (a bullet is fired)
(x)

;; press enter to shoot

;; pop from b, which makes b advance down the list. The popped value
;; goes into x and is used to select the appropriate string for
;; printing.
(princ
(if (setf x(pop b))
"*BANG!*"
"*click*")))

Perl 5, 43 bytes

42 bytes + -p command line option. Just press enter to trigger.

$_=0|rand 7-$.<++$i?die"*BANG!*":"*click*" Thanks to Dom Hastings for his help! Original answer was 67 bytes:$i++;$a=$i>=int(rand(6));print$_=$a?'*BANG!*':'*click*';last if($a) • Actually the problem with -p was that it would exit before calling the last print statement, not sure why. I've tried it. Other than that, awesome suggestions, thanks! My knowledge continues to grow... Dec 16, 2015 at 13:21 • @DomHastings Also, unfortunately, for some reason the 0| trick didn't work as expected, but I did shave some bytes off of it, the print statement and the last statement like you suggested. How does it look now? Dec 16, 2015 at 13:29 • @DomHastings Damn, you are good. I recommend putting that as your own answer, since you definitely wrote a smaller program than I (you have 40 bytes compared to my original 67!) Dec 16, 2015 at 13:41 • I appreciate the explanation! Always happy to learn more of my favorite scripting language! I never even knew about the prefex incrementing, that's pretty awesome. Thanks :) Dec 16, 2015 at 13:50 • You're very welcome, glad to have helped! Dec 16, 2015 at 13:51 MATL, 41 bytes 6Yrj?t@=?'*BANG!*'DT.}'*click*'DT]}T.]]x To pull the trigger, input a non-empty string (such as 'try'). To terminate, input an empty string Examples In this case the trigger was pulled once and... bad luck: >> matl > 6Yrj?t@=?'*BANG!*'DT.}'*click*'DT]}T.]]x > > try *BANG!* In this case the user stopped (note the final empty input) after two lucky pulls: >> matl > 6Yrj?t@=?'*BANG!*'DT.}'*click*'DT]}T.]]x > > try *click* > try *click* > Explanation 6Yr % random avlue from 1 to 6  % do...while j % input string ? % if nonempty t % duplicate the orignal random value @ % loop iteration index = % are the equal? ? % if so '*BANG!*'D % display string T. % unconditional break } % else '*click*'D % display string T % true value, to go on with do...while loop ] % end if } % else T. % unconditional break ] % end ] % end x % delete original random value Perl 6, 58 53 bytes for ^6 .pick(*) {get;say <*BANG!* *click*>[?$_];!$_&&last} # 58 bytes$ perl6 -pe '$///=^6 .pick;$_=$/--??"*click*"!!say("BANG!")&&last' # 52+1= 53 bytes Press enter to pull the trigger, or ctrl+c to put it down. Python 2, 88 84 bytes This solution is inspired by the python 3 solutions already given. I chose python 2 to remove the print parenthesis even though this changes the behavior of input(). import time for i in[0]*int(time.time()%6)+[1]:input();print("*click*","*BANG!*")[i] • I am using modulo of the time as a random function (good enough for russian roulette) • the player input should be "i" then Enter (otherwise input() will throw an error), this trick relies on the fact that the input can be "whatever". Ruby, 45+1=46 Not as clever as D-side's but slightly shorter. With command-line flag p, run rand(7-$.)<1?(puts'*BANG*';exit):$_='*click*' The user can pull the trigger with return and leave with control-c. p causes the program to run in a loop, reading lines from STDIN and outputting$_. Each time it runs, it increments $.. So on the first run, it chooses a random positive integer less than 6, then 5, then 4, and so on. On the first 0, we output manually and exit, until then we output implicitly. (and now I notice that there's already a very similar Perl. Oh well.) Perl 5, 6951 49 bytes map{<>;print"*click*"}1..rand 6;<>;print"*BANG!*" There is probably some more golfing potential, I will look into this. Changes: • Saved 8 bytes by removing$l and some semicolons, and 10 bytes by changing <STDIN> to <>
• Saved 2 bytes thanks to Oleg V. Volkov
• 49: map{<>;print"*click*"}1..rand 6;<>;print"*BANG!*" Dec 16, 2015 at 21:17
• @OlegV.Volkov Thanks! I'll edit it in now. Dec 16, 2015 at 23:45

VBA, 126 bytes

Golf Version for Minimal Bytes

Sub S()
r=Int(5*Rnd())
e:
a=MsgBox("")
If a=1 Then: If i=r Then MsgBox "*BANG!*" Else: MsgBox "*click*": i=i+1: GoTo e
End Sub

Fun Version that Makes The Buttons more Clear for Increased User Acceptance.

Sub RR()
r = Int(5 * Rnd())
e:
a = MsgBox("Are you Feeling Lucky?", 4)
If a=6 Then: If i=r Then MsgBox "*BANG!*", 16 Else: MsgBox "*click*", 48: i=i+1: GoTo e
End Sub

Some Fun with Custom Forms and You could make a pretty Slick Game in VBA.

APL, 39/65 bytes

{⍞⊢↑⍵:⍞←'*BANG*'⋄∇1↓⍵⊣⍞←'*click*'}6=6?6

• What do the two byte counts mean?
– user45941
Dec 17, 2015 at 9:37

C, 180 Bytes

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(){srand(time(NULL));int r,i=6;while(i!=1){getchar();r=rand()%i;if(r){puts("CLICK");}else{puts("BANG");exit(0);}i--;}}

My first attempt at code golf, there's probably a lot of room for improvement :)

Julia, 71 bytes

Press Enter to fire or Ctrl+C to quit. The latter ends with an InterruptException.

Ungolfed:

# Set an initial bullet location
b = rand(1:6)

while b > 0