首页 > 解决方案 > 大约每 24 场比赛一次,我的二十一点游戏的随机选择失败

问题描述

大约 2 个月前,我开始学习 Python。所以,我想这对很多人来说可能是显而易见的。

我制作了这个黑杰克代码,它或多或少地按照我想要的方式工作。除了一件我无法弄清楚会发生什么的错误。

在得到我的初始手之后。如果我抽到一张“黑桃 A”或“方块 A”,我将抽的下一张牌将是相同的(“黑桃 A”或“方块 A”取决于前一张),这不应该发生,因为卡片不应该再出现在甲板上,因为它已经在我手中。到最后,仍然会有 52 张牌,但会有 5 张“A”,并且会随机丢失另一张。

对不起,很长的帖子。这是我的第一个 Stack 问题,我仍在研究如何充分利用它。

这是我很长而且可能不是那么理想的代码:

import random


deck = {"Ace of Spades": 11, "2 of Spades": 2, "3 of Spades": 3, "4 of Spades": 4,
        "5 of Spades": 5, "6 of Spades": 6, "7 of Spades": 7, "8 of Spades": 8,
        "9 of Spades": 9, "10 of Spades": 10, "Jack of Spades": 10,
        "Queen of Spades": 10, "King of Spades": 10,
        "Ace of Hearts": 11, "2 of Hearts": 2, "3 of Hearts": 3, "4 of Hearts": 4,
        "5 of Hearts": 5, "6 of Hearts": 6, "7 of Hearts": 7, "8 of Hearts": 8,
        "9 of Hearts": 9, "10 of Hearts": 10, "Jack of Hearts": 10,
        "Queen of Hearts": 10, "King of Hearts": 10,
        "Ace of Clovers": 11, "2 of Clovers": 2, "3 of Clovers": 3, "4 of Clovers": 4,
        "5 of Clovers": 5, "6 of Clovers": 6, "7 of Clovers": 7, "8 of Clovers": 8,
        "9 of Clovers": 9, "10 of Clovers": 10, "Jack of Clovers": 10,
        "Queen of Clovers": 10, "King of Clovers": 10,
        "Ace of Diamonds": 11, "2 of Diamonds": 2, "3 of Diamonds": 3, "4 of Diamonds": 4,
        "5 of Diamonds": 5, "6 of Diamonds": 6, "7 of Diamonds": 7, "8 of Diamonds": 8,
        "9 of Diamonds": 9, "10 of Diamonds": 10, "Jack of Diamonds": 10,
        "Queen of Diamonds": 10, "King of Diamonds": 10}

###################################################################################################################
#####                                   DEFINING DEAL |BJ - SPECIFIC|                                         #####


def deal(deck: dict, value: int, cards_in_hand: list, show_list: list):
    """
    Deals a card for the Black Jack game and provides the added value of the card.
    :param deck: A Dictionary. Same for everybody.
    :param value: A score. Dependant on the player.
    :param cards_in_hand: A list. Dependant on the player.
    :return: Returns a random selected card, its int value and the updated deck without
    the drawn card
    """
    card = random.choice(list(deck))
    cards_in_hand.append(card)
    show_list.append(card)
    hand_value = deck.get(card) + value
    deck.pop(card)
    for card in cards_in_hand:
        if hand_value > 21 and "Ace" in card:
            hand_value = hand_value - 10
            cards_in_hand.remove(card)
    return card, hand_value

###################################################################################################################
#####                                                    RESET                                                #####


