python3 實現麻將胡牌問題

2021-10-02 06:43:01 字數 4027 閱讀 8068

題目描述:

清一色是麻將番種之一,指由一種花色的序數牌組成的和牌.

數字1-9,每個數字最多有4張牌

我們不考慮具體花色,我們只看數字組合。

刻子:三張一樣的牌;如: 111, 222, 333, …, 999

順子:三張連續的牌;如: 123, 234, 345, …, 789

對子:兩張相同的牌;如: 11, 22, 33, …, 99

需要實現乙個程式,判斷給定牌,是否可以和牌(胡牌)。

和牌要求:

思路:輸入字元合法性校驗自然不用多說,本題使用遞迴求解,首先判斷當前牌型是否包含順子或者刻子,如果包含就去除這些字元,直到最後剩下兩張牌時,再判斷這兩張牌是否相同,相同則可胡,不相同就胡不了了,具體實現看**:

import copy

class ma_jiang()

: def __init__

(self, pai_str)

: is_invalid_input = self.

is_invalid_input

(pai_str) #判斷輸入是否合法

if is_invalid_input != false:

print

('error message: '

+ is_invalid_input)

else

:print

(self.

if_win([

int(i)

for i in list

(pai_str)])

) def is_invalid_input

(self, par_str)

: length =

len(par_str)

temp_str =

list

(par_str)

temp_str.

sort()

if length >

14 or length <2:

return

'長度不合法'

elif par_str.

isdigit

() and temp_str.

count

('0')!=

0:return

'包含非法字元'

elif length not in [2,

5,8,

11,14]

:return

'胡牌數量不夠'

elif par_str !=''.

join

(temp_str)

:return

'輸入字元未排序'

else

:for i in set

(temp_str)

:if par_str.

count

(i)>4:

return

' '.

format

(i,'出現次數超過四次'

)return false

def if_win

(self, pai_list):if

len(pai_list)==2

: # 剩餘兩張牌時,相等則胡

if pai_list[0]

== pai_list[1]

:return

'yes'

return

'no'

for index in range

(len

(pai_list)-2

): # 判斷是否有刻子

if pai_list[index]

== pai_list[index +

1] and pai_list[index]

== pai_list[index +2]

: pai_list[index]=-

1 # 使用-

1標記需要刪除的牌,一會統一刪,不然元列表位置索引會亂

pai_list[index +1]

=-1 pai_list[index +2]

=-1return self.

if_win

(self.

remove_pai

(pai_list)

) has_shunzi = self.

has_shunzi

(pai_list) # 判斷是否有順子

if has_shunzi.

count(-

1)==3

:return self.

if_win

(self.

remove_pai

(has_shunzi)

)return

'no' # 所有牌都迭代完,都沒有刻子順子對子,則不胡

def remove_pai

(self, pai_list)

: temp = copy.

copy

(pai_list)

for item in temp:

if item ==-1

: pai_list.

remove

(item)

return pai_list

def has_shunzi

(self, pai_list)

: temp_list = copy.

copy

(pai_list)

for index1 in range

(len

(pai_list)-2

):temp =-1

# 標記與當前元素pai_list[index1]第乙個相鄰元素的索引temp,找到後記住位置

for index2 in range

(index1 +1,

len(pai_list)-1

):if pai_list[index1]

== pai_list[index2]-1

: pai_list[index1]=-

1 temp = index2

break

if temp !=-1

: # 標記與當前元素pai_list[index1]第乙個相鄰元素的索引pai_list[temp]相鄰的第乙個元素index3,

for index3 in range

(temp +1,

len(pai_list)):

if pai_list[temp]

== pai_list[index3]-1

: pai_list[temp]=-

1 pai_list[index3]=-

1break

if pai_list.

count(-

1)==3

: # 有三張牌被標為-

1,表示有順子,停止迭代

return pai_list

else

: pai_list = temp_list # 進入下一輪迭代,原來的標記釋放掉

return temp_list

if __name__ ==

'__main__'

:ma_jiang

('11122233344455'

) # 可胡牌型

ma_jiang

('12233344455688'

) # 可胡牌型

ma_jiang

('11344555666778'

) # 可胡牌型

ma_jiang

('11122245667999'

) # 不胡牌型

python3模擬撲克牌

python3.6環境 import collections from random import choice card collections.namedtuple card rank suit class frenchdeck ranks str n for n in range 2,11 l...

棋盤覆蓋問題python3實現

在2 k 2 k個方格組成的棋盤中,有乙個方格被占用,用下圖的4種l型骨牌覆蓋所有棋盤上的其餘所有方格,不能重疊。如下 def chess tr,tc,pr,pc,size global mark global table mark 1 count mark if size 1 return hal...

棋盤覆蓋問題python3實現

在2 k 2 k個方格組成的棋盤中,有乙個方格被占用,用下圖的4種l型骨牌覆蓋全部棋盤上的其餘全部方格,不能重疊。例如以下 def chess tr,tc,pr,pc,size global mark global table mark 1 count mark if size 1 return h...