Unknownzdx Unknownzdx - 1 month ago 11
Python Question

Characters from listbox are still recorded even when deleted from listbox

So my little game is programmed to have two characters fight each other. One from the left side and one from the right side. After they fight both should be deleted regardless of who wins or loses. They are in fact deleted from listboxes, but after you have two more charachters from each side fight those previous characters sometimes show up. If you start with Zys and Rash fighting no other names are printed in the win and loss section besides theirs. Only when you go backwards from Dant and Ilora does it work the way it should with each character making a place in either wins or loss only once. If you start with some other characters they could be put in the wins and loss section more then once. It is also possible for a character to be placed as a win or loss even if it hasnt been selected to fight. The bottomline is each character gets to fight a character on the opposite side ONCE and after that it is placed and then deleted with no use in the later part of the program. For some apparent reason it does not do that.

from tkinter import *
from tkinter import ttk
from tkinter import messagebox

class Character:
def __init__(self, name, attack, defense, health):
self.name = name
self.attack = attack
self.defense = defense
self.health = health
self.total = attack+defense+health

#Left side characters
Rash = Character("Rash", 42, 50, 80)
Untss = Character("Untss", 15, 54, 100)
Ilora = Character("Ilora", 60, 35, 80)
#Both sides have totals of 165 168 and 175
#Right side characters
Zys = Character("Zys", 12, 97, 83)
Eentha = Character("Eentha", 55, 17, 90)
Dant = Character("Dant", 73, 28, 88)

def fight(): #Part of code that checks for wins and loss checks which has greater total stats and deletes from list box

try:
namel = ""
namer=""
left = lbox.curselection()[0]
right = rbox.curselection()[0]

totalleft = 0
totalright = 0
if left == 0:
namel = "Rash"
totalleft = Rash.total
elif left==1:
namel = "Untss"
totalleft = Untss.total
elif left==2:
namel = "Ilora"
totalleft = 60+35+80

if right == 0:
namer = "Zys"
totalright = Zys.total
elif right==1:
namer = "Eentha"
totalright = Eentha.total
elif right==2:
namer = "Dant"
totalright = Dant.total

lbox.delete(lbox.curselection()[0])
rbox.delete(rbox.curselection()[0])
print(namel)
print(namer)
if (totalleft>totalright): #Checks if won or lost
wins.set(wins.get()+"\n"+namel)
loss.set(loss.get()+"\n"+namer)
else:
wins.set(wins.get()+"\n"+namer)
loss.set(loss.get()+"\n"+namel)
except IndexError:
pass


#The left listbox and its characters
leftnames = ('Rash', 'Untss', 'Ilora')
lnames = StringVar(value=leftnames)
lbox = Listbox(mainframe, listvariable=lnames, exportselection=0, height=3)
lbox.grid(column=0, row=0)


#Right listboxes characters
rightnames = ('Zys', 'Eentha', 'Dant')
rnames = StringVar(value=rightnames)
rbox = Listbox(mainframe, listvariable=rnames, exportselection=0, height=3)
rbox.grid(column=1, row=0)


#Shows users wins and lossses

wins = StringVar()
loss = StringVar()

#Label that
ttk.Label(mainframe, text="Wins", width=13).grid(column=2, row=0, sticky=N)
ttk.Label(mainframe, text="Loss", width=13).grid(column=2, row=1, sticky=N)
ttk.Label(mainframe, textvariable=wins).grid(column=2, row=0, sticky=(S,E))
ttk.Label(mainframe, textvariable=loss).grid(column=2, row=1, sticky=(S, E))

#Button for fighting
fightbttn= ttk.Button(mainframe, text="Fight", command=fight)
fightbttn.grid(column=3, row=3, sticky=(E))

root.mainloop()


This is only the part of the code that could relate to the problem not the code as a whole.

This is not the same question from yesterday just the same code. I thought it would be more appropriate to work with the bugs one at a time as different problems so they could be more organized.

Answer

Problem is because you use always if left == 0: namel = "Rash" even if"Rash"was deleted from listbox and nowleft == 0means"Untss".

You have to get selected name instead of index

    namel = lbox.get(lbox.curselection()[0])
    namer = rbox.get(rbox.curselection()[0])

and use it

    if namel == "Rush":
       totalleft = Rash.total

But you could use dictionary to get data

left_characters = {        
    "Rash": Character("Rash", 42, 50, 80),
    "Untss": Character("Untss", 15, 54, 100),
    "Ilora": Character("Ilora", 60, 35, 80),
}

right_characters = {
    "Zys": Character("Zys", 12, 97, 83),
    "Eentha": Character("Eentha", 55, 17, 90),
    "Dant": Character("Dant", 73, 28, 88),
}

leftnames = list(left_characters.keys())
rightnames = list(right_characters.keys())

and then

def fight():

    try:
        namel = lbox.get(lbox.curselection()[0])
        namer = rbox.get(rbox.curselection()[0])

        print(namel)
        print(namer)

        totalleft = left_characters[namel].total
        totalright = right_characters[namer].total

        lbox.delete(lbox.curselection()[0])
        rbox.delete(rbox.curselection()[0])

        if totalleft > totalright : #Checks if won or lost
            wins.set(wins.get()+"\n"+namel)
            loss.set(loss.get()+"\n"+namer)
        else:
            wins.set(wins.get()+"\n"+namer)
            loss.set(loss.get()+"\n"+namel)
    except IndexError as e:
        print("ERROR:", e)

If you add new characters to dictionary then you don't have to change code.

BTW: don't use pass in except because you don't see error if there is something wrong with code.

Comments