貌似去年去面試一家公司,問了麻將的演算法。雖然之前做過廣東麻將,但是胡牌演算法在服務端,就沒有在意。
現在在網上搜了一些演算法試了試 = =!
麻將普通的胡牌就是刻子+順子+將。癩子可以充當任意一張牌。
網上蒐羅的演算法,先取將牌,然後遞迴判斷剩下的牌是否能組成刻子或順子。
public canhulaizi(cards, laizi)
// 排序方便胡牌判斷
cards.sort(function(a, b) )
// 依次刪除一對牌做將,其餘牌全部成撲則可胡
for (var i = 0; i < cards.length; i++)
if ((i + 1 < cards.length && cards[i] == cards[i + 1]) || laizi > 0)
else
// 刪去對子判斷剩下的牌是否成撲
if (this.ispu(pucards, pulaizi))
} }
if (laizi >= 2 && this.ispu(cards, laizi - 2))
return false;
}
遞迴判斷陣列cards是否能組成順子或刻子
public ispu(cards, laizi)
// 若第一張是順子中的一張
for (var first = cards[0] - 2; first <= cards[0]; first++)
var shuncount = 0;
for (var i = 0; i < 3; i++)
} if (shuncount == 3 || shuncount + laizi >= 3)
else
} if (this.ispu(pucards, pulaizi))
} }
// 若第一張是刻子中的一張
var kezicount = 1;
var kezicard = cards[0];
if (cards[1] == kezicard)
if (cards[2] == kezicard)
if (kezicount == 3 || kezicount + laizi >= 3)
else
} if (this.ispu(pucards, pulaizi))
} return false;
}
測試1萬次,含4癩子是否能胡牌。大概花了50ms。
// cards:手牌陣列,不超過14張牌,每張牌由整數表示如下
// 條:1, 2, 3, 4, 5, 6, 7, 8, 9,
// 萬:11, 12, 13, 14, 15, 16, 17, 18, 19,
// 筒:21, 22, 23, 24, 25, 26, 27, 28, 29,
// 東南西北中發白:31, 41, 51, 61, 71, 81, 91,
//
// laizi:癩子數量,用整數表示
let cardlist = [1,1,2,3,4,23,24,27,28,5];
let laizi = 4;
let bhupai;
let starttime = egret.gettimer();
for(let i=0;i<10000;i++)
console.log(egret.gettimer() - starttime, bhupai); //51 true
判斷聽牌,就是將條,萬,索,字共34張麻將牌遍歷一遍加入手牌,看是否能胡,如果能胡,則表示聽此張牌。
癩子麻將胡牌判斷
牌值 var cardvalue 1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27,28,29,31,41,51,61,71,81,91 定撲 function ispu cards,laizinum 順子判斷 var...
棋牌麻將 無癩子胡牌演算法
本文涉及的所有名詞均在博文中有說明 去除雜念 由於字牌中只只允許出現對子和刻子,所以單獨處理字牌.返璞歸真 萬 筒 條牌等序數牌處理除了花色不同其他規則一致,所以忽略序數牌花色進行處理.分而治之 序數牌中存在關係的牌必須是連續的,不連續的牌之間不會存在關係,所以對連續牌進行分片.各司其職 單一分片能...
麻將胡牌演算法
majiang algorithm是帶多張鬼牌的通用胡牌演算法,採用查表方式,簡單高效。在生成表的階段,時間是不值錢的,所以生成方法我們可以任意窮舉。首先分為普通 風 箭三張表。窮舉出所有的key,比如普通表,就是000000000 444420000,因為每一種牌最大4張,且總和不超過14張牌。對...