21点(BlackJack)扑克游戏,挑战用100行代码实现
作者:互联网
21点(BlackJack)扑克游戏,挑战用100行代码实现
本人平时喜欢与朋友们玩玩21点与德州扑克,特别是看了《决胜21点》后,很想自己写一款简单的21点游戏。趁着清明节小长假闲来无事在家中试着实现了一下。感兴趣的朋友可以和我一起练习!
首先我做的,就是把实现的路径规划下来,以下就是我的大致思路:
- 将游戏规则写下来
- 将规则编程化
一. 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一直要牌
二. 将规则编程化
- 首先我们看第一个规则,“四种花色,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
]
- “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,则保持现状
- “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')
- “选手选择是否要牌,如果要,系统发一张牌,直到爆掉之前,选手可以一直要牌”。在这我们为选手要牌单独写一个逻辑。
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#如果开牌直接比选手的大了,那还加啥牌,直接返回值
- 上边是玩家需要加牌的状况,如果不要加牌,则直接开牌对比。这边的代码与上面的相似。之后我们写一个,进行最终判断的代码:
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#返回值
到这边,我们的程序基本框架已经出来了,之后就是将程序细化,并且完成。
以下是全部的代码:
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)
这个程序当然也有许多的不足,例如:
- 没有办法进行加注,真正的扑克游戏中会有筹码的概念。做这款小程序只是为了给自己闲来无事打发一下时间,如果要加入筹码的朋友可以自己修改,不难。
- 没有办法像网页游戏那么好看,没有弹窗,没有UI设计,纯粹和电脑在玩。
- 写到这我发现,貌似没有加入开局如果某一方有21点直接判赢,不过我想应该也无伤大雅,大家可以自己进行一些调整。
最后,希望看了文章的朋友们喜欢的话可以给我点个赞,谢谢啦!
标签:10,21,玩家,player,BlackJack,cards,100,手牌,dealer 来源: https://blog.csdn.net/m0_56552142/article/details/115432888