###### tags: `APCS` # **b519-撲克牌遊戲** ### **題目連結:** [**b519**](https://zerojudge.tw/ShowProblem?problemid=b519) ### **題目解析** 此題目是撲克牌遊戲的一部分,我們需要判斷玩家手上的五張牌屬於哪種牌型,並根據牌型給予對應的分數。牌型包括同花順、四條、葫蘆、順子、三條、兩對、一對和雜牌。每種牌型都有不同的得分。 ### **解題方向** * 將每張牌轉換為花色和點數:根據給定的數字,我們需要將其轉換為相應的花色和點數。 * 判斷牌型:依次檢查是否為同花順、四條、葫蘆、順子、三條、兩對和一對。如果不屬於任何一種牌型,則為雜牌。 * 計算分數:根據判斷出的牌型,給予對應的分數。 ### **程式解析** 讀取輸入 ```python # Start N = int(input()) ``` 逐行處理測試資料 ```python for s in sys.stdin: data = list(map(int, s.split())) ``` 轉換牌號為花色和點數 ```python # Set input card, separate flower and number handcard = [] for i in data: card = [] flower = math.ceil(i / 13) # 1, 2, 3, 4 number = i % 13 # 0~12, 0=K card.append(flower) card.append(number) handcard.append(card) ``` * 將每張牌的數字轉換為對應的花色和點數,並存入handcard列表中。 * flower:根據數字計算牌的花色。 * number:根據數字計算牌的點數。 初始化分數 ```python score = 0 ``` 檢查順子 ```python card_num = [] for i in range(5): card_num.append(handcard[i][1]) card_num.sort() # 把數字丟入此arr並由小到大排序 ``` * 提取所有牌的點數,並將其排序。 ```python diff = 0 for i in range(4): if card_num[i + 1] - card_num[i] == 1: diff += 1 if diff == 3 and sum(card_num) == 34: diff += 1 # 10 J Q K A 特例 if diff == 4: # 至少是順子 score = 4 ``` * 檢查是否為順子: * diff:記錄相鄰牌的點數差是否為1。 * 若連續4次相鄰牌的點數差為1,則為順子。 * 特別處理10, J, Q, K, A的情況。 檢查同花 ```python now_flower = handcard[0][0] isFlush = True # 起始預設True for i in range(1, 5): if handcard[i][0] != now_flower: # 檢查花色是否相同 isFlush = False if isFlush == True: # 判斷是不是同花順 score += 3 ``` * 若為順子,則進一步檢查是否為同花順: * isFlush:標記是否為同花。 * 若所有牌的花色相同,則為同花順,分數加3。 檢查對子 ```python else: # Check pairs num_type = [] for i in range(5): now_point = handcard[i][1] for j in range(i + 1, 5): if handcard[j][1] == now_point: score += 1 # 有一個與先前相同就+1 if now_point not in num_type: # 丟入num_type num_type.append(now_point) ``` * 若不是順子,則檢查對子: * num_type:記錄出現過的點數。 * 檢查是否有相同點數的牌,並計算出現次數。 檢查葫蘆 ```python # Check fullhouse if len(num_type) == 2 and score == 4: # 檢查葫蘆 score += 1 ``` * 若有兩種點數,且分數為4(代表至少有一個三條和一個對子),則為葫蘆,分數加1。 輸出結果 ```python print(score) ``` ### **完整程式碼** ```python= import sys, math # Start N = int(input()) for s in sys.stdin: data = list(map(int, s.split())) # Set input card, separate flower and number handcard = [] for i in data: card = [] flower = math.ceil(i/13) # 1, 2, 3, 4 number = i % 13 # 0~12, 0=K card.append(flower) card.append(number) handcard.append(card) score = 0 # Check straight card_num = [] for i in range(5): card_num.append(handcard[i][1]) card_num.sort() # 把數字丟入此arr並由小到大排序 diff = 0 for i in range(4): if card_num[i+1] - card_num[i] == 1: diff += 1 if diff==3 and sum(card_num)==34: diff+=1 # 10 J Q K A 特例 if diff == 4: # 至少是順子 score = 4 # Check flower now_flower = handcard[0][0] isFlush = True # 起始預設True for i in range(1, 5): if handcard[i][0] != now_flower: # 檢查花色是否相同 isFlush = False if isFlush == True: # 判斷是不是同花順 score += 3 else: # Check pairs # 檢查對子 num_type = [] for i in range(5): now_point = handcard[i][1] for j in range(i+1, 5): if handcard[j][1] == now_point: # 判斷目前點數與先前的(now_point)是否相同 score += 1 # 有一個與先前相同就+1 if now_point not in num_type: # 丟入num_type num_type.append(now_point) # Check fullhouse if len(num_type) == 2 and score == 4: # 檢查葫蘆 # 「葫蘆」為三張同數字,另兩張同數字的牌;一個「一對」和「三條」所組成的五張牌; # 得分5分; score += 1 print(score) ```