【Dison夏令营 Day 03】使用 Python 创建我们自己的 21 点游戏

21 点(英文:Blackjack)是一种在赌场玩的纸牌游戏。这种游戏的参与者不是互相竞争,而是与赌场指定的庄家竞争。在本文中,我们将从头开始创建可在终端上玩的玩家与庄家之间的二十一点游戏。
在这里插入图片描述

二十一点规则

我们将为从未玩过二十一点的读者提供一套简短的规则。21 点的神奇数字是 21。玩家拿到的所有牌的价值相加,如果总和超过 21,玩家就会立即爆牌并输掉。

如果玩家拿到的牌正好是 21,那么玩家就赢了庄家。否则,要想获胜,玩家的牌数总和必须大于庄家的牌数总和。

每张扑克牌的面值都是 10,而 A 可以被算作 1 或 11,这对玩家的获胜机会非常有利。其余牌的价值由其编号决定。

二十一点游戏的发牌过程如下:
  • 一张牌发给朝上的玩家(所有人都能看到)。
  • 庄家给自己发一张所有人都能看到的牌。
  • 另一张牌发给朝上的玩家。
  • 庄家给自己发一张朝下的牌。
  • 玩家必须决定是用现有的牌站着还是再拿一张牌。
  • 如果玩家决定打牌,庄家会再发一张牌。
  • 如果玩家决定不出牌,庄家就会亮出隐藏的牌。
  • 庄家无权决定玩家是跟还是不跟。一般规则是,如果庄家牌的总和小于 17,庄家需要继续打出更多的牌。
  • 一旦庄家牌的总和达到或超过 17 点,庄家就有义务不出牌。
  • 根据最后的牌数决定胜负。

了解规则后,21 点游戏的编程就变得简单了。从零开始创建基于终端的游戏需要三个主要部分:游戏设计、游戏逻辑和玩家互动管理。

用 Python 设计二十一点

首先,我们将进行游戏设计。我们的任务是在终端上有效地显示一系列牌,如下图所示。

在这里插入图片描述
我们需要一个能打印卡片序列且与卡片数量无关的函数。此外,它还必须提供在需要时打印隐藏卡片的功能。

下面的代码解决了我们的问题。

# 打印卡片的功能
def print_cards(cards, hidden):
         
    s = ""
    for card in cards:
        s = s + "\t ________________"
    if hidden:
        s += "\t ________________"
    print(s)
 
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|                |"    
    print(s)
 
    s = ""
    for card in cards:
        if card.value == '10':
            s = s + "\t|  {}            |".format(card.value)
        else:
            s = s + "\t|  {}             |".format(card.value)  
    if hidden:
        s += "\t|                |"    
    print(s)
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|      * *       |"
    print(s)    
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|    *     *     |"
    print(s)    
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|   *       *    |"
    print(s)    
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|   *       *    |"
    print(s)    
 
    s = ""
    for card in cards:
        s = s + "\t|       {}        |".format(card.suit)
    if hidden:
        s += "\t|          *     |"
    print(s)    
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|         *      |"
    print(s)    
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|        *       |"
    print(s)
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|                |"
    print(s)
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|                |"
    print(s)    
 
    s = ""
    for card in cards:
        if card.value == '10':
            s = s + "\t|            {}  |".format(card.value)
        else:
            s = s + "\t|            {}   |".format(card.value)
    if hidden:
        s += "\t|        *       |"        
    print(s)    
         
    s = ""
    for card in cards:
        s = s + "\t|________________|"
    if hidden:
        s += "\t|________________|"
    print(s)        
 
    print()

每张卡片的详细信息都存储为一个卡片对象。print_cards() 函数的第二个参数是一个布尔值,表示是否显示隐藏的卡片。

创建卡片

在类和对象的帮助下,我们可以创建一个花色和数值的组合来表示一张 “扑克牌”。在二十一点游戏中,一张牌有三个属性:花色、代表值和作为分数的值。

所有上述属性都在下面的 "卡 "类中维护。

