Duelling Idiots

  • Thread starter Arman777
  • Start date
1,476
102
Problem:

A and B decide to duel but, being poor, they have just one gun (a six-shot revolver) and only one bullet. Being dumb, as well, this does not deter them and they agree to "duel" as follows: They will insert the lone bullet into the gun's cylinder, A will then spin the cylinder and shoot at B (who, standing inches away, is impossible to miss). If the gun doesn't fire then A will give the gun to B, who will spin the cylinder and then shoot at A. This back-and-forth duel will continue until one fool shoots the other. What is the probability that A will win?

Python:
import random

a_wins = 0
for i in range(10**6):
    Chances = ["d","nd","nd","nd","nd","nd"]  #nd = not dead, d = dead
    while len(Chances)> 0:
        b = random.choice (Chances)  #A shoots B
        if b == "d":
            a_wins += 1
            break
        else:
            Chances.remove("nd")
            a = random.choice(Chances)  #B shoots A
            if a == "d":
                break  #A cannot win
            else:
                Chances.remove("nd")   #wasting antoher chance
print(a_wins/10**6)
I am getting 0.50 however the correct answer is 0.54 so I guess I am missing something abour related to the first shoot ? Anyone can help. Thanks
 
You don't have to remove the nd, because B spin the cylinder again before shooting.
 
24,758
6,190
As @Gaussian97 says, you shoudn't remove the "nd" from Chances; the Chances are the same for each shot.

because B spin the cylinder again before shooting.
That makes a random choice among the chances correct for each shot, but it doesn't explain why the chances are the same for each shot. The reason the chances are the same for each shot is that the number of slots is the same (6) for all shots--an empty slot doesn't get removed if a shot is attempted but nothing fires.
 
24,758
6,190
you shoudn't remove the "nd" from Chances
This also means your inner while loop does not need the len(Chances) > 0 condition; that will always be true since you're not removing elements from Chances. It can just be while True (the two break statements are the only way to exit the loop).
 
As @Gaussian97 says, you shoudn't remove the "nd" from Chances; the Chances are the same for each shot.



That makes a random choice among the chances correct for each shot, but it doesn't explain why the chances are the same for each shot. The reason the chances are the same for each shot is that the number of slots is the same (6) for all shots--an empty slot doesn't get removed if a shot is attempted but nothing fires.
It really does, in fact, the code that @Arman777 has written is exactly the one you should use to simulate the case without B spinning before (and has a probability of 50%). The reason is that if you don't spin every round, once you spin, the bullet is in a concrete spot and you will kill the other in 6 or fewer tries, so once you have "shoot" an empty spot you will never shoot it again.
 
24,758
6,190
I am getting 0.50
As a useful exercise, you might want to prove that 0.50 is in fact what you should get if you do remove an "nd" from Chances each time a shot is attempted but not fired--or, to put it another way, if the gun was a special gun that ejected an empty slot (reducing the total number of slots by 1) if a shot was attempted but not fired.
 
10,442
3,962
I sure hope this is a paintball gun but didn’t if kenos of any made with a 6 shot cylinder.

I suppose for a paintball gun you could put 5 white balls and one red ball in the hopper and shake it up before shooting although I think after a shot the gun loads another ball.

The notion of dropping a shot each round sounds almost like the Josephus puzzle where you and many others make a circle and you cycle around the circle eliminating the player next to you until only is left.
 
1,476
102
Josephus puzzle
I know that game..See it on numberphile. Maybe at some other time, I can write a code for that. I think it would not be so hard



As a useful exercise, you might want to prove that 0.50 is in fact what you should get if you do remove an "nd" from Chances each time a shot is attempted but not fired--or, to put it another way, if the gun was a special gun that ejected an empty slot (reducing the total number of slots by 1) if a shot was attempted but not fired.
Like mathematically? My probability theory is not so great...

For spinning the cylinder case, I would have expected P= 0.50 since it seems more random. However, without spinning the cylinder, the first shooter always has more chance (or it seems to me that way ) so it's somewhat interesting to see such results.



