其他分享
首页 > 其他分享> > 21点(BlackJack)扑克游戏,挑战用100行代码实现

21点(BlackJack)扑克游戏,挑战用100行代码实现

作者:互联网

21点(BlackJack)扑克游戏,挑战用100行代码实现


本人平时喜欢与朋友们玩玩21点与德州扑克,特别是看了《决胜21点》后,很想自己写一款简单的21点游戏。趁着清明节小长假闲来无事在家中试着实现了一下。感兴趣的朋友可以和我一起练习!

首先我做的,就是把实现的路径规划下来,以下就是我的大致思路:

  1. 将游戏规则写下来
  2. 将规则编程化

一. 21点游戏规则
1. 四种花色,13张牌,共52张牌。然而在21点游戏中,花色没有任何权重,也没有孰强孰弱之分,所以其实就是A,2,3,4,5,6,7,8,9,10,10(J),10(Q),10(K)乘以4
2. A比较特殊,可以算作是1,也可以算作是11,要看情况来区别对待
3. Dealer进行发牌,给选手发两张牌,给自己发两张牌,选手看得到Dealer的其中一张牌
4. 选手选择是否要牌,如果要,系统发一张牌,直到爆掉之前,选手可以一直要牌
5. 选手选择是否要牌,如果不要,dealer继续给自己发牌。直到爆牌或者到21点,不到17一直要牌

二. 将规则编程化

  1. 首先我们看第一个规则,“四种花色,13张牌,共52张牌。然而在21点游戏中,花色没有任何权重,也没有孰强孰弱之分,所以其实就是A,2,3,4,5,6,7,8,9,10,10(J),10(Q),10(K)乘以4”。我们建立一个牌库。我们将牌库命名为cards,并且暂且先把A当成是11点。
cards = [
    11,2,3,4,5,6,7,8,9,10,10,10,10,
    11,2,3,4,5,6,7,8,9,10,10,10,10,
    11,2,3,4,5,6,7,8,9,10,10,10,10,
    11,2,3,4,5,6,7,8,9,10,10,10,10
]
  1. “A比较特殊,可以算作是1,也可以算作是11,要看情况来区别对待”。于是,我们为A牌专门创建一个规则。
def player_if_ace(player_cards):#判断玩家/庄家手中是否有A牌
    if 11 in player_cards:#假设玩家/庄家拿到了A牌(之前我们将A预先设置成了11点)
        if sum(player_cards) > 21:#当玩家/庄家的所有手牌相加超过了21点,那自然就要把11点往下降变成1点,从而避免爆牌
            location = player_cards.index(11)#在list中找到玩家/庄家的11点所在的位置
            player_cards[location] = 1#找到list中的11点,并替换成1点
            return player_cards#将新的1点返回到玩家/庄家手牌中
        else:
            return player_cards#如果手牌相加并没有到21点,则A保持11点
    else:
        return player_cards#如果玩家/庄家并没有A,则保持现状
  1. “Dealer进行发牌,给选手发两张牌,给自己发两张牌,选手看得到Dealer的其中一张牌”
    player_cards = [random.choice(cards), random.choice(cards)]#玩家的两张手牌随机生成
    player_cards = player_if_ace(player_cards)#判断手牌中是否有A,再进行新的定义

    dealer_cards = [random.choice(cards), random.choice(cards)]#庄家的两张手牌随机生成
    dealer_cards = player_if_ace(dealer_cards)#判断手牌中是否有A,再进行新的定义

系统进行提示,告诉我们自己的两张牌是什么,相加后是什么,并且和我们说庄家的其中一张牌是什么

    print('******* 游戏开始,你的牌是:' + str(player_cards[0]) + '和' 
          + str(player_cards[1]) + ' *******\n' + '总和是' 
          + str(sum(player_cards)) + '\n' + 'Dealer的牌有一张是' 
          + str(dealer_cards[0]) + '\n')
  1. “选手选择是否要牌,如果要,系统发一张牌,直到爆掉之前,选手可以一直要牌”。在这我们为选手要牌单独写一个逻辑。