# 卡片类别的定义
class Card:
    def __init__(self, suit, value, card_value):
         
        # 纸牌的花色,如黑桃和梅花
        self.suit = suit
 
        # 表示牌的价值,如 A 表示 Ace,K 表示 King
        self.value = value
 
        # 卡片的分值,如 10 分代表国王
        self.card_value = card_value

使用上述类,我们可以创建一副包含 52 个 Card 对象的纸牌。

一些基本价值观

每种纸牌游戏都需要一些基本价值,如花色类型、纸牌类型以及每张纸牌的价值。

为了更方便理解,我代码和备注都用全英文了

# The type of suit
suits = ["Spades", "Hearts", "Clubs", "Diamonds"]
 
# The suit value 
suits_values = {"Spades":"\u2664", "Hearts":"\u2661", "Clubs": "\u2667", "Diamonds": "\u2662"}
 
# The type of card
cards = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
 
# The card value
cards_values = {"A": 11, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "10":10, "J":10, "Q":10, "K":10}

这里需要注意的一点是,A 最初被标记为 11 点。这一策略背后的理念是,每当玩家/发牌者的分数似乎超过 21 分时,我们就可以将 A 的分数(如果发牌)减为 1 分。

我们稍后将在本文中看到减分的实施。

生成一副扑克牌

一副普通的扑克牌由 52 张牌组成,每张牌都有不同的花色和价值组合。利用上述基本值和卡片类,我们可以生成一副扑克牌。

# The deck of cards
deck = []
 
# Loop for every type of suit
for suit in suits:
 
    # Loop for every type of card in a suit
    for card in cards:
 
        # Adding card to the deck
        deck.append(Card(suits_values[suit], card, cards_values[card]))

实际上,21 点游戏涉及多副扑克牌,因此可以重复使用上述循环来填充多副扑克牌。

新创建的牌面将传递给执行游戏的函数。

blackjack_game(deck)      

让我们来了解一下玩家和电脑发牌员之间 21 点游戏单次迭代背后的游戏逻辑。

声明重要的游戏变量

在任何时刻,我们都需要以下游戏变量:

  • 玩家和庄家的发牌列表。
  • 双方牌值的总和。
# Function for a single game of blackjack
def blackjack_game(deck):
 
    global cards_values
 
    # Cards for both dealer and player
    player_cards = []
    dealer_cards = []
 
    # Scores for both dealer and player
    player_score = 0
    dealer_score = 0

当我们设计游戏逻辑时,这些游戏变量就会发挥作用。

Python 二十一点游戏逻辑

整个游戏逻辑都围绕着发牌和玩家对击中或站立的选择。只要我们处理好上述两件事,今天的工作就完成了。

发牌的第一阶段:必发牌

初始发牌包括给玩家和庄家两张牌。不过,庄家的第二张牌必须保持未知。

# Initial dealing for player and dealer
while len(player_cards) < 2:
 
    # Randomly dealing a card
    player_card = random.choice(deck)
    player_cards.append(player_card)
    deck.remove(player_card)
 
    # Updating the player score
    player_score += player_card.card_value
 
    # In case both the cards are Ace, make the first ace value as 1 
    if len(player_cards) == 2:
        if player_cards[0].card_value == 11 and player_cards[1].card_value == 11:
            player_cards[0].card_value = 1
            player_score -= 10
 
    # Print player cards and score      
    print("PLAYER CARDS: ")
    print_cards(player_cards, False)
    print("PLAYER SCORE = ", player_score)
 
    input()
 
    # Randomly dealing a card
    dealer_card = random.choice(deck)
    dealer_cards.append(dealer_card)
    deck.remove(dealer_card)
 
    # Updating the dealer score
    dealer_score += dealer_card.card_value
 
    # Print dealer cards and score, keeping in mind to hide the second card and score
    print("DEALER CARDS: ")
    if len(dealer_cards) == 1:
        print_cards(dealer_cards, False)
        print("DEALER SCORE = ", dealer_score)
    else:
        print_cards(dealer_cards[:-1], True)    
        print("DEALER SCORE = ", dealer_score - dealer_cards[-1].card_value)
 
 
    # In case both the cards are Ace, make the second ace value as 1 
    if len(dealer_cards) == 2:
        if dealer_cards[0].card_value == 11 and dealer_cards[1].card_value == 11:
            dealer_cards[1].card_value = 1
            dealer_score -= 10
 
    input()
 
