题设:
class SiChuanMaJiang(object): pattern = ('D', 'W', 'T') def __init__(self, pai): self.pt = p[1] self.num = int(p[0]) self.view = pai self.id = SiChuanMaJiang.pattern.index(self.pt)*10 + self.num #编码,通过间隔一个数字,达到区别花色的目的
1 class SiChuanMaJiang(object): 2 pattern = ('D', 'W', 'T') 3 4 def __init__(self, pai): 5 self.pt = p[1] 6 self.num = int(p[0]) 7 self.view = pai 8 self.id = SiChuanMaJiang.pattern.index(self.pt)*10 + self.num 9 10 class InputParse(object): 11 @classmethod 12 def split_pai(cls, input): # 把字符串分开 13 result = [] 14 for i in range(0, 28, 2): 15 result.append(input[i:i+2]) 16 return result 17 18 class PaiAnaly(object): 19 def __init__(self): 20 self.total_num = 0 21 self.patterns = [] 22 self.id_list = [] 23 24 def next_one(self, pai_instance): 25 if pai_instance.pt not in self.patterns: 26 self.patterns.append(pai_instance.pt) 27 self.id_list.append(pai_instance.id) 28 self.total_num += 1 29 30 @staticmethod 31 def qi_pai(pai_instance_list): # 对整个手牌进行统计 32 pai_mian = PaiAnaly() 33 map(lambda x: pai_mian.next_one(x), pai_instance_list) 34 return pai_mian 35 36 @staticmethod 37 def find_ok_three(sort_list): 38 if sort_list[0] == sort_list[1] and / # 因为已经排序,所以直接找前三个是否相同,相同就返回 39 sort_list[1] == sort_list[2]: 40 return sort_list[1], sort_list[2] 41 idx1 = 0 42 idx2 = 0 43 for i in range(1, len(sort_list)): # 寻找sort_list[0]+1 44 if sort_list[i] > sort_list[0] + 1: 45 return False 46 if sort_list[i] == sort_list[0] + 1: 47 idx1 = i 48 break 49 if sort_list[i] == sort_list[0]: 50 continue 51 if idx1 == 0: 52 return False 53 54 for j in range(idx1+1, len(sort_list)): # 在找到sort_list[0]+1的情况下,寻找sort_list[0]+2 55 if sort_list[j] > sort_list[idx1] + 1: 56 return False 57 if sort_list[j] == sort_list[idx1] + 1: 58 idx2 = j 59 break 60 if sort_list[j] == sort_list[idx1]: 61 continue 62 if idx2 == 0: 63 return False 64 65 return sort_list[idx1], sort_list[idx2] # 若找到,就返回。 66 67 @staticmethod 68 def recur_check(lt): # 递归过程 69 if len(lt) != 0: # 当列表为空,就认为可以胡牌 70 re = PaiAnaly.find_ok_three(lt) 71 if not re: 72 return False 73 else: # 如果依然能够配对,就去除已经配对的牌,继续递归调用 74 lt.remove(lt[0]) 75 lt.remove(re[0]) 76 lt.remove(re[1]) 77 PRint lt 78 return PaiAnaly.recur_check(lt) 79 else: 80 return True 81 82 def find_duizi(self): # 找出手牌中所有的对子,然后以每个对子作为头,调用以上的递归过程 83 res = [] 84 for i in range(13): 85 try: 86 # print self.id_list[i] 87 if self.id_list[i] == self.id_list[i+1] and / 88 self.id_list[i] != self.id_list[res[-1]]: 89 res.append(i) 90 except IndexError: 91 res.append(i) 92 print res 93 return res 94 95 96 def judge_hui(self): 97 self.id_list.sort() 98 if self.total_num != 14: 99 return False100 if len(self.patterns) == 3:101 return False102 103 duizi_index = self.find_duizi()104 print '本来牌面: %s' % self.id_list105 106 for idx in duizi_index:107 tl = copy.deepcopy(self.id_list)108 print '对子: %s%s' % (tl[idx], tl[idx+1])109 val = tl[idx]110 tl.remove(val)111 tl.remove(val)112 print '去除对子以后的牌面: %s' % tl113 r = PaiAnaly.recur_check(tl)114 if not r:115 continue116 else:117 '-------------'118 return True119 120 if __name__ == '__main__':121 pai_string = raw_input('牌面:')122 pai_list = InputParse.split_pai(pai_string)123 pai_instance_list = []124 for p in pai_list:125 pai_instance_list.append(SiChuanMaJiang(p))126 127 pai_ready = PaiAnaly.qi_pai(pai_instance_list)128 r = pai_ready.judge_hui()129 130 if r:131 print '胡了'132 else:133 print '不能胡'
以上的代码看似没有问题,其实,任然有一点不足:
在find_ok_three方法中,我们找到三张一样就返回,没有寻找是不是还存在顺子的情况,举个例子:假设此时列表中的前5张牌为[1,1,1,2,3,...],那么这个时候,我们的程序会返回对牌1,1,1,然后程序会把这些数删除,继续递归过程。而另一方面,如果,我们先删除1,2,3然后再递归,那么这两次递归的结果会不会有什么不一样呢。再进一步说,优先删除对牌,进行递归,会不会造成误判,即:是否本来可以判定胡牌的牌面,因为优先删除对牌的策略,导致判定为不能胡牌。
现在,我们假设,优先删除对牌不会造成误判,即证明:
新闻热点
疑难解答