所以我试图在python 3中制作一个简单的二十一点游戏,一切正常,但我无法忍受。如果我输入2,它将不会做任何事情。提前致谢。编辑1:击中效果很好。编辑2:发布整个脚本,所以你可以重现我面临的问题,正如@roganjosh建议的那样。
from random import shuffle
import sys
def deal(deck, player, dealer):
shuffle(deck)
for _ in range(2):
player.append(deck.pop())
dealer.append(deck.pop())
def score(hand):
non_aces = [c for c in hand if c != 'A']
aces = [c for c in hand if c == 'A']
sum = 0
for card in non_aces:
if card in 'JQK':
sum += 10
else:
sum += int(card)
for card in aces:
if sum <= 10:
sum += 11
else:
sum += 1
return sum
def display_info(player, dealer, stand):
print("Your cards: [{}] ({})".format(']['.join(player), score(player)))
if stand:
print("Dealer cards: [{}] ({})".format(']['.join(dealer), score(dealer)))
else:
print("Dealer cards: [{}] [?]".format(dealer[0]))
def results(player, dealer, hand, stand):
if score(player) == 21 and hand:
print("Blackjack! You won!")
sys.exit()
elif score(player) > 21:
print("Busted. You lost!")
sys.exit()
if stand:
if score(dealer) > 21:
print("Dealer busted. You won!")
elif score(player) > score(dealer):
print("You beat the dealer! You won!")
elif score(player) < score(dealer):
print("You lost!")
else:
print("Push. Nobody wins or losses.")
sys.exit()
def hit_stand(deck, player, dealer, hand, stand):
print("What would you like to do")
print("[1] - Hit\n[2] - Stand")
choice = input("> ")
hand = False
if choice == '1':
player.append(deck.pop())
elif choice == '2':
stand = True
while score(dealer) <= 16:
dealer.append(deck.pop())
if __name__ == '__main__':
deck = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']*4
player = []
dealer = []
standing = False
first_hand = True
deal(deck, player, dealer)
while True:
display_info(player, dealer, standing)
results(player, dealer, first_hand, standing)
hit_stand(deck, player, dealer, first_hand, standing)
玩家选择站立后,您不会检查结果。因为在deal()
循环之前你只有while True
一次,如果你选择反复站立,你就会得到一个无限的条件。在经销商提取所有卡片后计算得分。
def hit_stand(deck, player, dealer, hand, stand):
print("What would you like to do")
print("[1] - Hit\n[2] - Stand")
choice = input("> ")
hand = False
if choice == '1':
player.append(deck.pop())
elif choice == '2':
stand = True
while score(dealer) <= 16:
print(score(dealer))
dealer.append(deck.pop())
display_info(player, dealer, stand)
results(player, dealer, first_hand, stand) # HERE
在一个有些不相关的说明中,确定最终得分后撞出游戏并不是很优雅。你会想看一个比while True:
和sys.exit()
更好的结构来控制流量,但这对你来说是一个练习。
最后,你不应该在sum
中使用score()
作为变量名,因为这是一个你正在重新定义的内置函数。使用像total
这样的东西,这样你就不会冒掩盖内置函数本身的风险。
来自@roganjosh的答案是正确的,但我想添加另一个注释,因为我认为这是关于Python如何工作的一个非常重要的观点。这是来自C / C ++ / Java背景的人(即我们几乎所有人)在使用Python时需要取消学习。
正如我在上面的评论中所说的,在Maria Laura的原始代码中,看起来对hit_stand
的调用是为了使用一些变量(例如stand
)作为输出变量,而在Python中我们不能在“a”中使用“输出变量”。功能调用。但Maria Laura提到“击中效果很好”,这意味着参数player
正在被修改。那么,如果我们不能拥有“输出变量”,那么为什么player
的值会被函数hit_stand
修改?
当代码调用hit_stand
时,会将五个对象传入函数:
deck
,player
,dealer
,hand
,stand
此函数外部的代码也有名称(deck, player, dealer, first_hand, standing)
指向这五个相同的对象。在hit_stand
的代码中,在.append()
和player
列表对象上调用dealer
方法,并且在.pop()
对象上调用deck
方法,因此所有这些对象都是突变的。调用范围中的名称仍然指向那些相同的对象,因此这些名称现在将看到这些更改。
hand
和stand
的故事是不同的。在hit_stand
函数内部,hand
和stand
被赋予=
运算符的新值。正如this excellent write-up from Fredrik Lundh所述,Python中的=
运算符不会“更改”变量,它只需要一个对象并将其绑定到一个名称。对象本身没有改变,而是用新的布尔对象替换。因此,外部作用域中的变量standing
仍然指向其原始的布尔对象,函数中的变量stand
指向一个全新的布尔对象,与外部作用域中的不同。我们无法对外部范围内可见的变量hand
和stand
做任何事情,就像我们在其他语言中一样,没有“通过引用传递”或“输出参数”这样的东西。
这是一个看起来非常陌生的概念,直到我们不了解我们在C / C ++ / Java教育中学到的东西。