# Player gets a blackjack   
if player_score == 21:
    print("PLAYER HAS A BLACKJACK!!!!")
    print("PLAYER WINS!!!!")
    quit()

对于一个看似简单的交易来说,这可能是一个很大的挑战。让我们来了解一下上述代码所涉及的过程:

  • 主循环一直运行到玩家和庄家各拿到两张牌为止。
  • 庄家从牌组中随机抽取一张牌,然后在下一步中将这张牌从牌组中移除。
  • 这张牌的价值加到玩家的分数中。
  • 同样,庄家也会随机抽取一张牌,并将其价值计入庄家得分。
  • 玩家的牌正常显示在屏幕上。
  • 庄家的牌会小心显示,不会显示第二张牌及其牌值。
  • 如果任何一方拿到双 A,则会调整其分数,以确保双方都不爆牌。
  • 上述所有步骤顺利完成后,我们进入第二阶段发牌。

注:玩家和庄家的分数调整有细微差别。前者调整的是第一张牌的价值,而后者调整的是第二张牌的价值。

之所以要调整第二张牌的价值,是因为如果我们调整了第一张牌的价值,就会暴露隐藏牌是 Ace 的身份。

最后要做的一件事是检查玩家是否已经拥有 21 点。如果有,玩家获胜,游戏结束。

注:input() 函数会暂停程序,直到玩家按下 "ENTER "键。这样可以防止所有游戏事件的快速回放。

clear()函数负责清除终端,为游戏提供一个干净的界面。

第二阶段发牌:玩家的选择

发牌的第二阶段取决于玩家的决定,是要另一张牌来提高分数,还是维持现有的牌。

# Print dealer and player cards
print("DEALER CARDS: ")
print_cards(dealer_cards[:-1], True)
print("DEALER SCORE = ", dealer_score - dealer_cards[-1].card_value)
 
print() 
 
print("PLAYER CARDS: ")
print_cards(player_cards, False)
print("PLAYER SCORE = ", player_score)
 
# Managing the player moves
while player_score < 21:
    choice = input("Enter H to Hit or S to Stand : ")
 
    # Sanity checks for player's choice
    if len(choice) != 1 or (choice.upper() != 'H' and choice.upper() != 'S'):
        clear()
        print("Wrong choice!! Try Again")
 
    # If player decides to HIT
    if choice.upper() == 'H':
 
        # Dealing a new card
        player_card = random.choice(deck)
        player_cards.append(player_card)
        deck.remove(player_card)
 
        # Updating player score
        player_score += player_card.card_value
 
        # Updating player score in case player's card have ace in them
        c = 0
        while player_score > 21 and c < len(player_cards):
            if player_cards[c].card_value == 11:
                player_cards[c].card_value = 1
                player_score -= 10
                c += 1
            else:
                c += 1 
 
        clear()     
 
        # Print player and dealer cards
        print("DEALER CARDS: ")
        print_cards(dealer_cards[:-1], True)
        print("DEALER SCORE = ", dealer_score - dealer_cards[-1].card_value)
 
        print()
 
        print("PLAYER CARDS: ")
        print_cards(player_cards, False)
        print("PLAYER SCORE = ", player_score)
         
    # If player decides to Stand
    if choice.upper() == 'S':
        break
 
# Check if player has a Blackjack
if player_score == 21:
    print("PLAYER HAS A BLACKJACK")
    quit()
 
# Check if player busts
if player_score > 21:
    print("PLAYER BUSTED!!! GAME OVER!!!")
    quit()

玩家决定是打还是不打,直到分数超过 21 分或玩家决定不打为止。玩家发牌的数量没有限制,只有分数限制。

