麻将计算器3个3条2和4条三条算砍吗

成都麻将胡牌问题算法 - 推酷
成都麻将胡牌问题算法
*&成都麻将只能包括3种类型:筒(D),万(W),条(T)。没有“门、东南西北、红中”。
*&每种牌都是数字从1到9,每个数字有4张,共36张。筒(D),万(W),条(T)均一样。
*&胡牌规则如下:&
*&1、手里面的牌最多只有两种类型,即必须打缺一种,不能出现:条,筒,万都存在的情况。
*&2、必须有一个对子,即两张相同的牌,比如:两个2筒,两个4条等。&
*&3、剩余的牌,每3张需要凑成一个有效牌,比如:3个一样的牌(3个2筒),
*&或者3个顺子(1条2条3条),如果所有的牌都能够凑好,再满足规则2和1,有一个对子,&并且所有的牌只有两种类型,
*&那么就可以胡牌了。
*&4、有一种特殊牌,叫做七对,即全部的牌都是成对出现,&比如:2筒2筒5筒5筒3筒3筒4条4条8条8条1条1条2条2条,
*&一共7对,再满足条件1,也可以胡牌。
*&5、假设牌不会出现碰的情况,即手里面的牌肯定是14张。&输入数据肯定都是麻将牌,不用考虑异常输入;也不用考虑会输入“门”,“红中”等成都麻将中不会出现的牌
* 输入14张牌,判断能不能胡牌。
* 例如: 输入:1D1D2D2D3D3D4W4W5W5W6W6W7W8W 输出:False; 输入:1D1D1D3D3D3D4D5D6D7D8D9D4D4D 输出:True
分析,建模:
0 以下的分析不包括7组对胡牌的情况,这种情况由于其特殊性,单独处理。
1 关于牌面的关系,比较特殊的两种情况是:相同,连续。用户输入的是字符,对于后一种关系的判断不是很方便。怎么办呢?很自然的就可以想到为每张牌面编码,相邻的牌面的编码也连续。于是,我们很自然的想到,总共三种牌,每种从1到9,那么需要27个数就可以。于是假设‘D’的牌编号从0到9,‘W’的牌面编号从10到18,‘T’的牌面编号从19到27。按照这样的编码方式,如果手中的牌是1D1D1D,则对应的编号列表就是[1,1,1];顺子的编号就是[i, i+1, i+2]。
2 关于牌面组合的方法。因为要胡牌,所有的牌必须和其他的牌以某种关系组合,在牌面已经编码的情况下,这种关系就是找到三张一样的牌或者连续的三张牌。考虑,假设牌堆有牌i和i+2,而没有i+1,那么i和i+2是不会发生任何联系的,也就是说,牌面编码上联系或相同的牌才可能发生联系。于是,可以先对手牌排序,我们以此从前向后来寻找这样的关系,找到就剔除,继续下去。如果最后所有的牌都能被剔除,则可以胡牌。比如说,某个阶段,序列的前三个数值为[9,10,11]我们就可以认为他们是9D1W2W。。。等一下,好像出问题了。这种情况下。虽然数值上连续,但是实际上却横跨了两个花色。对于这个问题,有两种解决方法,第一种,就是在后期判断时,以9n为界限,不许出现跨界配对,第二种,就是对我们的编码规则稍作修改,仔细考虑会引起这个问题的原因是我们在编码时只加入了对点数的考虑,没有能区别花色的因素。为了让不同花色的牌面不能配对,我们在编码时加入间隔。最简单的一种方法就是:‘D’的牌编号从1到9,‘W’的牌面编号从11到19,‘T’的牌面编号从21到29。以下是关于牌面编码的代码:
class SiChuanMaJiang(object):
pattern = ('D', 'W', 'T')
def __init__(self, pai):
= int(p[0])
self.view = pai
= SiChuanMaJiang.pattern.index(self.pt)*10 + self.num #编码,通过间隔一个数字,达到区别花色的目的
这样,再后期检索列表配对时,就不会出现跨花色配对的麻烦。
现在附上整个过程的代码(没有考虑7对出现的情况):
1 class SiChuanMaJiang(object):
pattern = ('D', 'W', 'T')
def __init__(self, pai):
= int(p[0])
self.view = pai
= SiChuanMaJiang.pattern.index(self.pt)*10 + self.num
10 class InputParse(object):
@classmethod
def split_pai(cls, input): # 把字符串分开
result = []
for i in range(0, 28, 2):
result.append(input[i:i+2])
return result
18 class PaiAnaly(object):
def __init__(self):
self.total_num = 0
self.patterns = []
self.id_list
def next_one(self, pai_instance):
if pai_instance.pt not in self.patterns:
self.patterns.append(pai_instance.pt)
self.id_list.append(pai_instance.id)
self.total_num += 1
@staticmethod
def qi_pai(pai_instance_list): # 对整个手牌进行统计
pai_mian = PaiAnaly()
map(lambda x: pai_mian.next_one(x), pai_instance_list)
return pai_mian
@staticmethod
def find_ok_three(sort_list):
if sort_list[0] == sort_list[1] and \
# 因为已经排序,所以直接找前三个是否相同,相同就返回
sort_list[1] == sort_list[2]:
return sort_list[1], sort_list[2]
for i in range(1, len(sort_list)): # 寻找sort_list[0]+1
if sort_list[i] & sort_list[0] + 1:
return False
if sort_list[i] == sort_list[0] + 1:
if sort_list[i] == sort_list[0]:
if idx1 == 0:
return False
for j in range(idx1+1, len(sort_list)): # 在找到sort_list[0]+1的情况下,寻找sort_list[0]+2
if sort_list[j] & sort_list[idx1] + 1:
return False
if sort_list[j] == sort_list[idx1] + 1:
if sort_list[j] == sort_list[idx1]:
if idx2 == 0:
return False
return sort_list[idx1], sort_list[idx2] # 若找到,就返回。
@staticmethod
def recur_check(lt): # 递归过程
if len(lt) != 0: # 当列表为空,就认为可以胡牌
re = PaiAnaly.find_ok_three(lt)
if not re:
return False
else: # 如果依然能够配对,就去除已经配对的牌,继续递归调用
lt.remove(lt[0])
lt.remove(re[0])
lt.remove(re[1])
return PaiAnaly.recur_check(lt)
return True
def find_duizi(self): # 找出手牌中所有的对子,然后以每个对子作为头,调用以上的递归过程
for i in range(13):
# print self.id_list[i]
if self.id_list[i] == self.id_list[i+1] and \
self.id_list[i] != self.id_list[res[-1]]:
res.append(i)
except IndexError:
res.append(i)
return res
def judge_hui(self):
self.id_list.sort()
if self.total_num != 14:
return False
if len(self.patterns) == 3:
return False
duizi_index = self.find_duizi()
print '本来牌面: %s' % self.id_list
for idx in duizi_index:
tl = copy.deepcopy(self.id_list)
print '对子: %s%s' % (tl[idx], tl[idx+1])
val = tl[idx]
tl.remove(val)
tl.remove(val)
print '去除对子以后的牌面: %s' % tl
PaiAnaly.recur_check(tl)
'-------------'
return True
120 if __name__ == '__main__':
pai_string = raw_input('牌面:')
pai_list = InputParse.split_pai(pai_string)
pai_instance_list = []
for p in pai_list:
pai_instance_list.append(SiChuanMaJiang(p))
pai_ready = PaiAnaly.qi_pai(pai_instance_list)
r = pai_ready.judge_hui()
print '胡了'
print '不能胡'
以上的代码看似没有问题,其实,任然有一点不足:
在find_ok_three方法中,我们找到三张一样就返回,没有寻找是不是还存在顺子的情况,举个例子:假设此时列表中的前5张牌为[1,1,1,2,3,...],那么这个时候,我们的程序会返回对牌1,1,1,然后程序会把这些数删除,继续递归过程。而另一方面,如果,我们先删除1,2,3然后再递归,那么这两次递归的结果会不会有什么不一样呢。再进一步说,优先删除对牌,进行递归,会不会造成误判,即:是否本来可以判定胡牌的牌面,因为优先删除对牌的策略,导致判定为不能胡牌。
现在,我们假设,优先删除对牌不会造成误判,即证明:
&&&优先选择去除三个一样的算法是对结果无害的。&&&
证明过程:
#&能去除3个,只有两种情况:前三个一样&或者&前四个一样。
# (1) 若前三个一样。假设为a,则序列为[a,&a,&a,&a+1,...]
#&&&&&&则胡牌可能为{[a,&a,&a], 其他序列...},或者{[a,&a+1,&a+2],&[a,&a+1,&a+2],&[a,&a+1,&a+2],&...},&
#&&&&&&可以看到,在第二种情况下,a+1,a+2&也至少有3个,
#&&&&&&分类讨论:
# & & & & &(A) a+1 个数= 3&&&a+2 个数 &=&3
#&&&&&&&&&&这时按照优先去除三个一样的做法,会依次去除三个a+1,&三个a+2,则剩余的牌的数量和第二种一致,这时候,判定结果只取决于最后三张牌,显然无影响。
# & & & & &(B) a+1 个数=&4&&&a+2 个数&=&3
#&&&&&&&&&&这时会先去除三个a+1,&剩余一个a+1,必然配对{a+1,&a+2,&a+3},&又有a+2的张数大于等于3,所以若此时想配对,只有可能是[a+2,&a+2,&a+2]
# & & & & &这种情况下的能胡牌的牌面是固定的[a,&a,&a,&a+1,&a+1,&a+1,&a+1,&a+2,&a+2,&a+2,&a+2,&a+3],算法判定胡牌,不会出错。
# (2) 若前四个一样。假设为a,则序列为[a,&a,&a,&a,&a+1,...]
#&&&&&&则胡牌可能为{[a,&a,&a],&[...]},或者{[a,&a+1,&a+2],&[a,&a+1,&a+2],&[a,&a+1,&a+2],&[a,&a+1,&a+2]},&
#&&&&&&可以看到,在第二种情况下,只有一种情况能胡牌:a,&a+1,a+2&各有4个,
#&&&&&&按照优先去除三个一样的算法,依次做下去,会依次去除[a,&a,&a],&[a,&a+1,&a+2],&[a+1,&a+1,&a+1],&[a+2,&a+2,&a+2],判定胡牌,不会出错。
#&&综上,优先去除三个一样的做法一定能得到正确答案,若改进题目为求所有可能的胡法,则需要分叉处理。&
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致您现在的位置: >
四川麻将之血战到底的规则
& & & & 中国麻将对于普通中国人来说是最受欢迎的游戏了,这已是勿庸置疑的了,搓麻将不但可以改善国人的休闲时间,还可以大大拉近我们和兄弟以及朋友互相间的距离,让大家可以从麻将中品尝到无限的乐趣。假如你要精确认识一件事物,你就需要用一分二方法去认识它。
& & & &是一种很有意思的的地方特色麻将游戏。在地方上,有非常高的人气和非常多人的追捧,麻将也给这个具有独特风情的城市带来了活力,令这座城市别具一格。接下来在下说& 一说具有地方特色的血战麻将的玩法。
& & & & 一、血战麻将牌库
麻将牌136张,包括万(从1到9,每种4,共有36张),索(1、2、3...9,每个四张,共36),筒子(1-9,每种四张,共有36张),中发白、东西南北(7乘以4共有28张)。余下的有春夏秋冬梅兰菊竹这八朵花所以一付麻将牌有144张。但也有一些地方先抽掉杠花,这样的话就只有136张麻将牌了。
& & & & 二、血战麻将行牌规则
行牌顺序:按照麻将桌逆时针的方向来抓牌、出牌、吃牌、碰牌、杠牌、补牌、和牌。
基本规则:在搓麻将的过程中,当一张牌打出,而且还有2位以上玩家都可吃碰这个牌的时候,碰比吃优先,如果有多位玩家能够吃牌时,首先叫吃者吃牌。
& & & & 三、血战麻将的基本术语
& & & & 自首:又叫做&五自首&、&九自首&。打麻将开局之前,要是庄家所投的点数为5或者是9那么需要再掷一次。
& & & & 喂张:指的是玩家打的一张被其他人吃或者是碰的牌。
& & & & 番种:此术语指的是玩麻将胡牌时,你摸到的胡牌组合根据规则会具有规定的分值,这种规则我们叫做番种。
& & & & 三钓:这个术语与双钓类似,说的是一副大顺子能够和3张牌。
& & & & 试张:也叫做编张,指的是为搞乱其他玩家而有意打的牌。
& & & & 面子:此术语说的是你的手里的牌只要能够组成对子、坎搭、拼子、边搭这种的组合牌,都可以称为面子。
& & & &上张:又叫做进张,意思是抓进了玩家所需要的牌。
& & & &筋线牌:此术语指的是序数牌中的一四七、二五八、三六九等等组合牌。
& & & &多张、少张:此术语意思是当你打麻将桌面的牌不符合规则规定的数量,多或者少牌。
& & & &老牌:这个术语意思是门牌中的六到九。
& & & &混子:这个术语便是我们常说的百搭牌,但是地方不一样叫法也有所不一样,有些地区叫做&财神&,有的地区叫做&宝牌&等等,意思便是混子可以替代任何一张手牌。
& & & &海底:此术语说的是牌墙中央的区域。
& & & &坎张五:又叫为&坎中心&,说的是坎张的数字为5的顺子。
& & & &刻子:3个相同的雀牌。碰别人牌的称之为明刻,抓在手里的叫暗刻。
& & & &四、血战麻将胡牌的基本牌型
&&& 1.2个2筒、4条5条6条、4筒5筒6筒、3条4条5条、7万8万9万。
&&& 2.2个4条、1条2条3条、1筒2筒3筒、3个1条、7万8万9万。
&&& 3.2个7万、3个5万、6筒7筒8筒、1条2条3条、1筒2筒3筒。
&&& 4.2个9筒、2筒3筒4筒、2条3条4条、1筒2筒3筒、3个7条。
&&& 5.2个北风、5筒6筒7筒、3个白板、6条7条8条、2万3万4万。
& & 玩麻将游戏,上91y麻将游戏网(/),体会不同的麻将游戏风味!
上一篇:没有了攀枝花麻将
一、攀枝花麻将(传统打法)概况
    特点:血战、杠立结、亮尾灯、杠尾灯、唱歌跳舞
