游戲規則
該游戲的規則與實際的玩法應該有點差異,因為我沒有去細查21點的確切玩法,只是根據印象中進行了一系列的定義,具體如下:
1.玩家為人類玩家與電腦玩家,共2個玩家。電腦為庄家。
2.先給人類玩家與電腦玩家分別發兩張牌作為底牌。
3.判斷雙方底牌是否為blackjack,如果一方為blackjack則直接判勝利,並在總分中記上一分。如果雙方均為blackjack,則判雙方平局,均不得分
4.如果沒有出現blackjack的情況,人類玩家根據牌面決定是否要牌,若要牌則得到牌堆的一張牌,並再次判斷。如果人類牌面的點數超過21點,則直接判負。
5.如果人類玩家停止要牌,且未因為超過21點而判負,則電腦要牌(電腦的要牌基於一個算法,后期如果更新,這個算法要基於對勝率的估算),電腦停止要牌后,判斷與人類的輸贏情況。贏者加一分。
6.人類玩家決定是否繼續下一輪,如果繼續,則從剩余牌堆中繼續發牌開始上述過程。如果不繼續,則計算總分,判斷誰勝出。
7.如果牌堆的牌已經不夠玩一輪的話,自動判斷游戲結束。人類可以選擇是否重新再玩。
程序功能
要實現上面游戲的規則,程序的功能進行划分如下,不同的功能用不同的函數來實現,以達到代碼的復用。
1.牌堆:在發牌的過程中,牌堆中會去除已經發出的牌
2.發牌:要牌的時候,需要從牌堆隨機抽取一張牌
3.計分:能對手中的牌的分數進行計算,其中需要考慮靠A的特殊性
4.勝負判斷:當結束要牌的時候,能通過分數判斷勝負
5.要牌與否:一個讓你判斷是否繼續要牌的功能
6.游戲結束判斷:讓你決定是否提前結束游戲,如果不提前結束,則在牌堆中牌的數量比較少的時候,自動結束游戲
7.一局游戲的過程

//角色類 class Role: def __init__(self): """初始化方法""" # 定義列表,用來保存當前角色手中的牌,初始牌為空,保存的類型為Card對象 self.cards = [] # 向控制台打印手中所有的牌 def show_card(self, style=0, show=True): lastpos = len(self.cards) - 1 if style == 1: msg = '你擁有的牌:' else: msg = '庄家的牌:' cardSow = '' for i, card in enumerate(self.cards): if show: if i < lastpos: cardSow = cardSow + (card.card_tpye + card.card_text) + ',' else: cardSow = cardSow + (card.card_tpye + card.card_text) else: if i < lastpos: cardSow = cardSow + (card.card_tpye + card.card_text) + ',' else: cardSow = cardSow + ' ?\n' print(msg + cardSow, sep='', end='') # 打印當前角色手中所有牌之后,在進行換行。 print() def get_value(self): """獲取當前角色牌的點數(分為最小值和最大值) """ Score = 0 Have_Ace = False for card in self.cards: Score += card.card_value for i in self.cards: if i.card_text == 'A': Have_Ace = True break else: continue if Have_Ace: if Score + 10 <= 21: Score = Score + 10 return Score def clear_card(self): # 清空牌,重新開始 self.cards = []

//牌類 class Card: def __init__(self, card_tpye, card_text, card_value): """初始化方法 Parameters --------- card_type:str 牌的類型:(紅桃,黑桃,梅花,方片) card_text:str 牌面顯示的文本(A,K,Q,J) card_value:int 牌面的真實值(例如A為1點或11點,K為10點) """ self.card_tpye = card_tpye self.card_text = card_text self.card_value = card_value

//牌管理類 class CardManager: """管理一整副撲克牌,並且能夠進行發牌""" def __init__(self): """初始化方法""" # 用來保存一整副52張撲克牌 self.cards = [] # 定義所有牌的花色類型 all_card_type = "♥♠♣♦" all_card_text = ["A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3", "2"] all_card_value = [11, 10, 10, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2] # 對牌面類型、牌面值、牌面文本嵌套循環 for card_type in all_card_type: for index, card_text in enumerate(all_card_text): card = Card(card_type, card_text, all_card_value[index]) self.cards.append(card) # 洗牌 random.shuffle(self.cards) def getCard(self): return self.cards # 發牌 def send_card(self, role, num=1): """給電腦或玩家發牌, Parameters ------ role:Role 電腦或玩家 num:int 發牌的數量,默認1張 """ for i in range(num): card = self.cards.pop() role.cards.append(card)