def add_card(player_cards, dealer_cards):#玩家选择是否要拍
    player_choice = input('是否要牌?Y/N')#玩家进行输入
    if 'y' in player_choice or 'Y' in player_choice: #如果选择要牌
        player_cards.append(random.choice(cards))#玩家牌池中再生成一张随机手牌
        player_cards = player_if_ace(player_cards)#再次判断是否有A
        return player_cards, dealer_cards, player_choice#返回值
    else:
        dealer_control(dealer_cards,player_cards)#如果玩家不要牌,直接进入庄家操作
        return player_cards, dealer_cards, player_choice#返回值

这里面倒数第二行,我们看一下。如果玩家不需要牌的话,系统直接进行庄家的操作,这时候胜负马上就能揭晓了。再等待一下~!

def dealer_control(dealer_cards,player_cards):#庄家的操作
    print('Dealer翻牌了,总和是' + str(sum(dealer_cards)))#显示dealer的手牌之和
    time.sleep(2)#增加体验感,空两秒等待发牌过程:)
    if sum(player_cards) > sum(dealer_cards):#如果开牌没有玩家的手牌之和大,才选择要牌
        while sum(dealer_cards) < 17:#在casino中,庄家在未拿到17点以上的牌时不可停止要牌
            dealer_cards.append(random.choice(cards))#给dealer加牌
            dealer_cards = player_if_ace(dealer_cards)#判断是否有A
            print('Dealer加牌了,拿到一张' + str(dealer_cards[-1]) + '当前Dealer总和是' + str(sum(dealer_cards)))
            time.sleep(2)
            return dealer_cards#返回最新值
    else:
        return dealer_cards#如果开牌直接比选手的大了,那还加啥牌,直接返回值
  1. 上边是玩家需要加牌的状况,如果不要加牌,则直接开牌对比。这边的代码与上面的相似。之后我们写一个,进行最终判断的代码:
    if sum(dealer_cards) > 21:#如果庄家手牌大于21点,庄家爆牌,玩家赢
        print('Dealer爆牌,恭喜,你赢了')
        won += 1
    else:
        if sum(dealer_cards) > sum(player_cards):#如果庄家比玩家手牌要打,庄赢
            print('对不起,你输了')
            lost += 1
        elif sum(dealer_cards) == sum(player_cards):#点数一样,平局
            print('平局')
            tie += 1
        else:
            print('恭喜,你赢了')#玩家手牌比庄家大,玩家赢
            won += 1
            time.sleep(2)
  1. 设计完以上代码后,我想到,可能有些朋友希望用自己的策略来测试胜率,所以我们也顺便写一个可以记录每一局输赢,并且将总局数,与胜率给体现出来。
    games_played = int(won) + int(lost) + int(tie)#用于算一共玩了几局
    chance = won / games_played * 100#用于计算胜率
    print('一共进行了' + str(games_played) + '局' + '\n' + '赢的概率是' + str(chance) + '%')
    return won, lost, tie#返回值

到这边,我们的程序基本框架已经出来了,之后就是将程序细化,并且完成。
以下是全部的代码:

import random
import time

cards = [
    11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10,
    11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10,
    11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10,
    11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10
]


def player_if_ace(player_cards):#判断玩家/庄家手中是否有A牌
    if 11 in player_cards:#假设玩家拿到了A牌(之前我们将A预先设置成了11点)
        if sum(player_cards) > 21:#当玩家的所有手牌相加超过了21点,那自然就要把11点往下降变成1点,从而避免爆牌
            location = player_cards.index(11)#在list中找到玩家的11点所在的位置
            player_cards[location] = 1#找到list中的11点,并替换成1点
            return player_cards#将新的1点返回到玩家手牌中
        else:
            return player_cards#如果手牌相加并没有到21点,则A保持11点
    else:
        return player_cards#如果玩家并没有A,则保持现状


def dealer_control(dealer_cards,player_cards):#庄家的操作
    print('Dealer翻牌了,总和是' + str(sum(dealer_cards)))#显示dealer的手牌之和
    time.sleep(2)#增加体验感,空两秒等待发牌过程:)
    if sum(player_cards) > sum(dealer_cards):#如果开牌没有玩家的手牌之和大,才选择要牌
        while sum(dealer_cards) < 17:#在casino中,庄家在未拿到17点以上的牌时不可停止要牌
            dealer_cards.append(random.choice(cards))#给dealer加牌
            dealer_cards = player_if_ace(dealer_cards)#判断是否有A
            print('Dealer加牌了,拿到一张' + str(dealer_cards[-1]) + '当前Dealer总和是' + str(sum(dealer_cards)))
            time.sleep(2)
            return dealer_cards#返回最新值
    else:
        return dealer_cards#如果开牌直接比选手的大了,那还加啥牌,直接返回值


