利用Python編寫簡易版德州撲克小游戲
德州撲克簡要介紹
什么是德州撲克
德州撲克不知道大家是否玩過,它是起源于美國的得克薩斯州的一種博弈類卡牌游戲,英文名叫做Texas Hold’em Poker。玩法上又分為常規(guī)桌(Cash, 現(xiàn)金局),單桌賽(SNG)和多桌錦標(biāo)賽(MTT)。雖然撲克種類繁多,但基本的撲克規(guī)則通常保持一致。它是一種考驗心態(tài)與謀略的游戲。
游戲規(guī)則簡要介紹
一、使用道具
一副標(biāo)準(zhǔn)撲克牌去掉大小王后的52張牌進行游戲。
二、游戲人數(shù)
一般2-10個玩家,個別情況有12個玩家的。
三、游戲目的
贏取其他玩家籌碼
四、下注宗旨
玩家之間同時繼續(xù)看牌或比牌需要下同樣注額籌碼,籌碼不足的玩家all-in全下后可以看到底并參與比牌。
五、發(fā)牌下注
發(fā)牌一般分為5個步驟,分別為,
Perflop——先下大小盲注,然后給每個玩家發(fā)2張底牌,大盲注后面第一個玩家選擇跟注、加注或者蓋牌放棄,按照順時針方向,其他玩家依次表態(tài),大盲注玩家最后表態(tài),如果玩家有加注情況,前面已經(jīng)跟注的玩家需要再次表態(tài)甚至多次表態(tài)。
Flop——同時發(fā)三張公牌,由小盲注開始(如果小盲注已蓋牌,由后面最近的玩家開始,以此類推),按照順時針方向依次表態(tài),玩家可以選擇下注、加注、或者蓋牌放棄。
Turn——發(fā)第4張牌,由小盲注開始,按照順時針方向依次表態(tài)。
River——發(fā)第五張牌,由小盲注開始,按照順時針方向依次表態(tài),玩家可以選擇下注、加注、或者蓋牌放棄。
比牌——經(jīng)過前面4輪發(fā)牌和下注,剩余的玩家開始亮牌比大小,成牌最大的玩家贏取池底。
六、比牌方法
用自己的2張底牌和5張公共牌結(jié)合在一起,選出5張牌,不論手中的牌使用幾張(甚至可以不用手中的底牌),湊成最大的成牌,跟其他玩家比大小。
比牌先比牌型,大的牌型大于小的牌型,牌型一般分為10種,從大到小為:

德州撲克游戲的python實現(xiàn)過程
游戲初始化
#調(diào)用random庫中的sample函數(shù),用于從卡牌堆中隨機抽取卡牌 from random import sample #利用列表存儲卡牌的花色與數(shù)字 color = ['黑桃','紅桃','梅花','方塊'] number = ['2','3','4','5','6','7','8','9','10','J','Q','K','A']
導(dǎo)入random庫中的sample函數(shù),后續(xù)用于從卡牌堆中隨機抽取卡牌。同時利用列表分別將卡牌的顏色與數(shù)字存儲在color與number中。
#PokerGenerator函數(shù)用于生成一組卡牌
def PokerGenerator():
#將卡牌存儲于列表中
Poker = []
# 用字典表示卡牌,在Poker列表中添加52張空白的卡牌
for i in range(0,52):
t = {'數(shù)字':0,'花色':''}
Poker.append(t)
#對每張卡牌進行賦值,每種花色各有13種花色,共四種花色,52張卡牌。
for i in range(0,52):
Poker[i].update({'數(shù)字':number[i%13],'花色':color[i//13]})
#將存儲有52張卡牌的列表Poker返回
return Poker
函數(shù)PokerGenerator用于生成一副新的撲克牌,德州撲克所采用的撲克牌標(biāo)準(zhǔn)牌組,包含四種花色(‘黑桃’,‘紅桃’,‘梅花’,‘方塊’),每種花色有’2’到’A’等13張卡牌,共52張撲克,不包含大小王。
#根據(jù)玩家人數(shù)分發(fā)卡牌
def Pokerinitial(playersum):
Playerpoker = []
Poker = PokerGenerator()#初始化一副新的卡牌
num = 52
for i in range(0,playersum):
Pripoker = sample(Poker,2)#從卡牌中隨機抽取兩張卡牌作為一名玩家的手牌
Playerpoker.append(Pripoker)#所抽取的卡牌以元組形式假加入Playerpoker列表中,以Playerpoker的下標(biāo)序號代表玩家的序號
#將每位玩家所抽取的卡牌從卡牌堆中刪除,即實現(xiàn)不放回抽樣
for n in [0,1]:
for m in range(0,num):
if Poker[m] == Pripoker[n]:
del Poker[m]
num -=1
break
Publicpoker = sample(Poker,3)#從牌堆中再抽取三張牌作為公共牌
#將所抽取的公共牌從牌堆中刪除
for n in [0,1,2]:
for m in range(0,num):
if Poker[m] == Publicpoker[n]:
del Poker[m]
num -=1
break
#將每位玩家的手牌與公共牌輸出顯示
for i in range(0,playersum):
print("玩家 %d"%(i+1)+":牌1:"+str(Playerpoker[i][0])+" 牌2:"+str(Playerpoker[i][1]))
print("")
print("")
print("")
print("公共牌: "+str(Publicpoker)+" ")
return [Playerpoker,Poker,Publicpoker]#將玩家手牌,剩余的牌堆,公共牌組返回
給每位玩家分發(fā)兩張手牌,分發(fā)游戲開始時的三張公共牌,并將每位玩家的手牌情況與公共情況輸出顯示,利用字典表示撲克牌。
評選贏家
實現(xiàn)德州撲克最關(guān)鍵的一步便是計算出那位玩家的手牌最大,確定最終的贏家,若最終贏家有多位則平分獎池。我用0到8等9個數(shù)字分別代表高牌到同花順等四個等級,我不專門為皇家同花順列一個等級,若場上同時出現(xiàn)兩個同花順,則根據(jù)同花順中最大的卡牌數(shù)字來確定贏家,接下來開始介紹判斷各種手牌類別的方法。
#判斷玩家的牌與公共牌是否構(gòu)成順子 def judgestraight(finalpoker): ? ? result = [0, 0]#用于儲存結(jié)果,result[0]中儲存此位玩家最好的五張牌的類別,從高牌到皇家同花順編號為0到9。result[1]儲存當(dāng)前開組中數(shù)字最大的牌 ? ? pokernum = []#存儲卡牌的數(shù)字 ? ? for i in range(0, len(finalpoker)): ? ? ? ? pokernum.append(number.index(finalpoker[i]['數(shù)字'])) ? ? pokernum.sort()#將卡牌號碼從小到大進行排序 ? ? #判斷玩家卡牌與公共卡牌的組合是否能構(gòu)成順子 ? ? maxp = minp = 0 ? ? for i in range(1, len(finalpoker)): ? ? ? ? if (pokernum[i - 1] + 1) == pokernum[i]: ? ? ? ? ? ? maxp = i ? ? ? ? else: ? ? ? ? ? ? minp = i ? ? ? ? if (maxp - minp) == 4: ? ? ? ? ? ? result[0] = 4 ? ? ? ? ? ? result[1] = max(pokernum[minp:maxp + 1]) ? ? return result
judgestraight函數(shù)用于判斷玩家手牌與五張公共牌是否能構(gòu)成順子,需要輸入?yún)?shù)finalpoker。finalpoker應(yīng)接受一個列表對象,其內(nèi)應(yīng)包含玩家手牌與最終的公共牌,總計7張牌。而后判斷其中是否有順子,并將判斷結(jié)果返回。結(jié)果中包含了兩個信息:result[0]若為4則表明其內(nèi)包含有順子,為0則不包含。若包含順子result[1]中會存儲順子中最大的卡牌數(shù)字。
#判斷卡組中是否存在同花
def judgeflush(finalpoker):
result = [0, 0]
pokernum = []
flush = []#用于存儲相同花色的卡牌
while len(finalpoker) >= 5:
#抽出卡組中同花色的卡牌
flush.append(finalpoker[0])
for i in range(1, len(finalpoker)):
if finalpoker[i]['花色'] == finalpoker[0]['花色']:
flush.append(finalpoker[i])
#若同花色卡牌不少于五張,那么卡組存在同花
if len(flush) >= 5:
result[0] = 5
for ele in flush:
pokernum.append(number.index(ele['數(shù)字']))
result[1] = max(pokernum)
for ele in flush:
finalpoker.remove(ele)
flush.clear()
return result
judgeflush函數(shù)用于判斷玩家的手牌中是否包含有同花,并將結(jié)果返回。同上,judgestraight函數(shù)所返回的結(jié)果包含兩個信息,玩家的手牌與公共拍的組合中是否包含有同花,若有同花則同時將同花中的最大數(shù)字返回。
#判斷卡組中是否存在四條、三條、兩對或一對
def judgesame(finalpoker):
result = [0, 0]
four = -1 #記錄卡組中是否存在四條
three = -1 #記錄卡組中是否存在三條
two = [-1, -1] #記錄卡組中是否存在兩對與一對
count = 1
pokernum = []
bottom = 0
#將卡組的所有卡牌號存儲進pokernum中,并進行排序
for i in range(0, len(finalpoker)):
pokernum.append(number.index(finalpoker[i]['數(shù)字']))
pokernum.sort()
#判斷卡組中是否存在四條、三條、兩對或一對等,并將所對應(yīng)最大的卡牌數(shù)字進行存儲
for i in range(1, len(finalpoker)):
if pokernum[i] == pokernum[bottom]:
count += 1
else:
if count == 2:
if pokernum[bottom] > min(two):
numid = two.index(min(two))
two[numid] = pokernum[bottom]
if count == 3:
if pokernum[bottom] > three:
three = pokernum[bottom]
if count == 4:
four = pokernum[bottom]
bottom = i
count = 1
#判斷卡組中所存在的最大的組合牌類型
if four >= 0:
result[0] = 7
result[1] = four
elif three >= 0 and max(two) >= 0:
result[0] = 6
t = three * 10 + max(two)
result[1] = t
elif three >= 0:
result[0] = 3
result[1] = three
elif min(two) >= 0:
result[0] = 2
result[1] = max(two)
elif max(two) >= 0:
result[0] = 1
result[1] = max(two)
return result
這個函數(shù)相較于上面兩個函數(shù)相對長很多,因為它一個函數(shù)實現(xiàn)了三個功能,判斷玩家手牌與公共牌的組合中是否含有一對、兩對、三條或四條。與上述函數(shù)功能相似,judgesame會判斷所接受卡組中是否含有上述四種情況,若有則將等級最高的情況返回,同時將該情況中所含最大的卡牌數(shù)字返回。
#計算出玩家所持卡組中最大的組合牌類型
def computeresult(Playerpoker, Publicpoker):
finalresult = [0, 0]
finalpoker = []
finalpoker = Playerpoker + Publicpoker
a = finalpoker.copy()
b = finalpoker.copy()
c = finalpoker.copy()
#分別存儲同花、順子、四條、三條(即數(shù)字相同的個數(shù)與情況)等的判斷結(jié)果
result_1 = judgeflush(a)
result_2 = judgestraight(b)
result_3 = judgesame(c)
#判斷是否是同花順
if result_1[0] != 0 and result_2[0] != 0:
finalresult[0] = 8
finalresult[1] = result_2[1]
#若不是同花順,則判斷玩家手牌與公共牌所在組成的最大卡組種類
else:
t_0 = result_1[0]
t_1 = result_1[1]
if result_2[0] > t_0:
t_0 = result_2[0]
t_1 = result_2[1]
if result_3[0] > t_0:
t_0 = result_3[0]
t_1 = result_3[1]
#確定最終結(jié)果,即玩家所擁有的最大卡牌種類
finalresult[0] = t_0
finalresult[1] = t_1
return finalresult
我最終利用computeresult函數(shù)計算出每位玩家最終所擁有的最高等級卡組。在此函數(shù)中我分別調(diào)用了以上三個函數(shù),通過比較得出玩家所擁有的最高等級卡組,并將結(jié)果返回。
游戲主題函數(shù)
我們編寫的函數(shù)已能夠?qū)崿F(xiàn)游戲初始化與游戲結(jié)果的計算,接下來我們便利用以上函數(shù)編寫德州撲克游戲的真正的主體。
#游戲函數(shù)主體
def gamestart(playersum):
finalresult = []#用于存儲每個玩家的最大手牌
[playerpoker,Poker,Publicpoker] = Pokerinitial(playersum)#根據(jù)玩家數(shù)初始化一副卡牌,并給每位玩家分發(fā)兩張手牌,并分發(fā)初始的三張公共牌
playerlist = list(range(1,playersum+1))#記錄每輪回合過后還剩下的玩家
playerlist_t = []
Playerpoker = []
while len(Publicpoker) < 5 and len(playerlist) > 1:#當(dāng)公共牌數(shù)為5或僅剩一個玩家時,游戲結(jié)束進行結(jié)算
tag = 0 #標(biāo)識符,標(biāo)注所輸入的繼續(xù)游戲的玩家是否有誤,若有誤則重新輸入
playerkeep = input("請輸入繼續(xù)游戲的玩家:")
playerlist_t = eval(playerkeep)
if isinstance(playerlist_t,int):
if playerlist_t in playerlist:
winplayer = playerlist_t
print("game over. The winner is "+str(winplayer))#若選擇繼續(xù)游戲的玩家僅有一人,則游戲結(jié)束進行結(jié)算
return
playerlist.clear()
else:
print("輸入有誤,請重新輸入")#若輸入玩家在本回合中不存在則報錯并重新輸入
elif isinstance(playerlist_t, tuple):
playerlist_t = list(playerlist_t)
for i in playerlist_t:
if i not in playerlist:
tag = 1
if tag == 1:
print("輸入有誤,請重新輸入")#若輸入的玩家中有玩家在本回合中不存在則報錯并重新輸入
else:
playerlist = playerlist_t
pokerkeep = sample(Poker,1)#從剩余卡牌中再抽取一張作為公共牌
Publicpoker += pokerkeep
pokerkeep = pokerkeep[0]
print("公共牌: "+str(Publicpoker)+" ")#將本回合的公共牌進行顯示
for n in range(0,len(Poker)):#將所抽取的公共牌從剩余卡牌中刪除
if Poker[n] == pokerkeep:
del Poker[n]
break
for i in playerlist:
Playerpoker.append(playerpoker[i-1])
for ppoker in Playerpoker:
finalresult.append(computeresult(ppoker, Publicpoker))#將每位玩家的手牌與公共牌代入計算最終結(jié)果
finalscore = []
finalscore_t = []
finalplayer = []
winner = []
for t in range(0, len(finalresult)):
finalscore.append(finalresult[t][0])
maxscore = max(finalscore)#判斷此時所有玩家中最大的組合牌類型
#若有多位玩家同時擁有最大類型的組合牌,則對他們最大的牌數(shù)字進行比較
for t in range(0, len(finalresult)):
if finalscore[t] == maxscore:
finalplayer.append(t)
for t in finalplayer:
finalscore_t.append(finalresult[t][1])
maxscore_t = max(finalscore_t)
for t in finalplayer:
if finalresult[t][1] == maxscore_t:
winner.append(playerlist[t])
##輸出最終玩家
print("game over.The winner is:")
for t in winner:
print("玩家:"+str(t))
return
gamestart函數(shù)唯一需要輸出的參數(shù)便是玩家的人數(shù)。在游戲的開始,我們利用Pokerinitial函數(shù)獲得一副新卡牌,為每位玩家分發(fā)兩張手牌,并分發(fā)三張初始公共牌。當(dāng)玩家人數(shù)在游戲中途僅剩1時,我們認為游戲已結(jié)束,并顯示最終贏家。若游戲正常進行到最后(有兩位及以上玩家堅持到最后回合),則對每位玩家所擁有的最高等級卡牌組合進行計算與比較,得出最終贏家。若中途輸入繼續(xù)游戲的玩家并不在當(dāng)前玩家隊伍中時,系統(tǒng)會報錯并提示重新輸入。好了,話不多說,接下來我們便開始體驗游戲吧!
游戲體驗與展示
from Texas_Hold_em_Poker import gamestart
我們首先導(dǎo)入我們所寫的德州撲克游戲模塊,并且僅需其中的gamstart函數(shù)。
n = input('請輸入要進行的游戲的玩家人數(shù):')
gamestart(int(n))
接著我們便通過編寫input函數(shù)從控制臺獲取進行游戲的玩家人數(shù)。

