Python 实现简单的单机版 21 点游戏
Python 實現簡單的單機版 21 點游戲
- 1. 21 點游戲規則簡介
- 2. 實現代碼
- 3. 運行效果
- 4. 總結
1. 21 點游戲規則簡介
21 點游戲規則:
 點數計算:每張牌都有點數。2 到 10 的牌的點數就是其牌面的數字,J、Q、K的點數是 10.
 A有兩種算法: 1 或者 11, 如果 A 算為 11 時總和大于 21,則 A 算為 1. 例如 (A, 8)是 19 點, (A,7,J)則為 18 點
 爆牌:玩家手中牌的總點數超過 21 點
 停牌:玩家不再要牌, 等待其他玩家操作
 要牌:玩家根據自己手上的點數決定是否要牌, 如果要牌, 則系統再發一張牌給玩家. 如果要牌后總點數超過 21, 則算爆牌,玩家輸掉本輪游戲;若要牌后點數為 21點, 則不能再要。如果要牌后總點數不到 21 點, 則玩家可以繼續 “要牌” “停牌”“
 莊家持牌總點數少于 17,則必須要牌,直到超過 16,如果莊家的總點數等于或多于 17 點,則必須停牌
 如果莊家手中有 A,且 A 作 11 點時大于 16點,作 1 點時小于或等于 16 點, 則由莊家自己選擇是否要牌
 注意:游戲開始后,玩家和莊家各發兩張牌,莊家的第二張牌對外不可見。