玩家每决定击中一次,就会从牌组中发出一张新牌,分数也会随之更新。如前所述,A 可以算作 1 或 11。如果分数超过 21,一段特殊的代码会将 A 的值从 11 转换为 1。

当玩家对当前分数满意时,他就会起立。当他这样做时,我们会在进行一些强制性检查(如二十一点或爆牌情况)后进入发牌的最后阶段。

发牌的最后阶段:庄家的牌

在发牌的最后阶段,庄家的暗牌会被揭开,庄家的分数也会被揭开。根据二十一点的标准规则,庄家必须给自己发更多的牌,直到分数大于或等于 17。

# Managing the dealer moves
while dealer_score < 17:
    clear() 
 
    print("DEALER DECIDES TO HIT.....")
 
    # Dealing card for dealer
    dealer_card = random.choice(deck)
    dealer_cards.append(dealer_card)
    deck.remove(dealer_card)
 
    # Updating the dealer's score
    dealer_score += dealer_card.card_value
 
    # Updating player score in case player's card have ace in them
    c = 0
    while dealer_score > 21 and c < len(dealer_cards):
        if dealer_cards[c].card_value == 11:
            dealer_cards[c].card_value = 1
            dealer_score -= 10
            c += 1
        else:
            c += 1
 
    # print player and dealer cards
    print("PLAYER CARDS: ")
    print_cards(player_cards, False)
    print("PLAYER SCORE = ", player_score)
 
    print()
 
    print("DEALER CARDS: ")
    print_cards(dealer_cards, False)
    print("DEALER SCORE = ", dealer_score)
 
    input()

庄家继续击球,直到分数越过 17 分为止。如果需要,我们也有类似的方法将 A 的牌值从 11 转换为 1。

游戏终结

当庄家的分数是 17 或更多时,我们就进入 “终局”,即比较牌局的胜负。可能会出现以下几种情况:

  • 庄家爆牌 - 庄家的分数超过 21。
  • 庄家有 21 点 - 庄家的准确分数是 21。
  • 平局 - 玩家和庄家的分数相同。
  • 闲家赢 - 闲家的分数超过庄家。
  • 庄家赢 - 庄家的分数超过闲家。

我们会检查上述每种可能性,并宣布获胜者。

# Dealer busts
if dealer_score > 21:        
    print("DEALER BUSTED!!! YOU WIN!!!") 
    quit()  
 
# Dealer gets a blackjack
if dealer_score == 21:
    print("DEALER HAS A BLACKJACK!!! PLAYER LOSES")
    quit()
 
# TIE Game
if dealer_score == player_score:
    print("TIE GAME!!!!")
 
# Player Wins
elif player_score > dealer_score:
    print("PLAYER WINS!!!")                 
 
# Dealer Wins
else:
    print("DEALER WINS!!!")  

至此,玩家与庄家之间的 21 点游戏的单次迭代结束。

二十一点游戏的完整 Python 代码

import random
import os
import time
 
# The Card class definition
class Card:
    def __init__(self, suit, value, card_value):
         
        # Suit of the Card like Spades and Clubs
        self.suit = suit
 
        # Representing Value of the Card like A for Ace, K for King
        self.value = value
 
        # Score Value for the Card like 10 for King
        self.card_value = card_value
 
# Clear the terminal
def clear():
    os.system("clear")
 