def add_card(player_cards, dealer_cards):#玩家选择是否要拍
    player_choice = input('是否要牌?Y/N')#玩家进行输入
    if 'y' in player_choice or 'Y' in player_choice: #如果选择要牌
        player_cards.append(random.choice(cards))#玩家牌池中再生成一张随机手牌
        player_cards = player_if_ace(player_cards)#再次判断是否有A
        return player_cards, dealer_cards, player_choice#返回值
    else:
        dealer_control(dealer_cards,player_cards)#如果玩家不要牌,直接进入庄家操作
        return player_cards, dealer_cards, player_choice#返回值


def blackjack(w, l, t):
    won = w
    lost = l
    tie = t

    player_cards = [random.choice(cards), random.choice(cards)]#玩家的两张手牌随机生成
    player_cards = player_if_ace(player_cards)#判断手牌中是否有A,再进行新的定义

    dealer_cards = [random.choice(cards), random.choice(cards)]#庄家的两张手牌随机生成
    dealer_cards = player_if_ace(dealer_cards)#判断手牌中是否有A,再进行新的定义

    print('******* 游戏开始,你的牌是:' + str(player_cards[0]) + '和'
          + str(player_cards[1]) + ' *******\n' + '总和是'
          + str(sum(player_cards)) + '\n' + 'Dealer的牌有一张是'
          + str(dealer_cards[0]) + '\n')

    player_cards, dealer_cards, player_choice = add_card(player_cards, dealer_cards)
    while player_choice == 'y' or player_choice == 'Y':#当玩家选择要牌时
        if sum(player_cards) > 21:#如果玩家手牌之后超过了21点,直接判输,并且终止游戏
            print('很遗憾,爆牌了,当前总和' + str(sum(player_cards)))
            lost += 1#给玩家判输
            games_played = int(won) + int(lost) + int(tie)
            chance = won / games_played * 100
            time.sleep(2)
            print('一共进行了' + str(games_played) + '局' + '\n' + '赢的概率是' + str(chance) + '%')
            return won, lost, tie#利用返回值跳出此次游戏

        else:#如果玩家手牌没有超过21点,继续询问是否需要加牌
            print('你拿到了一张' + str(player_cards[-1]) + ',当前总和' + str(sum(player_cards)))
            player_cards, dealer_cards, player_choice = add_card(player_cards, dealer_cards)

    time.sleep(2)
    if sum(dealer_cards) > 21:#如果庄家手牌大于21点,玩家赢
        print('Dealer爆牌,恭喜,你赢了')
        won += 1
    else:
        if sum(dealer_cards) > sum(player_cards):#如果庄家比玩家手牌要打,庄赢
            print('对不起,你输了')
            lost += 1
        elif sum(dealer_cards) == sum(player_cards):#点数一样,平局
            print('平局')
            tie += 1
        else:
            print('恭喜,你赢了')#玩家手牌比庄家大,玩家赢
            won += 1
            time.sleep(2)

    games_played = int(won) + int(lost) + int(tie)#用于算一共玩了几局
    chance = won / games_played * 100#用于计算胜率
    print('一共进行了' + str(games_played) + '局' + '\n' + '赢的概率是' + str(chance) + '%')
    return won, lost, tie


w = 0
l = 0
t = 0
while True:
    w, l, t = blackjack(w, l, t)

这个程序当然也有许多的不足,例如:

  1. 没有办法进行加注,真正的扑克游戏中会有筹码的概念。做这款小程序只是为了给自己闲来无事打发一下时间,如果要加入筹码的朋友可以自己修改,不难。
  2. 没有办法像网页游戏那么好看,没有弹窗,没有UI设计,纯粹和电脑在玩。
  3. 写到这我发现,貌似没有加入开局如果某一方有21点直接判赢,不过我想应该也无伤大雅,大家可以自己进行一些调整。

最后,希望看了文章的朋友们喜欢的话可以给我点个赞,谢谢啦!

标签:10,21,玩家,player,BlackJack,cards,100,手牌,dealer
来源: https://blog.csdn.net/m0_56552142/article/details/115432888