//游戲管理類 class GameManager: def __init__(self): # 創建撲克牌管理器類 self.cards = CardManager() # 創建玩家角色 self.player = Role() # 創建電腦角色 self.computer = Role() self.total_score = np.array([0, 0]) # 總分的計分器 def start_game(self): Round = 1 while len(self.cards.getCard()) > 10: self.player.clear_card() self.computer.clear_card() input('開始, good luck...<<Enter>>\n') print(f'第 {Round} 輪:') print('.' * 60) score = self.one_round() self.total_score += score print(f'總分數:{self.total_score[0]}:{self.total_score[1]}') Round += 1 self.continue_or_quit() def judgement(self, your_score, pc_score): # 結束要牌的時候,計算雙方的點數,判斷輸贏 if your_score > 21 and pc_score > 21: print(f'平局,分數: {your_score}:{pc_score}') return np.array([0, 0]) elif your_score > 21 and pc_score <= 21: print(f'你輸了,分數: {your_score}:{pc_score}') return np.array([0, 1]) elif your_score <= 21 and pc_score > 21: print(f'你贏了,分數: {your_score}:{pc_score}') return np.array([1, 0]) elif your_score <= 21 and pc_score <= 21: if your_score < pc_score: print(f'你輸了,分數: {your_score}:{pc_score}') return np.array([0, 1]) elif your_score > pc_score: print(f'你贏了,分數: {your_score}:{pc_score}') return np.array([1, 0]) else: print(f'平局,分數: {your_score}:{pc_score}') return np.array([0, 0]) def one_round(self): # 一個回合的游戲 self.cards.send_card(self.player, 2) self.cards.send_card(self.computer, 2) self.player.show_card(1) self.computer.show_card(0, False) score = np.array([self.player.get_value(), self.computer.get_value()]) if score[0] == 21 or score[1] == 21: print('BlackJack 21點直接獲勝') return self.judgement(score[0], score[1]) else: while score[0] <= 21: Get_New_Poker = self.hit_or_stand() # 要了一張牌 if Get_New_Poker: self.player.show_card(1) self.computer.show_card(0, False) score[0] = self.player.get_value() if score[0] > 21: print('你超過21點') self.computer.show_card(0) print() return self.judgement(score[0], score[1]) else: continue elif not Get_New_Poker: # npc點數比玩家低,則要牌 while score[1] < score[0]: self.cards.send_card(self.computer) score[1] = self.computer.get_value() self.player.show_card(1) self.computer.show_card(0) print() return self.judgement(score[0], score[1]) else: continue def hit_or_stand(self): # 玩家需要判斷是否繼續叫牌 AskPoker = input('是否叫牌? 【Y/N】>>:') if AskPoker.upper() == 'Y': print() self.cards.send_card(self.player) return True elif AskPoker.upper() == 'N': print('你沒加牌.') print() return False else: print('輸入錯誤 Y/y or N/n!>>') return self.hit_or_stand() def continue_or_quit(self): # 在每一輪結束后,判斷是否繼續下一輪的游戲。當牌堆里面牌的數目不足的時候,自動停止游戲 NextRound = input('是否繼續? 【Y/N】>>') if NextRound.upper() == 'Y': if len(self.cards.getCard()) < 10: print('牌不夠了') input('Game Over') exit(1) else: return True elif NextRound.upper() == 'N': input('Game Over') exit(1) else: print('輸入有誤') self.continue_or_quit()