def reset(list1: list, list2: list, list3: list, list4: list,
          int1: int, int2: int, my_choice_: str, bot_choice_: str, deck_: dict):
    """
    Resets all the factors of the game to begin from scratch everytime you begin a new game.
    :param list1: Your hand related to value.
    :param list2: Your hand related to figures (or cards).
    :param list3: The bots hand related to value.
    :param list4: The bots related to figures (or cards).
    :param int1: The value or score of your cards.
    :param int2: The value or score of the bots hand.
    :param my_choice_: The decision to 'hit' or 'stand'.
    :param bot_choice_: The bots decision to 'hit' or 'stand'.
    :param deck_: The dictionary containing the full deck of cards.
    :return: Gives you back all the values as originals.
    """
    list1 = []
    list2 = []
    list3 = []
    list4 = []
    int1 = 0
    int2 = 0
    bot_choice_ = ""
    my_choice_ = ""
    deck_ = {"Ace of Spades": 11, "2 of Spades": 2, "3 of Spades": 3, "4 of Spades": 4,
             "5 of Spades": 5, "6 of Spades": 6, "7 of Spades": 7, "8 of Spades": 8,
             "9 of Spades": 9, "10 of Spades": 10, "Jack of Spades": 10,
             "Queen of Spades": 10, "King of Spades": 10,
             "Ace of Hearts": 11, "2 of Hearts": 2, "3 of Hearts": 3, "4 of Hearts": 4,
             "5 of Hearts": 5, "6 of Hearts": 6, "7 of Hearts": 7, "8 of Hearts": 8,
             "9 of Hearts": 9, "10 of Hearts": 10, "Jack of Hearts": 10,
             "Queen of Hearts": 10, "King of Hearts": 10,
             "Ace of Clovers": 11, "2 of Clovers": 2, "3 of Clovers": 3, "4 of Clovers": 4,
             "5 of Clovers": 5, "6 of Clovers": 6, "7 of Clovers": 7, "8 of Clovers": 8,
             "9 of Clovers": 9, "10 of Clovers": 10, "Jack of Clovers": 10,
             "Queen of Clovers": 10, "King of Clovers": 10,
             "Ace of Diamonds": 11, "2 of Diamonds": 2, "3 of Diamonds": 3, "4 of Diamonds": 4,
             "5 of Diamonds": 5, "6 of Diamonds": 6, "7 of Diamonds": 7, "8 of Diamonds": 8,
             "9 of Diamonds": 9, "10 of Diamonds": 10, "Jack of Diamonds": 10,
             "Queen of Diamonds": 10, "King of Diamonds": 10}
    return list1, list2, list3, list4, int1, int2, my_choice_, bot_choice_, deck_

###################################################################################################################
#####                                                 BOT PLAYER                                              #####


def bot(bot_score: int) -> str:
    """
    This bot is made to decide if s/he want to get another card from the dealer or not, depending on
    the value of his hand in relation to 21.
    :param bot_score: An int score of the sum value of cards
    :return: A decision of [Y/N] for 'Yes' or 'No' depending on card values.
    """
    if bot_score <= 16:
        bots_choice = "Y"
    else:
        bots_choice = "N"
    return bots_choice


###################################################################################################################
#####                                                    REFEREE                                              #####


def referee(bot_score: int, score: int, show_of_human: list, show_of_robot: list):
    """
    Compares the scores of the player and the bot and dictates a winner.
    :param bot_score: The int value of the sum of values of the cards of the bot.
    :param score: The int value of the sum of values of the cards of the player.
    :return: A decision of [Y/N] for 'Yes' or 'No' depending on card values.
    """
    referee_says = ""
    if bot_score >= 22 and score <= 21:
        referee_says = "DEALER: Ruben went over 21. You win!"
    elif score >= 22 and bot_score <= 21:
        referee_says = "DEALER: You went over 21. Ruben win!"
    elif bot_score and score >= 22:
        referee_says = "DEALER: You both went over 21. Nobody wins!"
    else:
        if bot_score == score:
            referee_says = "DEALER: It's a tie!"
        elif bot_score < score:
            referee_says = "DEALER: You win!"
        else:
            referee_says = "DEALER: Ruben win!"
    return "YOUR HAND: {1}\nRUBEN'S HAND: {0}\n\nWith a score of:\nYOU: {3}\nRUBEN: {2}\n" \
        .format(show_of_robot, show_of_human, bot_score, score) + referee_says


###################################################################################################################
#####                                             SCORES & HAND                                               #####


score = 0
bot_score = 0
my_cards = []
bots_cards = []
show_of_hand = []
show_of_bot = []
another_bot_card = ""
another_card = ""
hit = "Y"
stand = "N"
continue_playing = True



###################################################################################################################
#####                                              INTRO & GAME                                               #####


input("Press ENTER to play some Black Jack")
print()
ready_payer_one = input("DEALER: 'Are you ready to begin?'[Y/N]: ")
print("-" * 72)

