Reputation: 145
This is a very strange error, I have no idea what is going on. Essentially my code is top trumps its not fully done yet but anyway. For those of you who have played top trumps my code simulates the passing of cards between the two hands. However if you look at line 129 (if len(Your_Hand)== 0:
) where I have used len() to print the length of these hands, they dont add up. Ie len() says a length which when one reads the list is obviously not right?
Thanks if you could take a look and try and help me as to what is going on that would be brilliant!
This is my code:
#top trumps stuff
import random
import time
pack = [("harry Potter",2,3,4,5),
("Hermione Granger", 5,6,7,8),
("Ron Weasley", 12, 13,4,5),
("Neville Longbottom", 1,1,1,1),
("Ginny Weasley",2,3,4,5),
("Draco Malfoy",3,6,7,8) ]
pile_1 = []
pile_2 = []
clash_pile = []
Your_Hand = 0
Opponent_Hand = 0
end_loop=0
catagory_exchange = {"brains":0,
"knowledge": 1 ,
"cunning": 2,
"evil":3}
choice = 0
acceptable_answers = catagory_exchange.keys()
proceed = 0
clash = 0
end_game = 0
#Shuffles the pack
random.shuffle(pack)
# Deals the cards
Dealer_count =0
while Dealer_count <len(pack):
pile_1.append(pack[0])
pack.remove(pack[0])
pile_2.append(pack[0])
pack.remove(pack[0])
#Asks Which pile they'd like
Which_Pile = raw_input(">> Which Pile would you like 1 or 2?")
while end_loop != 1:
if Which_Pile == "1":
Your_Hand = pile_1
Opponent_Hand = pile_2
print "Lets now start!"
end_loop = 1
elif Which_Pile == "2":
Your_Hand = pile_2
Opponent_Hand = pile_1
print "Lets now start!"
end_loop = 1
else:
Which_Pile = raw_input("You didn't pick 1 or 2! Pick again!!")
while end_game != 1:
print len(Your_Hand)
print Your_Hand
print len(Opponent_Hand)
print Opponent_Hand
print Your_Hand[0]
choice = raw_input(">> choose a catagory, brains, knowledge, cunning, evil - ")
if choice in acceptable_answers:
proceed = 1
else:
print "Thats not an catagory"
if proceed == 1:
if Your_Hand[0][catagory_exchange[choice]] > Opponent_Hand[0][catagory_exchange[choice]]:
if clash == 1:
print "You won the cards from previous rounds aswell!!"
clash = 0
clash_pile[:] = []
else:
print "You won the card you received %s" % Opponent_Hand[0][0]
Your_Hand.append(Opponent_Hand[0])
Your_Hand.append(clash_pile)
Opponent_Hand.remove(Opponent_Hand[0])
Your_Hand.append(Your_Hand[0])
Your_Hand.remove(Your_Hand[0])
elif Your_Hand[0][catagory_exchange[choice]] < Opponent_Hand[0][catagory_exchange[choice]]:
if clash ==1:
print "You lost the cards from previous rounds aswell"
clash = 0
clash_pile[:] = []
else:
print "You lost the card"
Opponent_Hand.append(Your_Hand[0])
Your_Hand.append(clash_pile)
Your_Hand.remove(Your_Hand[0])
Opponent_Hand.append(Opponent_Hand[0])
Opponent_Hand.remove(Opponent_Hand[0])
if Your_Hand[0][catagory_exchange[choice]] == Opponent_Hand[0][catagory_exchange[choice]]:
clash =1
print "They both have the same value"
print "They have been added to a pile which you will win when you win the next round"
clash_pile.append(Your_Hand[0])
clash_pile.append(Opponent_Hand[0])
Opponent_Hand.remove(Opponent_Hand[0])
Your_Hand.remove(Your_Hand[0])
if len(Your_Hand)== 0:
print "Oh no! You have run out of cards! You lose!!"
if len(Opponent_Hand)==0:
print "Well done! Your opponent has run out of cards! You win!!"
Upvotes: 0
Views: 375
Reputation: 76715
I rewrote your program and it works for me now. Several things I found:
The big problem was the one noted by @Kevin in his answer: you were using list.append()
instead of list.extend()
to copy cards from clash_pile
.
Also, category_exchange
contained values that were off by one. Item 0 in each card is a string, and choosing brains
was causing a string compare between card names. (I was very puzzled when I kept winning hands with Neville Longbottom!)
I rewrote the code to move cards. Instead of first calling .append()
and then calling .remove()
, I am calling .pop()
to remove the value and return it, and doing that inside .append()
. When it's all on one line, you are less likely to see a bug where someone changes just one of the two lines of code.
Also, instead of flag variables to signal when an acceptable input has been found, I am using infinite loops and simply breaking when an acceptable input has been found.
Also, instead of using flag variables to signal things like "clash pile has cards in it", or checking for length of 0 on card lists, I changed it to just directly check the list values.
Also, since I am very lazy, I made the program accept a number for a category. Instead of typing knowledge
you can just type 2
and it works.
Let me know if you have any questions.
#top trumps stuff
import random
import time
pack = [
("Harry Potter",2,3,4,5),
("Hermione Granger", 5,6,7,8),
("Ron Weasley", 12, 13,4,5),
("Neville Longbottom", 1,1,1,1),
("Ginny Weasley",2,3,4,5),
("Draco Malfoy",3,6,7,8)
]
pile_1 = []
pile_2 = []
clash_pile = []
category_exchange = {
"brains" : 1,
"knowledge" : 2 ,
"cunning" : 3,
"evil" : 4,
}
#Shuffles the pack
random.shuffle(pack)
# Deals the cards
while pack:
pile_1.append(pack.pop(0))
pile_2.append(pack.pop(0))
#Asks Which pile they'd like
while True:
Which_Pile = raw_input(">> Which Pile would you like 1 or 2?")
if Which_Pile.strip() == "1":
Your_Hand = pile_1
Opponent_Hand = pile_2
print "Lets now start!"
break
elif Which_Pile.strip() == "2":
Your_Hand = pile_2
Opponent_Hand = pile_1
print "Lets now start!"
break
else:
print "You didn't pick 1 or 2! Pick again!!"
while True:
if not Your_Hand:
print "Oh no! You have run out of cards! You lose!!"
break
if not Opponent_Hand:
print "Well done! Your opponent has run out of cards! You win!!"
break
print "\n"
print "DEBUG: Opponent: len: %d top_card: %s" % (len(Opponent_Hand), str(Opponent_Hand[0]))
print "DEBUG: You: len: %d top_card: %s" % (len(Your_Hand), str(Your_Hand[0]))
print "Here is your top card: '%s'" % str(Your_Hand[0])
while True:
choice = raw_input(">> choose a category, brains, knowledge, cunning, evil: ")
if choice in category_exchange:
i = category_exchange[choice]
break
else:
try:
i = int(choice)
except ValueError:
pass
if i in category_exchange.values():
break
print "That's not a category"
print "Opponent had: %s" % str(Opponent_Hand[0])
if Your_Hand[0][i] > Opponent_Hand[0][i]:
if clash_pile:
print "You won the cards from previous rounds as well!!"
else:
print "You won the card!"
Your_Hand.append(Opponent_Hand.pop(0))
Your_Hand.extend(clash_pile)
clash_pile = []
Your_Hand.append(Your_Hand.pop(0))
elif Your_Hand[0][i] < Opponent_Hand[0][i]:
if clash_pile:
print "You lost the cards from previous rounds as well"
else:
print "You lost the card!"
Opponent_Hand.append(Your_Hand.pop(0))
Opponent_Hand.extend(clash_pile)
clash_pile = []
Opponent_Hand.append(Opponent_Hand.pop(0))
else:
assert Your_Hand[0][i] == Opponent_Hand[0][i]
print "Both cards have the same value."
print "They have been added to a pile which will go to the next winner."
clash_pile.append(Your_Hand.pop(0))
clash_pile.append(Opponent_Hand.pop(0))
Upvotes: 1
Reputation: 76194
After a few rounds my hand had a length of 3, composed of one Ron Weasley card, and two empty lists: [('Ron Weasley', 12, 13, 4, 5), [], []]
. I'm guessing you don't want to have those empty lists there.
The culprit appears to be this line:
Your_Hand.append(clash_pile)
Which always adds an empty list to your hand.
you probably want extend
rather than append
. Additionally, you should add the clash pile to the winner's hand before you reset the clash pile to []
.
Other observations possibly not related to your original problem:
if
in the line if Your_Hand[0][catagory_exchange[choice]] == Opponent_Hand[0][catagory_exchange[choice]]:
should probably be elif
Upvotes: 4