While I was reading the question I did not pay attention to the spinning case.. thanks then

This also means your inner while loop does not need the lens(Chances) > 0 conditions; that will always be true since you're not removing elements from Chances. It can just be while True (the two break statements are the only way to exit the loop).
Yes, you are right.
 
24,758
6,190
For spinning the cylinder case, I would have expected P= 0.50 since it seems more random. However, without spinning the cylinder, the first shooter always has more chance (or it seems to me that way )
You have these backwards.

If you don't spin the cylinder after each firing attempt, then both shooters must have an equal chance at winning, i.e., P = 0.50, since the first shooter wins if the bullet is in an odd-numbered slot (numbering the slots 1 through 6 in the order they will be in the firing position) and the second shooter wins if the bullet is in an even-numbered slot, and there are the same number of both kinds of slots, so there is an equal chance of the bullet being in an odd or even slot.

If you spin the cylinder after each firing attempt, and the number of slots is fixed at 6 (as in any real gun), then the probability that the first shooter wins is 6/11 or 0.54 (which is what I assumed you were referring to when you said the correct answer is 0.54). But even without doing the calculation, it can be seen intuitively that the first shooter has an advantage in this scenario, simply because he shoots first. What the randomization of the cylinder by spinning does is make the chance of the bullet being in the firing position the same on each spin (a 1/6 chance); but that's not the same as making both shooters have the same chance of winning; if everything else about the scenario is the same between both shooters, then the one difference between them that you can't eliminate--that one of them shoots first--will be the deciding factor.

The interesting thing is that, if you do spin the cylinder after each attempt, but once a particular slot is used it can't be used again (either it's ejected from the gun or otherwise made unusable, so the cylinder will skip it on future spins), then you also have P = 0.50, not 0.54--i.e., both shooters have an equal chance at winning.
 
1,476
102
If you don't spin the cylinder after each firing attempt, then both shooters must have an equal chance at winning, i.e., P = 0.50, since the first shooter wins if the bullet is in an odd-numbered slot (numbering the slots 1 through 6 in the order they will be in the firing position) and the second shooter wins if the bullet is in an even-numbered slot, and there are the same number of both kinds of slots, so there is an equal chance of the bullet being in an odd or even slot.
Oh I understand it now.
The interesting thing is that, if you do spin the cylinder after each attempt, but once a particular slot is used it can't be used again (either it's ejected from the gun or otherwise made unusable, so the cylinder will skip it on future spins), then you also have P = 0.50, not 0.54--i.e., both shooters have an equal chance at winning.
It s interesting. I think my initial code was referring to spinning case but cannot using the same slot ?
 
24,758
6,190
I think my initial code was referring to spinning case but cannot using the same slot ?
Yes, your initial code was removing a slot every time a firing attempt was made but no bullet was in the slot, and then spinning the cylinder (since you were randomly choosing among the remaining slots each time).
 
1,476
102
Actually the question has another part which is like this

Now, here's your problem. Our two idiots have decided, after reading the preceding analysis, to use a different procedure. They still have just one gun and one bullet but now, with each exchange of the gun, they get one additional trigger pulL

That is, A puts the bullet in the cylinder, spins it and then shoots at B. If the gun doesn't fire, A gives the gun to B, who spins the cylinder and then shoots at A. If the gun doesn't fire, B spins the cylinder again and gets a second try. If the gun still doesn't fire, B gives the gun to A, who gets a maximum of three trigger pulls (with a spin of the cylinder between pulls), and so on.

Calculate P(A) theoretically.

This has also interesting result. I tried to write a code and this is the my code and P(A) this time becomes 0.52..

Python:
import random

chances = ["d", "nd", "nd", "nd", "nd", "nd"]


def a_shoots(chances, trigger_num):
    for i in range(trigger_num):
        b = random.choice(chances)
        if b == "d":
            return True


def b_shoots(chances, trigger_num):
    for i in range(trigger_num):
        a = random.choice(chances)
        if a == "d":
            return True

