为什么在我的Python二十一个纸牌游戏中发生此错误?
以下是错误:为什么在我的Python二十一个纸牌游戏中发生此错误?
Traceback (most recent call last): File "C:/Users/Wattel/Desktop/21 21 21.py", line 177, in main() File "C:/Users/Wattel/Desktop/21 21 21.py", line 167, in main PPOINTS, DPOINTS, PHAND, DHAND = dLoop(PHAND, DHAND, DECK) TypeError: 'NoneType' object is not iterable
我知道它有事情做与此代码,但不能找出问题到底是什么:
scoreHAND(DHAND) < 18 or scoreHAND(DHAND) < 21 and scoreHAND(DHAND) < scoreHAND(PHAND) or scoreHAND(DHAND) < 21
这里是休息我的代码:
##21 Card Game
##Wattel
##2016 Spring
from random import *
import random
from random import shuffle, randint
CARDPOINTS = {'AD': 11,'AH': 11,'AC': 11,'AS': 11,
'KD': 10,'KH': 10,'KC': 10,'KS':10,
'QD': 10,'QH': 10,'QC': 10,'QS': 10,
'JD': 10,'JH': 10,'JC': 10,'JS': 10,
'10D': 10,'10H': 10,'10C': 10,'10S': 10,
'9D': 9,'9H': 9,'9C': 9,'9S': 9,
'8D': 8,'8H': 8,'8C': 8,'8S': 8,
'7D': 7,'7H': 7,'7C': 7,'7S': 7,
'6D': 6,'6H': 6,'6C': 6,'6S': 6,
'5D': 5,'5H': 5,'5C': 5,'5S': 5,
'4D': 4,'4H': 4,'4C': 4,'4S': 4,
'3D': 3,'3H': 3,'3C': 3,'3S': 3,
'2D': 2,'2H': 2,'2C': 2,'2S': 2,}
List = ['AD','AH','AC','AS',
'KD','KH','KC','KS',
'QD','QH','QC','QS',
'JD','JH','JC','JS',
'10D','10H','10C','10S',
'9D','9H','9C','9S',
'8D','8H','8C','8S',
'7D','7H','7C','7S',
'6D','6H','6C','6S',
'5D','5H','5C','5S',
'4D','4H','4C','4S',
'3D','3H','3C','3S',
'2D','2H','2C','2S',]
def want2play():
Hit2Play = input(" Hit 'y' to begin your game of 21): ")
print ("")
return Hit2Play
def deckCheck(DECK):
print (DECK)
print("There are:",len(DECK),"cards in the deck.")
if len(DECK) < 20:
DECK = shuffleDeck()
return DECK
else:
return DECK
def openingDeal(DECK):
PHAND = []
DHAND = []
DHANDT = []
PHAND, DECK = dealOneCard(PHAND, DECK)
DHAND, DECK = dealOneCard(DHAND, DECK)
DHANDT.append(DHAND[0])
PHAND, DECK = dealOneCard(PHAND, DECK)
DHAND, DECK = dealOneCard(DHAND, DECK)
DHANDT.append("back of card")
PPOINTS = scoreHAND(PHAND)
printScores_0(PPOINTS, PHAND, DHANDT)
return PHAND, DHAND, DHANDT, DECK
def pLoop(PHAND, DHAND, DHANDT, DECK):
while scoreHAND(PHAND) < 21:
hitorhold = input('Do you want to hit or hold?: ')
if hitorhold == 'hit':
dealOneCard(PHAND, DECK)
printScores_0(scoreHAND(PHAND), PHAND, DHANDT)
elif hitorhold == 'hold':
print('Player holds')
printScores_0(scoreHAND(PHAND), PHAND, DHANDT)
break
return PHAND, DHAND, DECK
def dLoop(PHAND, DHAND, DECK):
printScores_1(scoreHAND(PHAND), scoreHAND(DHAND), PHAND, DHAND)
if scoreHAND(DHAND) < 18 or scoreHAND(DHAND) < 21 or scoreHAND(DHAND) < scoreHAND(PHAND) or scoreHAND(DHAND) < 21 or scoreHAND(PHAND) < 22:
dealOneCard(DHAND, DECK)
printScores_1(scoreHAND(PHAND), scoreHAND(DHAND), PHAND, DHAND)
return scoreHAND(PHAND), scoreHAND(DHAND), PHAND, DHAND
else:
return scoreHAND(PHAND), scoreHAND(DHAND), PHAND, DHAND
def checkScore(pWin, dWin, PPOINTS, DPOINTS):
if DPOINTS > PPOINTS and DPOINTS < 22:
dWin += 1
print (' ')
print ("Dealer Win")
return pWin, dWin
elif PPOINTS == DPOINTS and PPOINTS < 21:
dWin += 1
print (' ')
print ("Dealer Win")
return pWin, dWin
elif PPOINTS > 21 and DPOINTS < 21:
dWin += 1
print(' ')
print("Dealer Win")
return pWin, dWin
elif PPOINTS < 22 and DPOINTS > 21:
pWin += 1
print (' ')
print ("Player Win")
return pWin, dWin
elif PPOINTS > 21 and DPOINTS > 21:
print (' ')
print ("Tie.")
return pWin, dWin
elif PPOINTS == 21 and DPOINTS == 21:
print(' ')
print("Tie.")
return pWin, dWin
def dealOneCard(HAND,DECK):
theCard = DECK.pop(0)
HAND.append(theCard)
return HAND, DECK
def shuffleDeck():
CardPile = len(List)
random.shuffle(List)
return List
def scoreHAND(HAND):
points = addScore(HAND)
aceCount=0
if points > 21:
aceCount += HAND.count('AS')
aceCount += HAND.count('AH')
aceCount += HAND.count('AC')
aceCount += HAND.count('AD')
while points > 21 and aceCount > 0:
points -= 10
aceCount -= 1
return points
else:
return points
def addScore(HAND):
tempScore = 0
for i in HAND:
tempScore += CARDPOINTS[i]
return tempScore
def printScores_0(POINTS, HAND, HAND1):
print("Player's cards: ", HAND, "Player's hand score: ", POINTS)
print("Dealer's cards: ", HAND1)
def printScores_1(PPOINTS, DPOINTS, PHAND, DHAND):
print("Player's cards: ", PHAND, "Player's hand score: ", PPOINTS)
print("Dealer's cards: ", DHAND, "Dealer's hand score: ", DPOINTS)
def main():
DECK = shuffleDeck()
pWin = 0
dWin = 0
while True:
Hit2Play = want2play()
if Hit2Play == 'y':
DECK = deckCheck(DECK)
PHAND, DHAND, DHANDT, DECK = openingDeal(DECK)
PHAND, DHAND, DECK = pLoop(PHAND, DHAND, DHANDT, DECK)
PPOINTS, DPOINTS, PHAND, DHAND = dLoop(PHAND, DHAND, DECK)
pWin, dWin = checkScore(pWin, dWin, PPOINTS, DPOINTS)
print("")
print("Player's Wins:", pWin, "Dealer's Wins:",dWin)
print("")
else:
print("Player's Wins:", pWin, "Dealer's Wins:",dWin)
break
main()
我在代码中看到的唯一问题是在checkScore()函数中,每个if语句都返回相同的东西,但没有返回o如果是。如果你错过了一个角落案件或其他事情,那么这将会引发错误。我建议移动线
return pwin, dwin
以外的if,elif块。如果这不能解决您的问题,请尝试修改dloop功能;只有在函数返回无时才会发生您收到的错误。
你能告诉我一个你是什么意思的例子吗? – Wattel
我做了一个快速测试,遇到了同样的情况:'checkScore'有时会返回'None'。我看不到任何'dLoop'这样做的方式,所以我无法将发布的代码与生成OP原始错误的代码进行协调。 –
Wattel,在checkScore中没有最终的'else:',所以它有时返回'None'。添加一个'else:' –
这里是最终的代码结果!有没有人发现任何问题?
##21 Card Game
##Wattel
##2016 Spring
from random import *
import random
from random import shuffle, randint
CARDPOINTS = {'AD': 11,'AH': 11,'AC': 11,'AS': 11,
'KD': 10,'KH': 10,'KC': 10,'KS':10,
'QD': 10,'QH': 10,'QC': 10,'QS': 10,
'JD': 10,'JH': 10,'JC': 10,'JS': 10,
'10D': 10,'10H': 10,'10C': 10,'10S': 10,
'9D': 9,'9H': 9,'9C': 9,'9S': 9,
'8D': 8,'8H': 8,'8C': 8,'8S': 8,
'7D': 7,'7H': 7,'7C': 7,'7S': 7,
'6D': 6,'6H': 6,'6C': 6,'6S': 6,
'5D': 5,'5H': 5,'5C': 5,'5S': 5,
'4D': 4,'4H': 4,'4C': 4,'4S': 4,
'3D': 3,'3H': 3,'3C': 3,'3S': 3,
'2D': 2,'2H': 2,'2C': 2,'2S': 2,}
def shuffleDeck():
List = ['AD','AH','AC','AS',
'KD','KH','KC','KS',
'QD','QH','QC','QS',
'JD','JH','JC','JS',
'10D','10H','10C','10S',
'9D','9H','9C','9S',
'8D','8H','8C','8S',
'7D','7H','7C','7S',
'6D','6H','6C','6S',
'5D','5H','5C','5S',
'4D','4H','4C','4S',
'3D','3H','3C','3S',
'2D','2H','2C','2S',]
CardPile = len(List)
random.shuffle(List)
return List
def want2play():
Hit2Play = input(" Hit 'y' to begin your game of 21): ")
print ("")
return Hit2Play
def deckCheck(DECK):
print (DECK)
print("There are:",len(DECK),"cards in the deck.")
if len(DECK) < 20:
DECK = shuffleDeck()
return DECK
else:
return DECK
def openingDeal(DECK):
PHAND = []
DHAND = []
DHANDT = []
PHAND, DECK = dealOneCard(PHAND, DECK)
DHAND, DECK = dealOneCard(DHAND, DECK)
DHANDT.append(DHAND[0])
PHAND, DECK = dealOneCard(PHAND, DECK)
DHAND, DECK = dealOneCard(DHAND, DECK)
DHANDT.append("back of card")
PPOINTS = scoreHAND(PHAND)
printScores_0(PPOINTS, PHAND, DHANDT)
return PHAND, DHAND, DHANDT, DECK
def pLoop(PHAND, DHAND, DHANDT, DECK):
while scoreHAND(PHAND) < 21:
hitorhold = input('Do you want to hit or hold?: ')
if hitorhold == 'hit':
dealOneCard(PHAND, DECK)
printScores_0(scoreHAND(PHAND), PHAND, DHANDT)
elif hitorhold == 'hold':
print('Player holds')
printScores_0(scoreHAND(PHAND), PHAND, DHANDT)
break
return PHAND, DHAND, DECK
def dLoop(PHAND, DHAND, DECK):
printScores_1(scoreHAND(PHAND), scoreHAND(DHAND), PHAND, DHAND)
if scoreHAND(DHAND) < 21 or scoreHAND(DHAND) < 21 or scoreHAND(DHAND) < scoreHAND(PHAND) or scoreHAND(DHAND) < 21 or scoreHAND(PHAND) < 22:
dealOneCard(DHAND, DECK)
printScores_1(scoreHAND(PHAND), scoreHAND(DHAND), PHAND, DHAND)
return scoreHAND(PHAND), scoreHAND(DHAND), PHAND, DHAND
else:
return scoreHAND(PHAND), scoreHAND(DHAND), PHAND, DHAND
def checkScore(pWin, dWin, PPOINTS, DPOINTS):
if DPOINTS > PPOINTS and DPOINTS < 22:
dWin += 1
print (' ')
print ("Dealer Win")
return pWin, dWin
elif PPOINTS == DPOINTS and PPOINTS < 21:
dWin += 1
print (' ')
print ("Dealer Win")
return pWin, dWin
elif PPOINTS > 21 and DPOINTS < 21:
dWin += 1
print(' ')
print("Dealer Win")
return pWin, dWin
elif PPOINTS < 22 and DPOINTS > 21:
pWin += 1
print (' ')
print ("Player Win")
return pWin, dWin
elif PPOINTS > 21 and DPOINTS > 21:
print (' ')
print ("Tie.")
return pWin, dWin
else:
PPOINTS == 21 and DPOINTS == 21
print(' ')
print("Tie.")
return pWin, dWin
def dealOneCard(HAND,DECK):
theCard = DECK.pop(0)
HAND.append(theCard)
return HAND, DECK
def scoreHAND(HAND):
points = addScore(HAND)
aceCount=0
if points > 21:
aceCount += HAND.count('AS')
aceCount += HAND.count('AH')
aceCount += HAND.count('AC')
aceCount += HAND.count('AD')
while points > 21 and aceCount > 0:
points -= 10
aceCount -= 1
return points
else:
return points
def addScore(HAND):
tempScore = 0
for i in HAND:
tempScore += CARDPOINTS[i]
return tempScore
def printScores_0(POINTS, HAND, HAND1):
print("Player's cards: ", HAND, "Player's hand score: ", POINTS)
print("Dealer's cards: ", HAND1)
def printScores_1(PPOINTS, DPOINTS, PHAND, DHAND):
print("Player's cards: ", PHAND, "Player's hand score: ", PPOINTS)
print("Dealer's cards: ", DHAND, "Dealer's hand score: ", DPOINTS)
def main():
DECK = shuffleDeck()
pWin = 0
dWin = 0
while True:
Hit2Play = want2play()
if Hit2Play == 'y':
DECK = deckCheck(DECK)
PHAND, DHAND, DHANDT, DECK = openingDeal(DECK)
PHAND, DHAND, DECK = pLoop(PHAND, DHAND, DHANDT, DECK)
PPOINTS, DPOINTS, PHAND, DHAND = dLoop(PHAND, DHAND, DECK)
pWin, dWin = checkScore(pWin, dWin, PPOINTS, DPOINTS)
print("")
print("Player's Wins:", pWin, "Dealer's Wins:",dWin)
print("")
else:
print("Player's Wins:", pWin, "Dealer's Wins:",dWin)
break
main()
我相信在您的新密码输入有误,并
else:
PPOINTS == 21 and DPOINTS == 21
print(' ')
print("Tie.")
return pWin, dWin
应该
elif PPOINTS == 21 and DPOINTS == 21:
print(' ')
print("Tie.")
return pWin, dWin
如果是这样的话,我写了一个快速测试帧像这样:
results = [[''] * 25 for _ in range(25)]
for dp in range(25):
for pp in range(25):
res = checkScore(0, 0, pp, dp)
if res is None:
results[dp][pp] = 'N'
else:
p, d = res
results[dp][pp] = ["=+","-="][d][p]
results.reverse() # flip bottom-to-top
print("\n".join("".join(row) for row in results))
它给出(添加标签): 编辑:我拿到了得分倒退:
++++++++++++++++++++++===
++++++++++++++++++++++===
++++++++++++++++++++++===
D ---------------------=NNN
e 20 ---------------------N---
a --------------------NN--- + player wins
l -------------------NNN--- = player ties
e ------------------NNNN--- - player loses
r -----------------NNNNN---
15 ----------------NNNNNN---
P ---------------NNNNNNN--- N game crashes because
o --------------NNNNNNNN--- checkScore does not
i -------------NNNNNNNNN--- handle this combination
n ------------NNNNNNNNNN--- of inputs
t 10 -----------NNNNNNNNNNN---
s ----------NNNNNNNNNNNN---
---------NNNNNNNNNNNNN---
--------NNNNNNNNNNNNNN---
-------NNNNNNNNNNNNNNN---
5 ------NNNNNNNNNNNNNNNN---
-----NNNNNNNNNNNNNNNNN---
----NNNNNNNNNNNNNNNNNN---
---NNNNNNNNNNNNNNNNNNN---
--NNNNNNNNNNNNNNNNNNNN---
0 -NNNNNNNNNNNNNNNNNNNNN---
0 5 1 1 2
0 5 0
Player Points
我看见好多Ns的存在。
编辑2:解决办法:
上面的图表应该可以很容易看到所涉及的几何区域;我们只需要重写checkScore
,妥善处理中:
def check_score(player_wins, dealer_wins, player_pts, dealer_pts):
if dealer_pts > 21:
if player_pts > 21:
# no-one wins (top right square)
print("\nTie")
return player_wins, dealer_wins
else:
# player wins (top left rectangle)
print("\nPlayer wins")
return player_wins + 1, dealer_wins
else:
if player_pts > 21:
# player loses (bottom right rectangle)
print("\nDealer wins")
return player_wins, dealer_wins + 1
elif dealer_pts >= player_pts:
# player loses (top triangle)
print("\nDealer wins")
return player_wins, dealer_wins + 1
else:
# player wins (bottom triangle)
print("\nPlayer wins")
return player_wins + 1, dealer_wins
和重新测试给了我们
++++++++++++++++++++++===
++++++++++++++++++++++===
++++++++++++++++++++++===
-------------------------
---------------------+---
--------------------++--- Problem solved!
-------------------+++---
------------------++++---
-----------------+++++---
----------------++++++---
---------------+++++++---
--------------++++++++---
-------------+++++++++---
------------++++++++++---
-----------+++++++++++---
----------++++++++++++---
---------+++++++++++++---
--------++++++++++++++---
-------+++++++++++++++---
------++++++++++++++++---
-----+++++++++++++++++---
----++++++++++++++++++---
---+++++++++++++++++++---
--++++++++++++++++++++---
-+++++++++++++++++++++---
为了比较的缘故,我写了一个面向对象的版本。希望你从中学到很多东西;-)
from random import shuffle
LOSE, TIE, WIN = -1, 0, 1
def get_yn(prompt, error_message=None, yes_values={'y','yes',''}, no_values={'n','no'}):
"""
Prompt for input until a yes_value or no_value is entered.
Return True for a yes_value or False for a no_value
"""
while True:
response = input(prompt).strip().lower()
if response in yes_values:
return True
elif response in no_values:
return False
elif error_message is not None:
print(error_message)
class Deck:
SUITS = ('D', 'H', 'C', 'S')
FACES = ('2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A')
POINTS = (2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11)
def __init__(self):
self.reset()
def freshen(self):
if len(self.cards) < 20:
self.reset()
def reset(self):
self.cards = list(self.CARD_VALUES)
shuffle(self.cards)
def deal_to(self, hand):
card = self.cards.pop()
hand.cards.append(card)
# Back-patch because we cannot refer to Deck class variables until Deck is fully defined
Deck.CARD_VALUES = {f+s:p for f,p in zip(Deck.FACES, Deck.POINTS) for s in Deck.SUITS}
class Hand:
def __init__(self):
self.cards = []
@property
def points(self):
# get sum of cards values, counting aces as 11
card_value = Deck.CARD_VALUES.__getitem__
total = sum(card_value(card) for card in self.cards)
if total > 21:
# Aces can also be counted as 1;
# if total is too high, try to get it <= 21
max_aces = sum(card[0] == 'A' for card in self.cards)
use_aces = (total - 12) // 10
total -= 10 * min(use_aces, max_aces)
return total
def __str__(self):
return "{} ({} points)".format(" ".join(self.cards), self.points)
def dealer_first_hand(self):
# alternate __str__ for use while dealer's second card is hidden
return "{} ??".format(self.cards[0])
def show_hands(player, dealer, first_hand=False):
print("Player hand: {}".format(player))
print("Dealer hand: {}\n".format(dealer.dealer_first_hand() if first_hand else dealer))
class TwentyOne:
def __init__(self):
self.deck = Deck()
@staticmethod
def result(player_pts, dealer_pts):
if dealer_pts > 21:
if player_pts > 21:
# no-one wins (top right square)
print("\nTie")
return TIE
else:
# player wins (top left rectangle)
print("\nPlayer wins")
return WIN
else:
if player_pts > 21:
# player loses (bottom right rectangle)
print("\nDealer wins")
return LOSE
elif dealer_pts >= player_pts:
# player loses (top triangle)
print("\nDealer wins")
return LOSE
else:
# player wins (bottom triangle)
print("\nPlayer wins")
return WIN
def play(self):
self.deck.freshen()
player = Hand()
dealer = Hand()
# opening deal
self.deck.deal_to(player)
self.deck.deal_to(dealer)
self.deck.deal_to(player)
self.deck.deal_to(dealer)
# player loop
while player.points < 21:
show_hands(player, dealer, True)
if get_yn("Do you want to take another card? [Y/n] "):
self.deck.deal_to(player)
else:
print("Player holds\n")
break
# dealer loop
show_hands(player, dealer)
while dealer.points < 17:
self.deck.deal_to(dealer)
show_hands(player, dealer)
# tally the result
return self.result(player.points, dealer.points)
def main():
game = TwentyOne()
wins = 0
losses = 0
while True:
result = game.play()
wins += (result == WIN)
losses += (result == LOSE)
print("Player won {}, dealer won {}\n".format(wins, losses))
if not get_yn("Play again? [Y/n] "): break
if __name__ == "__main__":
main()
PEP-8建议ALL_CAPS应该为常量保留。 –
你确定这是堆栈跟踪?它应该追溯到迭代失败的位置,这个位置比调用的线路更靠下调用堆栈。从堆栈跟踪的底部,查看每行的代码,并问自己该变量是如何变成'None'的。如果您需要更多信息,散点图会打印出来。 – tdelaney
无论您在下面给出的帮助如何,在您发送程序之后,您应该获取此破解代码的副本,并学习使用pdb,python调试器! http://stackoverflow.com/questions/1623039/python-debugging-tips --- https://docs.python.org/2/library/pdb.html – pyInTheSky