# Function to print the cards
def print_cards(cards, hidden):
         
    s = ""
    for card in cards:
        s = s + "\t ________________"
    if hidden:
        s += "\t ________________"
    print(s)
 
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|                |"    
    print(s)
 
    s = ""
    for card in cards:
        if card.value == '10':
            s = s + "\t|  {}            |".format(card.value)
        else:
            s = s + "\t|  {}             |".format(card.value)  
    if hidden:
        s += "\t|                |"    
    print(s)
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|      * *       |"
    print(s)    
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|    *     *     |"
    print(s)    
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|   *       *    |"
    print(s)    
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|   *       *    |"
    print(s)    
 
    s = ""
    for card in cards:
        s = s + "\t|       {}        |".format(card.suit)
    if hidden:
        s += "\t|          *     |"
    print(s)    
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|         *      |"
    print(s)    
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|        *       |"
    print(s)
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|                |"
    print(s)
 
    s = ""
    for card in cards:
        s = s + "\t|                |"
    if hidden:
        s += "\t|                |"
    print(s)    
 
    s = ""
    for card in cards:
        if card.value == '10':
            s = s + "\t|            {}  |".format(card.value)
        else:
            s = s + "\t|            {}   |".format(card.value)
    if hidden:
        s += "\t|        *       |"        
    print(s)    
         
    s = ""
    for card in cards:
        s = s + "\t|________________|"
    if hidden:
        s += "\t|________________|"
    print(s)        
 
    print()
 
 
# Function for a single game of blackjack
def blackjack_game(deck):
 
    # Cards for both dealer and player
    player_cards = []
    dealer_cards = []
 
    # Scores for both dealer and player
    player_score = 0
    dealer_score = 0
 
    clear()
 
    # Initial dealing for player and dealer
    while len(player_cards) < 2:
 
        # Randomly dealing a card
        player_card = random.choice(deck)
        player_cards.append(player_card)
        deck.remove(player_card)
 
        # Updating the player score
        player_score += player_card.card_value
 
        # In case both the cards are Ace, make the first ace value as 1 
        if len(player_cards) == 2:
            if player_cards[0].card_value == 11 and player_cards[1].card_value == 11:
                player_cards[0].card_value = 1
                player_score -= 10
 
        # Print player cards and score      
        print("PLAYER CARDS: ")
        print_cards(player_cards, False)
        print("PLAYER SCORE = ", player_score)
 
        input()
 
        # Randomly dealing a card
        dealer_card = random.choice(deck)
        dealer_cards.append(dealer_card)
        deck.remove(dealer_card)
 
        # Updating the dealer score
        dealer_score += dealer_card.card_value
 
        # Print dealer cards and score, keeping in mind to hide the second card and score
        print("DEALER CARDS: ")
        if len(dealer_cards) == 1:
            print_cards(dealer_cards, False)
            print("DEALER SCORE = ", dealer_score)
        else:
            print_cards(dealer_cards[:-1], True)    
            print("DEALER SCORE = ", dealer_score - dealer_cards[-1].card_value)
 
 
        # In case both the cards are Ace, make the second ace value as 1 
        if len(dealer_cards) == 2:
            if dealer_cards[0].card_value == 11 and dealer_cards[1].card_value == 11:
                dealer_cards[1].card_value = 1
                dealer_score -= 10
 
        input()
 
    # Player gets a blackjack   
    if player_score == 21:
        print("PLAYER HAS A BLACKJACK!!!!")
        print("PLAYER WINS!!!!")
        quit()
 
    clear()
 
    # Print dealer and player cards
    print("DEALER CARDS: ")
    print_cards(dealer_cards[:-1], True)
    print("DEALER SCORE = ", dealer_score - dealer_cards[-1].card_value)
 
    print() 
 
    print("PLAYER CARDS: ")
    print_cards(player_cards, False)
    print("PLAYER SCORE = ", player_score)
 
    # Managing the player moves
    while player_score < 21:
        choice = input("Enter H to Hit or S to Stand : ")
 
        # Sanity checks for player's choice
        if len(choice) != 1 or (choice.upper() != 'H' and choice.upper() != 'S'):
            clear()
            print("Wrong choice!! Try Again")
 
        # If player decides to HIT
        if choice.upper() == 'H':
 
            # Dealing a new card
            player_card = random.choice(deck)
            player_cards.append(player_card)
            deck.remove(player_card)
 
            # Updating player score
            player_score += player_card.card_value
 
            # Updating player score in case player's card have ace in them
            c = 0
            while player_score > 21 and c < len(player_cards):
                if player_cards[c].card_value == 11:
                    player_cards[c].card_value = 1
                    player_score -= 10
                    c += 1
                else:
                    c += 1 
 
            clear()     
 
            # Print player and dealer cards
            print("DEALER CARDS: ")
            print_cards(dealer_cards[:-1], True)
            print("DEALER SCORE = ", dealer_score - dealer_cards[-1].card_value)
 
            print()
 
            print("PLAYER CARDS: ")
            print_cards(player_cards, False)
            print("PLAYER SCORE = ", player_score)
             
        # If player decides to Stand
        if choice.upper() == 'S':
            break
 
 
    clear() 
 
    # Print player and dealer cards
    print("PLAYER CARDS: ")
    print_cards(player_cards, False)
    print("PLAYER SCORE = ", player_score)
 
    print()
    print("DEALER IS REVEALING THE CARDS....")
 
    print("DEALER CARDS: ")
    print_cards(dealer_cards, False)
    print("DEALER SCORE = ", dealer_score)
 
    # Check if player has a Blackjack
    if player_score == 21:
        print("PLAYER HAS A BLACKJACK")
        quit()
 
    # Check if player busts
    if player_score > 21:
        print("PLAYER BUSTED!!! GAME OVER!!!")
        quit()
 
    input() 
 
    # Managing the dealer moves
    while dealer_score < 17:
        clear() 
 
        print("DEALER DECIDES TO HIT.....")
 
        # Dealing card for dealer
        dealer_card = random.choice(deck)
        dealer_cards.append(dealer_card)
        deck.remove(dealer_card)
 
        # Updating the dealer's score
        dealer_score += dealer_card.card_value
 
        # Updating player score in case player's card have ace in them
        c = 0
        while dealer_score > 21 and c < len(dealer_cards):
            if dealer_cards[c].card_value == 11:
                dealer_cards[c].card_value = 1
                dealer_score -= 10
                c += 1
            else:
                c += 1
 
        # print player and dealer cards
        print("PLAYER CARDS: ")
        print_cards(player_cards, False)
        print("PLAYER SCORE = ", player_score)
 
        print()
 
        print("DEALER CARDS: ")
        print_cards(dealer_cards, False)
        print("DEALER SCORE = ", dealer_score)      
 
        input()
 
    # Dealer busts
    if dealer_score > 21:        
        print("DEALER BUSTED!!! YOU WIN!!!") 
        quit()  
 
    # Dealer gets a blackjack
    if dealer_score == 21:
        print("DEALER HAS A BLACKJACK!!! PLAYER LOSES")
        quit()
 
    # TIE Game
    if dealer_score == player_score:
        print("TIE GAME!!!!")
 
    # Player Wins
    elif player_score > dealer_score:
        print("PLAYER WINS!!!")                 
 
    # Dealer Wins
    else:
        print("DEALER WINS!!!")                 
 