a_wins = 0
for i in range(10**6):
    trigger_num = 1
    while True:
        A = a_shoots(chances, trigger_num)
        if A == True:
            a_wins += 1
            break
        else:
            trigger_num += 1
            B = b_shoots(chances, trigger_num)
            if B == True:
                break
            else:
                trigger_num += 1

print(a_wins/10**6)
It seems that shooting first is important in any case
 
1,476
102
What is this question from? Is it a homework problem?
Oh no, it's not homework. I am just studying the Monte Carlo algorithm. My professor recommended me some books which are related to Monte Carlo and this problem is in the book.

 

FactChecker

Science Advisor
Gold Member
2018 Award
4,798
1,643
One comment I have about your code is that there should be comments in it. The fact that the number of trigger pulls increases each time they exchange the gun should be indicated in a comment. Other comments explaining things would also be nice. Inputs and outputs of functions should be defined in comments.

PS. If large programs are in your future (don't underestimate that possibility), it would be good to get used to writing comments in a format that Doxygen (or Sphinx?) can understand.
 
Last edited:
1,476
102
I ll be more careful on that idea. I ll put comments from now to get used to it..Thanks also for the formatting ideas.
 

Orodruin

Staff Emeritus
Science Advisor
Homework Helper
Insights Author
Gold Member
2018 Award
15,403
5,509
Note that the analytical consideration for the original case is much simpler than writing the code. All you need is some very basic considerations:
- What is the probability for the fool that is to shoot to win in the current shot?
- What is the probability that the fool misses?
- Given that the fool misses, what is the probability of him winning?
The total probability of winning is the sum of the probabilities of winning immediately and that of missing and winning anyway.
 

FactChecker

Science Advisor
Gold Member
2018 Award
4,798
1,643
Another programming comment. Although Python has a default function return value of None, I think that is unusual among programming languages. I recommend that you get in the habit of specifying a function return value in all cases:

Specify return value in all cases:
def b_shoots(chances, trigger_num):
    for i in range(trigger_num):
        a = random.choice(chances)
        if a == "d":
            return True
    return False
 
1,476
102
Another programming comment. Although Python has a default function return value of None, I think that is unusual among programming languages. I recommend that you get in the habit of specifying a function return value in all cases:

Specify return value in all cases:
def b_shoots(chances, trigger_num):
    for i in range(trigger_num):
        a = random.choice(chances)
        if a == "d":
            return True
    return False
Return False for in any case ?
 
1,476
102
Note that the analytical consideration for the original case is much simpler than writing the code. All you need is some very basic considerations:
- What is the probability for the fool that is to shoot to win in the current shot?
- What is the probability that the fool misses?
- Given that the fool misses, what is the probability of him winning?
The total probability of winning is the sum of the probabilities of winning immediately and that of missing and winning anyway.
Well its simpler indeed but thats not so much fun :)
 

FactChecker

Science Advisor
Gold Member
2018 Award
4,798
1,643
Return False for in any case ?
Return False if it made it through the entire "for i" loop and didn't return True. That is when it was returning None.
 

DaveC426913

Gold Member
17,935
1,567
One comment I have about your code is that there should be comments in it.
Also: You've got a duplicate function: one for A and an identical one for B. That's not good coding for several reasons. A good exercise would be to rewrite it as a single function for both shooters.
 
1,476
102
Also: You've got a duplicate function: one for A and an identical one for B. That's not good coding for several reasons. A good exercise would be to rewrite it as a single function for both shooters.
I see thanks for your comment. And I change my code by just using one function
 

Want to reply to this thread?

"Duelling Idiots" You must log in or register to reply here.

Physics Forums Values

We Value Quality
• Topics based on mainstream science
• Proper English grammar and spelling
We Value Civility
• Positive and compassionate attitudes
• Patience while debating
We Value Productivity
• Disciplined to remain on-topic
• Recognition of own weaknesses
• Solo and co-op problem solving
Top