麻將牌型主是AA,AAA,AAAA,ABC的組合構成胡牌,可以把牌分為明牌和手牌,明牌是指杠,吃,碰之后的牌,手牌指未露出來的牌,聽牌只需要算手牌即可。
聽牌可以分為有對將,其它為圓句,只留一個需要圓句,吃牌胡,或者碰牌胡。
如果無對將,則需所有為圓句和一張單牌吊將。
方法一:
先取一對將,再把剩下的牌遞歸找整句,直到只剩兩張牌,算出缺口牌即為聽的牌。中間任意一步失敗也該組合失敗。
先找整句,剩下的牌再找整句,如此遞歸,只到只剩一張,此牌為聽牌。任意一步失敗該組合也失敗。
算法缺陷:重復的組合很多,例如AAABBBC,BBBAAAC其實是一樣的,卻重復遞歸計算了。
方法二:
思路大體上與方法一一樣,改進點就是要減少重復的組合,找到所有的對,句去組合,再判斷。
算法缺陷:所有的對,句組合(cmn)時往往會也有少量重復計算,原因是句,對會有交叉,另外還要計算交叉組合是否與原牌相符合,計算量也不小。在多數情況下計算量還是要好於方法一。
以上兩種算法均已js實現。
如何處理交叉問題,減少無效組合計算?這確實有點難度,待深度思考。