while continue_playing:
    while ready_payer_one.upper() != "Y" or "N":
        if ready_payer_one.upper() == "Y":
            hand, score = deal(deck, score, my_cards, show_of_hand)
            hand2, score = deal(deck, score, my_cards, show_of_hand)
            bot_hand, bot_score = deal(deck, bot_score, bots_cards, show_of_bot)
            bot_hand2, bot_score = deal(deck, bot_score, bots_cards, show_of_bot)
            print("You got dealt a {} and a {}\n&".format(hand, hand2))
            print("Ruben, the robot, got dealt a {} and a face-down card".format(bot_hand))
            print("-" * 72)
            while another_bot_card.upper() != stand or another_card.upper() != stand:
                another_card = input("DEALER: Would you like another card?[Y/N]: ")
                another_bot_card = bot(bot_score)
                print("-" * 72)
                if another_card.upper() != hit or stand:
                    if another_card.upper() == hit:
                        hand, score = deal(deck, score, my_cards, show_of_hand)
                        print("You draw a {},".format(hand))
                    elif another_card.upper() == stand:
                        print("You stand,")
                    elif another_card.upper() != hit or stand:
                        another_card = input("DEALER: Dude, that's not a valid option. 'Y' to Hit or 'N' to Stand: ")
                        print("-" * 72)
                        if another_card.upper() == hit:
                            hand, score = deal(deck, score, my_cards, show_of_hand)
                            print("You draw a {}".format(hand))
                        elif another_card.upper() == stand:
                            print("You stand")

                if another_bot_card.upper() != stand:
                    bot_hand, bot_score = deal(deck, bot_score, bots_cards, show_of_bot)
                    print("Ruben draw a {}\n".format(bot_hand) + "-" * 72)
                else:
                    print("Ruben stands\n" + "-" * 72)

            final = referee(bot_score, score, show_of_hand, show_of_bot)
            print(final + "\n" + ("-" * 72))
            my_cards, bots_cards, show_of_hand, show_of_bot, score, bot_score, another_card, another_bot_card, deck = \
                reset(my_cards, bots_cards, show_of_hand, show_of_bot, score, bot_score, another_card, another_bot_card,
                      deck)
            break

        elif ready_payer_one.upper() == "N":
            print("DEALER: Thanks for the interest. Later!")
            break
        else:
            ready_payer_one = input("DEALER: That's not a valid choice. Please, choose 'Y' for Play or 'N' to Quit. ")
            print("-" * 72)
    again = input("DEALER: Type 'Iztaccihuatl' to PLAY AGAIN or 'N' to quit: ")
    print("DEALER: Haha trolled you. For next time, you can type anything to PLAY AGAIN...")
    print("-" * 72)
    if again.upper() == "N":
        print("MAURICIO: Thanks for playing!")
        continue_playing = False

标签: python

解决方案


问题在于您的deal功能。这是它的主体,仅供参考:

card = random.choice(list(deck))
cards_in_hand.append(card)
show_list.append(card)
hand_value = deck.get(card) + value
deck.pop(card)
for card in cards_in_hand:
    if hand_value > 21 and "Ace" in card:
        hand_value = hand_value - 10
        cards_in_hand.remove(card)
return card, hand_value

最后一行:return card, hand_value,大概应该返回随机发牌(您刚刚通过发牌random.choice),以及您当前手牌的总价值。但是,该标识符card正在为您的 for-loop: 重用for card in cards_in_hand。实际上,您从中获得的卡random.choice(list(deck))现在丢失了,并已替换为用于迭代您的cards_in_hand收藏的临时卡。当您到达退货声明时,您的列表card中最后一张卡片的价值将被计算出来。cards_in_hand此外,此错误只会在cards_in_hand不为空时发生,因为如果为空,则永远不会发生循环。

但是,您还忽略了其他一些事情-尽管它们与您描述的问题几乎没有关系。首先,当庄家问我是否想要另一张牌时,没有什么能阻止我抽越来越多的牌直到deck变空,此时这条线......:

card = random.choice(list(deck))

...在deal函数中将引发一个IndexError.

此外,一些常见的初学者错误 - 以下是一些片段:

while ready_payer_one.upper() != "Y" or "N":

if another_card.upper() != hit or stand:

elif another_card.upper() != hit or stand:

这些片段都犯了同样的错误。尽管 Python 是一种高级语言,并且 Python 源代码有时可能读起来像英文句子,但这些布尔表达式并没有按照您认为的方式进行评估。只要"N"orstand是非空字符串,它们就会被评估为“真”,并且如您所知, anor只需要它的一个操作数为真,整个表达式为真。换句话说,您将始终输入这些循环/if 语句的主体。


推荐阅读