if __name__ == '__main__':
 
    # The type of suit
    suits = ["Spades", "Hearts", "Clubs", "Diamonds"]
 
    # The suit value 
    suits_values = {"Spades":"\u2664", "Hearts":"\u2661", "Clubs": "\u2667", "Diamonds": "\u2662"}
 
    # The type of card
    cards = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
 
    # The card value
    cards_values = {"A": 11, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "10":10, "J":10, "Q":10, "K":10}
 
    # The deck of cards
    deck = []
 
    # Loop for every type of suit
    for suit in suits:
 
        # Loop for every type of card in a suit
        for card in cards:
 
            # Adding card to the deck
            deck.append(Card(suits_values[suit], card, cards_values[card]))
     
    blackjack_game(deck) 

读者不必遵循整个编码顺序。通过增加多人对庄家的功能,可以对上述代码进行各种修改。

结论

二十一点游戏起初看似简单随意,但只有当玩家遵循某些策略(如算牌)时,游戏才会变得复杂。

世界上流传着许多不同版本的 21 点游戏,如瑞典酒吧 21 点游戏和家庭游戏 21 点游戏。好奇的读者可以了解这些变体,并尝试利用本文中获得的知识来实施它们。

感谢大家花时间阅读我的文章,你们的支持是我不断前进的动力。期望未来能为大家带来更多有价值的内容,请多多关注我的动态!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/755818.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python实战因果推断】6_元学习器1

