ii aM  Osaama x
ii aM Osaama x

Reputation: 23

While loop not breaking under logical circumstances

I am making a code to simulate a dice and do other stuff, but there is a while loop which isn't breaking and I don't know why.

import random
import math

#infinite loop
while True:
    while True:
        a = 0
        #input amount of dice
        att_die = raw_input('Attacking dice: ')
        def_die = raw_input('Defending dice: ')

        #att
        #if NaN
        if str(att_die).isdigit() == False:
            print('NaN')
        #if not NaN
        else:
            a += 1

        #def
            #if NaN
        if str(def_die).isdigit() == False:
            print('NaN')
        #if not NaN
        else:
            a +=1

        if a == 2:
            break

    if att_die >= def_die:
        no = def_die
    else:
        no = att_die

    print (no)

    x = 0
    while x <= no:
        att_loss = 0
        def_loss = 0

        roll_att = random.randint(1,6)
        roll_def = random.randint(1,6)

        if roll_att <= roll_def:
            att_loss += 1
        elif roll_att == roll_def:
            att_loss += 1
        else:
            def_loss += 1

        x += 1
        print(x)
   print('Att: -' + str(att_loss) + '\nDef: -' + str(def_loss)) 

everything works up until the last while loop, which just continuously outputs the value of x increasing. Any help on how to fix this would be appreciated. Thanks in advance

Upvotes: 0

Views: 88

Answers (2)

Hugh Bothwell
Hugh Bothwell

Reputation: 56684

Here's a refactored version:

import random
import math

DIE_SIDES = 6
WINNING_ATTACK_ODDS = 0.5 * (DIE_SIDES - 1) / DIE_SIDES

def get_int(prompt):
    while True:
        try:
            return int(raw_input(prompt))
        except ValueError:
            pass

def attack():
    """
    Does the attacker win?
    """
    return random.random() < WINNING_ATTACK_ODDS

def main():
    while True:
        att_die = get_int("Attacking dice: ")
        def_die = get_int("Defending dice: ")

        rolls = min(att_die, def_die)
        def_loss = sum(attack() for _ in range(rolls))
        att_loss = rolls - def_loss

        print("Att: -{}\nDef: -{}".format(att_loss, def_loss))

if __name__=="__main__":
    main()

Upvotes: 0

unutbu
unutbu

Reputation: 880489

no is a str, not an int. x is an int. In Python2, ints are always compare less than strs:

In [187]: 9999 < '1'
Out[187]: True

The solution is to convert the str no into an int:

no = int(no)

In [188]: 9999 < int('1')
Out[188]: False

Note that in Python3, comparing an int with a str raises a TypeError, which will save many a programmer from this pitfall.

Upvotes: 2

Related Questions