我們將參與游戲的玩家人數(shù)定為5


接著屏幕上便出現(xiàn)了每個玩家的手牌與公共牌。

接著我們輸入繼續(xù)游戲的玩家

接著出現(xiàn)了下一回合的公共牌,我們接著讓1,2,3號玩家繼續(xù)游戲

可以看到出現(xiàn)了最后回合的公共牌,并計算出了最終贏家。此時我們嘗試輸入上一回合并未繼續(xù)參與游戲的玩家號,看看會出現(xiàn)什么。


我們?nèi)匀粚⒂螒蛲婕胰藬?shù)定為5,并仍在第一回合讓1,2,3號玩家繼續(xù)游戲

但我們在下一回合輸入已經(jīng)退出游戲的玩家4號與5號

可以看到系統(tǒng)報錯,并提示重新輸入,此時我們只需要輸入正確的玩家號碼便可以得到正確的結(jié)果。
模塊不足與后續(xù)改進
在游戲展示中我們可以看到玩家的手牌是公開的,而在實際中的德州撲克中,每位玩家的手牌都是完全保密的,這顯然不符合實際要求。但由于此代碼僅能在控制臺中輸出顯示,所以也沒有很好的辦法對每位玩家的手牌進行保密,若接下來能實現(xiàn)可視化便可通過設(shè)置密鑰的方式分別輸出每位玩家的手牌,實現(xiàn)很好的保密作用,或者在此基礎(chǔ)上將它發(fā)展成一個最終的小游戲也是能實現(xiàn)保密性的。
除此以外在德州撲克中需要有不停的加注與跟注,這也可以寫成一個函數(shù),這個等過段時間我稍微空了點可以補上去哈哈哈,有想法的朋友也可以自己來寫著試試。
到此這篇關(guān)于利用Python編寫簡易版德州撲克小游戲的文章就介紹到這了,更多相關(guān)Python德州撲克內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
selenium切換標(biāo)簽頁解決get超時問題的完整代碼
這篇文章主要給大家介紹了關(guān)于selenium切換標(biāo)簽頁解決get超時問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Python實現(xiàn)獲取sonarqube數(shù)據(jù)
sonarqube是一款代碼分析的工具,可以對通過soanrScanner掃描后的數(shù)據(jù)傳遞給sonarqube進行分析,本文為大家整理了Python獲取sonarqube數(shù)據(jù)的方法,需要的可以參考下2023-05-05
python通過shutil實現(xiàn)快速文件復(fù)制的方法
這篇文章主要介紹了python通過shutil實現(xiàn)快速文件復(fù)制的方法,涉及Python中shutil模塊的使用技巧,需要的朋友可以參考下2015-03-03
Python集成學(xué)習(xí)之Blending算法詳解
集成學(xué)習(xí)(又稱模型融合)就是結(jié)合若干個體分類器(基學(xué)習(xí)器)進行綜合預(yù)測,各個個體學(xué)習(xí)器通常是弱學(xué)習(xí)器.集成學(xué)習(xí)相較于個體學(xué)習(xí)在預(yù)測準(zhǔn)確率以及穩(wěn)定性上都有很大的提高.文中有非常詳細的代碼示例哦,需要的朋友可以參考下2021-05-05
Python OpenCV之圖片縮放的實現(xiàn)(cv2.resize)
這篇文章主要介紹了Python OpenCV之圖片縮放的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06