目录 Metalearners for Discrete Treatments T-Learner 简单回顾一下&#xff0c;在之前的部分中&#xff0c;你们的重点是干预效果的异质性&#xff0c;也就是确定各单位对治疗的不同反应。在此框架下&#xff0c;您希望估算 或连续情况下的 。换句话说&#xff0c;您想知道…

“深入解析操作系统核心:进程管理与并发艺术“

操作系统中最核心的概念是进程:这是对正在运行程序的ー个抽象 并行 并发 “在任何多道程序设计系统中,CPU由一个进程快速切换至另ー个进程,使每个进程各运行几十或几百毫秒。严格地说,在某ー个瞬间,CPU只能运行ー个进程。但在1秒钟内,它可能运行多个进程,这样就产生并行的错觉…

【RAG】FoRAG:面向网络增强型长形式问答的事实性优化RAG

一、解决问题 在基于网络的长形式问答&#xff08;Web-enhanced Long-form Question Answering, LFQA&#xff09;任务中&#xff0c;现有RAG在生成答案时存在的问题&#xff1a; 事实性不足&#xff1a;研究表明&#xff0c;现有系统生成的答案中只有大约一半的陈述能够完全得…

SpringBoot学习04-[定制SpringMVC]

定制SpringMVC 定制SpringMvc的自动配置定制springmvc-configurePathMatch配置定制SpringMVC-拦截器Interceptor定制SpringMVC-CORS配置全局cors配置针对某个方法加跨域解决 WebMvcConfigurer原理定制SpringMVC-JSONJSON开发jackson的使用定制化json序列化和反序列化 JSON国际化…

Kafka面试必备:深度解析Replica副本的作用与机制

我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货! Hey大家好!我是小米,一个超级喜欢分享技术干货的大哥哥!今天咱们来聊聊阿里巴巴面试题中的一个热门话题:Kafka中的Replica副本作用。这可是个既基础…

供应商关系管理(SRM)中的供应商绩效评估

供应商绩效评估是供应商关系管理&#xff08;SRM&#xff09;的核心组成部分&#xff0c;它涉及到对供应商在合作过程中的表现进行全面的分析和评价。一个有效的供应商绩效评估系统不仅可以帮助企业识别和解决供应链中的潜在问题&#xff0c;还可以促进供应商的持续改进和优化&…

npm创建一个空的vue3项目的方法或者pnpm创建vue3项目

1、前提我们已经安装了npm&#xff0c;或者pnpm 2、我们用npm来创建vue3项目 快速上手 | Vue.js 官网地址 这里我安装是的 node v18.20.3 以下是安装过程 &#xff1a; npm create vuelatest 根据自己的需要进行创建即可。 3、我们用pnpm来创建vite vue3项目 pnpm create …

【算法专题--栈】栈的压入、弹出序列 -- 高频面试题(图文详解,小白一看就懂!!)

目录 一、前言 二、题目描述 三、解题方法 &#x1f4a7;栈模拟法&#x1f4a7;-- 双指针 ⭐ 解题思路 ⭐ 案例图解 四、总结与提炼 五、共勉 一、前言 栈的压入、弹出序列 这道题&#xff0c;可以说是--栈专题--&#xff0c;最经典的一道题&#xff0c;也是在…

LinkedIn被封原因和解封方法

对于初识领英和对领英生态规则不熟悉的人来说&#xff0c;很容易造成领英账号被封号(被限制登录)的情况&#xff0c;那么如何才能避免和解决领英帐号被封号(被限制登录)的难题呢&#xff1f; 领英帐号被封号或被限制登录主要会有两类情况。 首先要搞清楚&#xff0c; Linkedi…

“ONLYOFFICE 8.1版本评测:功能更强大,用户体验更佳”

