站立的选择没有做任何事

问题描述 投票:0回答:2

所以我试图在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)
python python-3.x blackjack
2个回答
2
投票

玩家选择站立后,您不会检查结果。因为在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这样的东西,这样你就不会冒掩盖内置函数本身的风险。


0
投票

来自@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方法,因此所有这些对象都是突变的。调用范围中的名称仍然指向那些相同的对象,因此这些名称现在将看到这些更改。

handstand的故事是不同的。在hit_stand函数内部,handstand被赋予=运算符的新值。正如this excellent write-up from Fredrik Lundh所述,Python中的=运算符不会“更改”变量,它只需要一个对象并将其绑定到一个名称。对象本身没有改变,而是用新的布尔对象替换。因此,外部作用域中的变量standing仍然指向其原始的布尔对象,函数中的变量stand指向一个全新的布尔对象,与外部作用域中的不同。我们无法对外部范围内可见的变量handstand做任何事情,就像我们在其他语言中一样,没有“通过引用传递”或“输出参数”这样的东西。

这是一个看起来非常陌生的概念,直到我们不了解我们在C / C ++ / Java教育中学到的东西。

© www.soinside.com 2019 - 2024. All rights reserved.