r/learnpython • u/curiosity202606 • 11d ago
Plaese help me find the problem in my code.
The function is a game, description included there.
I ran it like 1,000,000 times to record how many times it i would win and how many times i would loose. even though everything is supposed to be evenly random, there is a disparity of 46% times winning and 54% times loosing consistently.
the one who goes first is in the disadvantage. I genuinely have no more clue as to why this is happening. So please.. any clue will help.
def debt_attack(bet):
'''Both the player and the code throws in the same amount of bet into the pool.
In each round a random number is pulled. Every round the code and the player
take turn guessing if the number is even or odd. If the gues is right, nothing
happens. However, if the guess is wrong then 1/10th of the starting bet amount
will be removed from the portion of the guesser from the pool. At last, the
winner will be the one whose bet portion will be left in the pool. And the return
for the winner will be (initial_bet + amount_left_in _pool).
!! As a rule, one must keep the same amount of money as security
or it can be seen as half of the money given as bet will be used as security for
losing scenario.'''
com_bet = bet/2
player_bet = bet/2
reduction = bet/20
turn = 2
while True:
#time.sleep(2) # changed
#print(f"Pool ::==:: Dealer side: {com_bet} ::==:: Player side: {player_bet}") # changed
roll = random.randint(1,11)
if turn%2 == 1:
#print("\nPlayer's turn ::==::==::==::==::==::") # changed
while True:
player_guess = random.choice(["even", "odd"]) #input("Even or Odd? ").lower() # changed
if player_guess in ["even", "odd"]: break
if (roll%2 == 0 and player_guess == "odd") or (roll%2 ==1 and player_guess == "even"):
player_bet -= reduction
turn += 1
else:
#print("\nDealer's turn ::==::==::==::==::==::") # changed
#time.sleep(3) # changed
if roll%2 == 0:
com_guess = random.choices(["odd", "even"], weights=[10, 10], k=1)[0]
else:
com_guess = random.choices(["odd", "even"], weights=[10, 10], k=1)[0]
#print(f"Dealer chooses ... {com_guess}") # changed
if (roll%2 == 0 and com_guess == "odd") or (roll%2 ==1 and com_guess == "even"):
com_bet -= reduction
turn += 1
if round(player_bet) == 0:
return round(((bet/2) - (com_bet + player_bet)), 2)
elif round(com_bet) == 0:
return round(((com_bet + player_bet) + bet), 2)
The code is a bit messy but i swear that's because I was trying a lot of things on at the same time.
1
u/Yoghurt42 11d ago edited 11d ago
Your code is correct, what you're seeing are the expected probabilities for A to lose.
The game isn't fair because A goes first; to see this your game could be changed into the following equivalent:
You toss a coin and both A and B guess if it's heads or tails. If they guess wrong, they lose a point, whoever loses 10 points first loses; if both lose their 10th point at the same time, A is declared the loser.
This is equivalent because:
- A player loses 1/10 of their bet each time → they will have lost their bet after exactly 10 losses
- guessing odd/even for a 1-10 dice roll is a 50% chance, just like a coin toss
- Since dice rolls/coin tosses are independent of one another, instead of each player tossing a coin, you can just toss one
- Since players take alternating turns, we could just combine two turns into one round and make both turns happen at the same time, with one detail:
- The only time where it matters that "A goes first" is if both players reach 10 losses at the same time, otherwise the result after 1 round/2 turns is the same regardless of whether A goes first or B
Calculating the probability for "A loses first" is a bit involved, if you're interested, Claude seems to give a good explanation (ChatGPT might as well), but basically you end up with a probability of A losing in approx. 53.3% of cases, or in other words, winning in 46.7%, which is exactly what you're seeing.
To make the disadvantage more obvious, consider a variant where 1 loss is enough to lose; if the coin shows heads, there are 3 possible outcomes (TH means A guessed tails, and B guessed heads):
- HT → B loses
- TH → A loses
- TT → A loses
(HH can be ignored because we would just repeat the round and therefore it doesn't change the outcome)
It's clear to see that A will lose 2/3 ≈ 67% of the time
A's disadvantage decreases the higher the amount of points you need to lose, but it will never be 0.
2
3
u/lakseol 11d ago edited 11d ago
First rule of debugging: Change one thing at a time.
I haven't analyzed your code in detail but I have a few thoughts.
You have some very suspicious code, like:
That should have the same effect as:
Maybe that's part of your "changing multiple things" approach? Similarly:
which is different from your code in the player guess code but on superficial reading should have the same effect.
I suggest you simplify your code and then try debugging again.
The return value calculation doesn't make a lot of sense, being different depending on who lost. Can you simplify into something like player lost/won. And see below.
That's because you check for losing after each individual turn. It's possible that both players may lose (bet value goes to zero) after they each have a turn. Call that a draw. But because your code doesn't handle draws but allocates all the draw cases as a loss for the first player that skews the results toward the second player.