最新版本的在线编辑器已经发布 ONLYOFFICE在线编辑器的最新版本8.1已经发布&#xff0c;整个套件带来了30多个新功能和432个bug修复。这个强大的文档编辑器支持处理文本文档、电子表格、演示文稿、可填写的表单和PDF&#xff0c;并允许多人在线协作&#xff0c;同时支持AI集成…

IP白名单及其作用解析

在网络安全领域&#xff0c;IP白名单是一项至关重要的策略&#xff0c;它允许特定的IP地址或地址范围访问网络资源&#xff0c;从而确保只有受信任的终端能够连接。下面&#xff0c;我们将深入探讨IP白名单的定义、作用以及实施时的关键考虑因素。 一、IP白名单的定义 IP白名单…

利用python爬取上证指数股吧评论并保存到mongodb数据库

大家好&#xff0c;我是带我去滑雪&#xff01; 东方财富网是中国领先的金融服务网站之一&#xff0c;以提供全面的金融市场数据、资讯和交易工具而闻名。其受欢迎的“股吧”论坛特别适合爬取股票评论&#xff0c;东方财富网的股吧聚集了大量投资者和金融分析师&#xff0c;他们…

GOROOT GOPATH GOPROXY GO111MODULE

GOROOT GOROOT代表Go的安装目录。可执行程序go(或go.exe)和gofmt(或gofmt.exe)位于 GOROOT/bin目录中。 配置GOROOT环境变量&#xff0c;其值为Go的安装目录&#xff1b;然后在环境变量PATH中添加GOROOT/bin路径。 注意&#xff1a;GOROOT变量只是代表了安装目录&#xff0c;不…

DiskGeniusV5.6.0.1565发布!

DiskGenius是一款功能强大的磁盘管理和数据恢复工具&#xff0c;V5.6.0.1565上线。新版本变化比较大&#xff0c;增加新的功能&#xff0c;修正已经问题&#xff0c;值得试一下。提醒大家&#xff0c;磁盘管理软件涉及数据安全&#xff0c;请始终使用最新版本&#xff01; 下面…

Linux开发讲课18--- “>file 2>1“ 和 “2>1 >file“ 的区别

在 Bash 脚本和命令行操作中&#xff0c;输出重定向是一项基本且强大的功能。它允许用户控制命令的输出流&#xff0c;将数据从一个地方转移到另一个地方&#xff0c;实现更加灵活和高效的工作流程。本文旨在记录 Bash 中几种常见的输出重定向方法&#xff0c;包括: -. > fi…

计算机Java项目|基于SpringBoot的新闻稿件管理系统

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、Python项目、前端项目、人工智能与大数据、简…

密码学:用随机函数隐藏指纹

英文中e的出现频率高&#xff0c;加密后&#xff0c;频率最高的那个符号代表e。这是历史上的一次真实案例。这些符号的概率&#xff0c;叫做“指纹”。 把e加密成2个符号&#xff0c;用随机函数选择&#xff0c;例如70%概率下选择符号1&#xff0c;30%选择符号2。解密时&#…

启智畅想:AI集装箱箱号识别系统,解决方案提供商

AI集装箱箱号识别系统 当前,智能卡口管理行业正处于快速发展的阶段。随着物联网、大数据、人工智能等技术的不断进步,智能卡口管理系统已经能够实现对集装箱运输的全程跟踪、监控和管理,大大提高了管理效率和安全性。然而,市场上现有的智能卡口管理系统仍然存在一些痛点问题,如…

Spring容器的启动过程及留给开发者的可拓展点

一、Spring容器启动经过了哪些过程&#xff1f; 1、首先需要加载读取到应用环境中的配置&#xff0c;比如要加载的bean的class的包路径等信息。 【读取配置】 2、再就需要找到哪些类是需要spring进行类实例创建并管理的&#xff0c;扫描到具体的Class及Class元信息上的一些注…

【漏洞复现】电信网关配置管理系统——命令执行

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 电信网关配置管理系统是一个用于管理和配置电信网关设备的软件系…