二、攀枝花麻将(传统打法)规则
  1、本地专用名词和术语
   1) 血战:血战场中的血战模式指一玩家胡牌了并不结束该局,而是未胡的玩家继续打,直到有3家都胡或者余下的玩家流局。这样先胡的玩家不一定获利最多,点炮的玩家也能翻身,提高了博弈性和趣味性,促进了牌局的稳定发展。牌局结束,一并结算,如果胡了的玩家提前离开,则不给予所赢番数。
   2) 查叫:如果牌已摸完,仍然有两家以上仍未胡牌,就要对仍未胡牌的各家“查叫 ”,已经胡牌的不计,无叫方赔有叫方,有叫方不需要赔。根据有叫方的牌面翻数、是否唱歌、跳舞等计算,有多大赔多大,直至封顶数。
   3) 杠牌:杠牌与是否胡牌无关,单独计算,杠牌分为明杠、暗杠、点杠,明杠的收益为基数*1*在场人数,点杠的收益为基数*2*1,暗杠的收益为基数*2*在场人数。杠牌单独算钱,不管是否胡牌,杠牌须亮出来出示给其它玩家。
    a)、暗杠:自己摸起同样四张牌,且倒下; 还没胡牌玩家 每家给两张;
    b)、点杠:任一家打出己方未碰的三张同样的牌,倒下杠牌,点家给2张,其它无关;
    c)、巴杠:己方摸到自己所碰的牌(如果自己手上的牌放一张下去与碰过的牌杠不算巴杠,不能收钱), 还没胡牌玩家 每家给1张;
    d)、暗杠上暗杠: 还没胡牌玩家 每家给6张(2+2*2);
    e)、暗杠上巴杠: 还没胡牌玩家 每家4张(2+1*2);
    f)、巴杠上暗杠: 还没胡牌玩家 每家5张(1+2*2);
    g)、巴杠上巴杠: 还没胡牌玩家 每家3张(1+1*2);
    h)、如果连续出现杠牌,就以杠牌的基数2*出现的次数*2来计算。如A杠后点B的杠,则B的杠牌算分为2*1*2=4,A付分给B;B杠后点C的杠,则C的杠牌算分为2*2*2=8,B付分给C;B杠后点在D的杠,则D的杠牌算分为2*3*2=12,C付分给D。依次累推。
    i)、如果杠牌是一直连续的,就一直乘2。有时会连续出现3、4个杠,虽然情况极少。哪个点的,哪个给。自已摸的暗杠,三家要支付。
   4) 传统规则杠牌的摸牌规则:杠牌后需要摸起最后一张牌(尾灯牌)。
   5) 亮尾灯:即庄家抓第一手牌后,翻开每盘可直接摸取的最后一张牌。如尾灯被杠走,则继续翻开下一张牌当尾灯,再杠走依次翻。
   6) 归牌:已碰过此牌,正好在叫此牌,胡牌称为“明归”;既能杠,又能胡时,胡牌优先,此时称为“暗归”;明归的收益为牌面翻数*唱歌*跳舞*2*在场人数(自摸受影响人数,点炮为1),暗归的收益为牌面翻数*唱歌*跳舞*4*在场人数。
   7) 卡心五:有牌为或46,叫牌为5时,称为卡心五,翻番。
   8) 唱歌、跳舞:听牌时将所胡的牌亮出,这种玩法叫“跳舞”,另外未胡玩家不能打出其所胡的牌,“跳舞”者只能自摸;“跳舞”后若自身胡牌或点炮或查叫,均按牌面*对方是否唱歌*对方是否跳舞*4倍给付计翻。听牌时告知其它未胡玩家已经听牌,且摸牌不能换牌,要么胡牌,要么打出,直至其它玩家打出所要胡牌或自摸;这种玩法叫“唱歌”;唱歌后如有人放炮必须胡牌。“唱歌”后若自身胡牌或点炮或查叫,均按牌面*对方是否唱歌*对方是否跳舞*2倍给付计翻。“唱歌”或“跳舞”后 如遇到杠上炮、杠上花则番数翻倍。(4*2或2*2),最后四敦牌(即最后八张牌)时不允许唱歌、跳舞。牌桌上有2家以上的唱歌或跳舞玩家时,各自按自身的出牌、胡牌规则进行。有跳舞玩家在先其他未胡牌玩家也可进行唱歌。玩家在没有下叫的情况下进行唱歌、跳舞称为诈胡,需按每家封顶价格赔偿3位玩家。
   9) 封顶:玩家打牌前先要确定番数是否封顶,一般是32或64番封顶(杠牌不封顶,不算番,单独计算)。
  2、胡牌方式
   1) 自摸:自己所摸的牌正是自己要胡的牌,当时在场的各方均需支付分值。
   2) 点炮:一方打出的牌正是其他方要胡的牌,并由胡牌者确定胡此牌即称为给其点炮。点炮的给分,其它人不计。
   3) 相同翻数的叫若其它玩家点炮或自摸没有胡牌,那么在未过自身的一圈中其它玩家点炮时不能胡牌。(同样要胡的牌,如果对家打了自家不胡的情况下,上家打同样牌则自家也不能再胡这张牌了。(俗称:不能放水)过手以后(即自己摸牌后)下家再打出同样的牌,可胡。)
   4) 放大掴小:若一玩家有2个以上不同翻数的叫牌,并且没有唱歌、跳舞,这时允许在一圈牌中不胡小翻数而胡大翻数的牌。
   5) 必胡规则,当牌局还剩最后8张时,如遇可以胡的牌必须胡。
  3、 番数计算
   1) 攀枝花麻将的翻数=牌面翻数*打法规则确定的,杠牌单独加,不算番。
   2) 牌面翻数,是根据牌型确定,一般有以下种类:未定义牌型
     a)、小七对,即7对牌;胡牌算4番;
     b)、龙七对,即7对中,有4张一样的牌,不能杠牌;胡牌算8番;
     c)、凤7对,即7对中,有两个4张一样的牌,不能杠牌;胡牌算16番;
     d)、卡心五,即听牌4和六,单调5,胡牌算2番;
     e)、将对,即全是2、5、8的大对,胡牌算8番;
     f)、么九,即每砍牌或将牌全带有1和9,胡牌算4番;
     g)、手把一,即手中牌全部碰完,只剩下一张,听牌单钓一张,胡牌算4番; (碰牌后不能换牌,没有此要求)
     h)、清一色,即手中牌、碰牌、杠牌等 全部是条、或万、或筒,胡牌算4番;
     i)、清一色手把一,胡牌算16番;
     j)、大对,三抹牌全部为同一张牌,如3个3万、3个2条、3个9桐,剩下两对牌任碰其中一对牌胡牌,胡牌算两番;
     k)、(明)四归一,即听牌后所胡的牌,是自己所碰的牌,算两番;( 还有一种情况:碰牌后,又摸碰了的第4张牌,摸起不杠,与手上的牌正好成一砍,胡其它的牌。如碰了4条,又摸4条,手中有3条、4条,听牌2条、5条;或者手中有3条、4条、5条,胡其它的牌。 )
     l)、暗)四归一,胡牌后,手中有4张牌为同一张牌(不管这4张牌是按123、 111 组合还是按 1111 组合),且未杠牌,算四番;( 这4张牌必须与另两张牌组合成顺子。如4个5加上6、7,或者4个5加上3、4,或者4个5加上4、6。)
     m)、杠上花,杠牌后摸的一张牌正好能胡牌,胡牌算2番,即在胡牌的基础上乘2,例如,卡心五算2张,在此乘2;杠牌另算;
     n)、杠上炮,杠牌后打出去的牌正好有人要胡,胡牌算2番,即在胡牌的基础上乘2。
     o)、天叫:天叫的基础翻数为4翻,还可以配合唱歌、跳舞同时进行再行计翻。
     p)、天胡:默认情况下按封顶值确定天胡的输赢数,天胡属于自摸。
   3) 打法规则,是当玩家选择的打法或进行唱歌、跳舞时产生的变化倍数。
     a)、“唱歌”、“跳舞”,玩家胡牌时与其胡牌直接关系的玩家中只有一方唱歌,则翻数*2,与其胡牌直接关系的玩家中只有一方跳舞的,则翻数*4;若与其胡牌直接关系的玩家中双方均唱歌,称为对唱2*2=4番;若与其胡牌直接关系的玩家中双方均跳舞,称为对跳4*4=16番;若是一唱一跳则2*4=8番。(举例有玩家跳舞又是第一家自摸平胡胡牌,另3家分别跳舞、唱歌、没唱歌跳舞,则这3家分别输16翻、8翻、4翻)。

我要回帖

更多关于 麻将计算器 的文章

 

随机推荐