2. 實現代碼
基于以上的規則,使用 Python 實現一個簡單的 21 點游戲,該游戲只有玩家和電腦兩個玩家,玩家通過命令行的方式輸入命令,決定是否要牌或停牌,電腦玩家要牌或停牌由程序自動控制。代碼如下:
import random # 導入隨機包# 模擬要牌, 從卡牌列表中隨機選擇一張卡牌 import timedef my_random_choose():card = random.choice(cards) # 從卡牌列表中隨機選取一張牌flag = card[0] # flag 存放卡牌的標記value = card[-1] # value 存放卡牌的字符串類型的值if value == 'A': # 如果卡牌為 Areturn flag, value, 1 # 暫時給它的值賦為 1elif value == '0':return flag, '10', 10 # 卡牌為 10elif value == 'J' or value == 'Q' or value == 'K':return flag, value, 10 # 卡牌為 J, Q, K 的當作 10else:return flag, value, int(value) # 其他卡牌, 按照卡牌上的數字計算即可# 詢問玩家是否繼續要牌, 獲取玩家選擇 def get_Input():Input = input('是否繼續要牌(Y|N):')while Input != 'Y' and Input != 'N': # 強制要求只能輸入 Y 或者 N, 其他輸入一律重新輸入Input = input('是否繼續要牌(Y|N):')return Input# 玩家要牌 def player_hit():# 開始游戲,隨機發給玩家兩張卡牌flag1, value1, num1 = my_random_choose()flag2, value2, num2 = my_random_choose()player_cards = [] # 玩家卡牌列表,存放玩家要的所有牌, 存放的是 flag 和 value# 如果第一張卡牌為 A, 則賦值為 11if num1 == 1:num1 = 11 # 卡牌數值為 11elif num1 != 1 and num2 == 1: # 如果第一張卡牌不為 A, 但是第二張卡牌為 Anum2 = 11 # 卡牌數值為 11player_total = num1 + num2 # 計算當前玩家手中卡牌總點數# 將初始發的兩張卡牌放到玩家卡牌列表中, 存放的是字符串, 所以不參與計算, 只是用于輸出卡牌擁有情況player_cards.append([flag1, value1])player_cards.append([flag2, value2])print('玩家手中的牌是:', [flag1, value1], [flag2, value2])if player_total == 21: # 玩家當前點數為 21 點# 玩家贏了return player_total # 返回玩家點數else: # 玩家當前點數不為 21 點Input = get_Input() # 詢問玩家是否要繼續要牌while Input == 'Y' or Input == 'N':if Input == 'Y': # 玩家繼續要牌flag, value, num = my_random_choose() # 隨機抽一張卡牌給玩家if num == 1 and (player_total + 11 <= 21): # 如果抽到了 A, 將 A 看成 11, 看一下此時手中卡牌總點數是否大于 21num = 11 # 如果不大于 21, 可以將當前 A 賦值為 11player_cards.append([flag, value]) # 將抽到的卡牌放到玩家卡牌列表中print('玩家手中的牌是:', player_cards) # 輸出當前擁有的卡牌player_total += num # 計算玩家當前擁有的卡牌的總點數if player_total > 21: # 如果玩家當前擁有的卡牌總點數大于 21return player_total # 玩家爆牌, 返回 玩家卡牌總點數, 結束函數執行elif Input == 'N': # 玩家不要牌return player_total # 返回玩家當前卡牌總點數, 結束函數執行, 讓莊家要牌Input = get_Input() # 玩家之前要了牌, 但是牌的總點數小于 21, 詢問玩家是否繼續要牌# 莊家要牌 def dealer_hit(num1, dealer_cards):DEALER_MIN_SCORE = 17 # 莊家手中的牌的總點數的最小值為 17, 如果小于 17, 莊家必須要牌flag2, value2, num2 = my_random_choose() # 為莊家隨機選擇一張卡牌if num1 != 11 and num2 == 1: # 莊家的第一張牌不是 A, 但是第二張卡牌是 Anum2 = 11 # 給第二張卡牌賦值為 11dealer_cards.append([flag2, value2]) # 將莊家的第二張卡牌放到莊家卡牌列表中, 用于之后輸出擁有卡牌情況dealer_total = num1 + num2# 當莊家手中牌的總點數小于 17, 必須要牌,while dealer_total < DEALER_MIN_SCORE:flag, value, num = my_random_choose()if num == 1 and (dealer_total + 11 <= 21):num = 11dealer_cards.append([flag, value])print('莊家得到一張牌, 莊家手中的牌是: ', dealer_cards)dealer_total += num# 莊家手中的牌的總點數大于等于17, 必須停牌, 即返回總點數return dealer_total# 決定贏家 def vs(player_total, dealer_total):if player_total > 21: # 如果玩家爆牌# 玩家輸print('莊家點數為 ', dealer_total, ', 玩家點數為 ', player_total, ', 莊家贏了!')return 1, 0 # 分別返回莊家和玩家的比分else:if dealer_total > 21: # 莊家爆牌print(' 莊家點數為 ', dealer_total, ', 玩家點數為 ', player_total, ', 玩家贏了!')return 0, 1else:if player_total == dealer_total: # 平局print(' 莊家點數為 ', dealer_total, ', 玩家點數為 ', player_total, ', 平局!')return 1, 1elif player_total > dealer_total: # 都沒有爆牌,但是玩家的卡牌總點數大于莊家卡牌總點數# 玩家贏print(' 莊家點數為 ', dealer_total, ', 玩家點數為 ', player_total, ', 玩家贏了!')return 0, 1else:# 莊家贏print(' 莊家點數為 ', dealer_total, ', 玩家點數為 ', player_total, ', 莊家贏了!')return 1, 0def start_21_game():player_score = 0 # 玩家得分dealer_score = 0 # 莊家得分Input = 'Y'round_count = 0 # 比賽的輪數while Input == 'Y':round_count += 1print(f'第{round_count}輪比賽開始:')flag1, value1, num1 = my_random_choose() # 從卡牌列表中隨機選擇一個卡牌if num1 == 1: # 卡牌為 Anum1 = 11 # 因為只有一個卡牌,所以不會爆牌,賦值為 11dealer_cards = [] # 莊家擁有的卡牌列表dealer_cards.append([flag1, value1]) # 將抽到的卡牌放到莊家卡牌列表中print('莊家手中的牌是: ', [flag1, value1], '?')player_total = player_hit() # 調用玩家要牌函數, 返回值是玩家此時的卡牌總點數dealer_total = dealer_hit(num1, dealer_cards) # 調用莊家要牌函數, 返回值是莊家此時的卡牌總點數dealer_point, player_point = vs(player_total, dealer_total) # 根據玩家和莊家的卡牌總點數判斷贏家是誰, 返回值分別是莊家和贏家當局的比分print('------------------------------')player_score += player_point # 將玩家當局的得分加到玩家總得分上dealer_score += dealer_point # 將莊家當局的得分加到莊家總得分上Input = input('是否進行下一局 [Y|N]:')while Input != 'Y' and Input != 'N':print('請輸入 Y or N.', end='')Input = input('請重新輸入 [Y|N]:')return player_score, dealer_scoreif __name__ == '__main__':# 定義一個存放卡牌的列表cards = ['?A', '?2', '?3', '?4', '?5', '?6', '?7', '?8', '?9', '?10', '?J', '?Q', '?K','?A', '?2', '?3', '?4', '?5', '?6', '?7', '?8', '?9', '?10', '?J', '?Q', '?K','?A', '?2', '?3', '?4', '?5', '?6', '?7', '?8', '?9', '?10', '?J', '?Q', '?K']# play_score 記錄玩家的得分, dealer_score 記錄莊家的得分player_score, dealer_score = start_21_game()print(f'玩家, 莊家總比分為:{player_score}:{dealer_score}')if player_score > dealer_score:print('玩家勝出')elif player_score < dealer_score:print('莊家勝出')else:print('平局')print('游戲結束')print('10秒后自動關閉窗口')time.sleep(10)3. 運行效果
上面的代碼可以直接運行,為了更加直觀地展示運行效果。我將使用 pyinstaller 將文件打包成可執行文件,然后在命令行窗口進行展示。在 Pycharm 集成開發工具的終端 terminal 輸入 pyinstaller 打包的命令, 命令如下:
pyinstaller -F 21點游戲.py如果未安裝 pyinstaller, 則使用如下 pip 命令進行安裝:
pip install pyinstaller -i https://mirrors.aliyun.com/pypi/simple打包完成之后,運行生成的可執行文件,運行效果截圖如下所示:
 
4. 總結
以上就是使用 Python 實現簡單的單機版 21 點游戲,上述代碼編寫并沒有體現使用面向對象的編程思想,大家可以在此基礎上,用對象進行封裝,從而對代碼有更深的體會!
 如果覺得有用的話,記得點贊、收藏加關注哦!
總結
以上是生活随笔為你收集整理的Python 实现简单的单机版 21 点游戏的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 关于江苏省地图的着色问题(课程设计)
- 下一篇: suggest 是搜索引擎一个方便的功能