//完整代碼 import random import numpy as np from sys import exit class Role: def __init__(self): """初始化方法""" # 定義列表,用來保存當前角色手中的牌,初始牌為空,保存的類型為Card對象 self.cards = [] # 向控制台打印手中所有的牌 def show_card(self, style=0, show=True): lastpos = len(self.cards) - 1 if style == 1: msg = '你擁有的牌:' else: msg = '庄家的牌:' cardSow = '' for i, card in enumerate(self.cards): if show: if i < lastpos: cardSow = cardSow + (card.card_tpye + card.card_text) + ',' else: cardSow = cardSow + (card.card_tpye + card.card_text) else: if i < lastpos: cardSow = cardSow + (card.card_tpye + card.card_text) + ',' else: cardSow = cardSow + ' ?\n' print(msg + cardSow, sep='', end='') # 打印當前角色手中所有牌之后,在進行換行。 print() def get_value(self): """獲取當前角色牌的點數(分為最小值和最大值) """ Score = 0 Have_Ace = False for card in self.cards: Score += card.card_value for i in self.cards: if i.card_text == 'A': Have_Ace = True break else: continue if Have_Ace: if Score + 10 <= 21: Score = Score + 10 return Score def clear_card(self): # 清空牌,重新開始 self.cards = [] class Card: def __init__(self, card_tpye, card_text, card_value): """初始化方法 Parameters --------- card_type:str 牌的類型:(紅桃,黑桃,梅花,方片) card_text:str 牌面顯示的文本(A,K,Q,J) card_value:int 牌面的真實值(例如A為1點或11點,K為10點) """ self.card_tpye = card_tpye self.card_text = card_text self.card_value = card_value class CardManager: """管理一整副撲克牌,並且能夠進行發牌""" def __init__(self): """初始化方法""" # 用來保存一整副52張撲克牌 self.cards = [] # 定義所有牌的花色類型 all_card_type = "♥♠♣♦" all_card_text = ["A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3", "2"] all_card_value = [11, 10, 10, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2] # 對牌面類型、牌面值、牌面文本嵌套循環 for card_type in all_card_type: for index, card_text in enumerate(all_card_text): card = Card(card_type, card_text, all_card_value[index]) self.cards.append(card) # 洗牌 random.shuffle(self.cards) def getCard(self): return self.cards # 發牌 def send_card(self, role, num=1): """給電腦或玩家發牌, Parameters ------ role:Role 電腦或玩家 num:int 發牌的數量,默認1張 """ for i in range(num): card = self.cards.pop() role.cards.append(card) """ 游戲管理類,檢測用戶輸入,分數判斷等 """ class GameManager: def __init__(self): # 創建撲克牌管理器類 self.cards = CardManager() # 創建玩家角色 self.player = Role() # 創建電腦角色 self.computer = Role() self.total_score = np.array([0, 0]) # 總分的計分器 def start_game(self): Round = 1 while len(self.cards.getCard()) > 10: self.player.clear_card() self.computer.clear_card() input('開始, good luck...<<Enter>>\n') print(f'第 {Round} 輪:') print('.' * 60) score = self.one_round() self.total_score += score print(f'總分數:{self.total_score[0]}:{self.total_score[1]}') Round += 1 self.continue_or_quit() def judgement(self, your_score, pc_score): # 結束要牌的時候,計算雙方的點數,判斷輸贏 if your_score > 21 and pc_score > 21: print(f'平局,分數: {your_score}:{pc_score}') return np.array([0, 0]) elif your_score > 21 and pc_score <= 21: print(f'你輸了,分數: {your_score}:{pc_score}') return np.array([0, 1]) elif your_score <= 21 and pc_score > 21: print(f'你贏了,分數: {your_score}:{pc_score}') return np.array([1, 0]) elif your_score <= 21 and pc_score <= 21: if your_score < pc_score: print(f'你輸了,分數: {your_score}:{pc_score}') return np.array([0, 1]) elif your_score > pc_score: print(f'你贏了,分數: {your_score}:{pc_score}') return np.array([1, 0]) else: print(f'平局,分數: {your_score}:{pc_score}') return np.array([0, 0]) def one_round(self): # 一個回合的游戲 self.cards.send_card(self.player, 2) self.cards.send_card(self.computer, 2) self.player.show_card(1) self.computer.show_card(0, False) score = np.array([self.player.get_value(), self.computer.get_value()]) if score[0] == 21 or score[1] == 21: print('BlackJack 21點直接獲勝') return self.judgement(score[0], score[1]) else: while score[0] <= 21: Get_New_Poker = self.hit_or_stand() # 要了一張牌 if Get_New_Poker: self.player.show_card(1) self.computer.show_card(0, False) score[0] = self.player.get_value() if score[0] > 21: print('你超過21點') self.computer.show_card(0) print() return self.judgement(score[0], score[1]) else: continue elif not Get_New_Poker: # npc點數比玩家低,則要牌 while score[1] < score[0]: self.cards.send_card(self.computer) score[1] = self.computer.get_value() self.player.show_card(1) self.computer.show_card(0) print() return self.judgement(score[0], score[1]) else: continue def hit_or_stand(self): # 玩家需要判斷是否繼續叫牌 AskPoker = input('是否叫牌? 【Y/N】>>:') if AskPoker.upper() == 'Y': print() self.cards.send_card(self.player) return True elif AskPoker.upper() == 'N': print('你沒加牌.') print() return False else: print('輸入錯誤 Y/y or N/n!>>') return self.hit_or_stand() def continue_or_quit(self): # 在每一輪結束后,判斷是否繼續下一輪的游戲。當牌堆里面牌的數目不足的時候,自動停止游戲 NextRound = input('是否繼續? 【Y/N】>>') if NextRound.upper() == 'Y': if len(self.cards.getCard()) < 10: print('牌不夠了') input('Game Over') exit(1) else: return True elif NextRound.upper() == 'N': input('Game Over') exit(1) else: print('輸入有誤') self.continue_or_quit() if __name__ == '__main__': startGame = GameManager() startGame.start_game()
效果: