帶賴子的超高效麻將、跑鬍子胡牌演算法
阿新 • • 發佈:2018-11-07
騰訊課堂視訊講解:https://ke.qq.com/course/305608?tuin=104cb0e2
文件 github地址 https://github.com/yuanfengyun/qipai/tree/master/doc
lua版 https://github.com/yuanfengyun/qipai/tree/master/mjlib_lua
c++版 https://github.com/yuanfengyun/qipai/tree/master/mjlib_c%2B%2B
golang版 https://github.com/yuanfengyun/qipai/tree/master/mjlib_go
js版 https://github.com/yuanfengyun/qipai/tree/master/mjlib_js
c#版 https://github.com/yuanfengyun/qipai/tree/master/mjlib_c%23
java版 https://github.com/yuanfengyun/qipai/tree/master/mjlib_java
速度:
每秒處理100萬次四個賴子判胡
每秒處理1000萬次八個賴子判胡
QQ: 273461474
核心思想: |
1、名詞解釋:eye(將),字牌(feng、東南西北中發白),花色(萬、筒、條、字牌) |
2、分而治之:檢查手牌是否能胡是依次檢查萬、筒、條、字牌四種花色是否能組成胡牌的一部分。 |
3、單一花色要能滿足胡牌的部分,則要麼是3*n(不帶將),要麼是3*n+2(帶將)。3*n中的3帶表三張牌一樣的刻子,或三張連續的牌如1筒2筒3筒。 |
4、判斷是否滿足胡牌的單一花色部分,需要根據是否有將,有幾個賴子,查詢不同的表。表內容表示表裡的元素加上對應的賴子數量能組成3*n 或3*n+2。 |
賴子數是表名最後的數字,帶有eye的表表示滿足3*n+2,沒有的表示滿足3*n。 |
5、查表的key值,是直接根據1-9有幾張牌就填幾(賴子不算),如1-9萬各一張,則key為111111111。如1萬3張,9萬2張,則key為300000002。 |
6、組合多種花色,判斷是否能胡牌。將賴子分配給不同的花色,有若干種分配方式,只要有一種分配能讓所有花色滿足單一花色胡牌部分,則手牌能胡。 |
如:手上有3個賴子,可以分配萬、筒、條各一張,也可以萬、同、字牌各一張 |
7、根據是否有將、是否字牌分為4種表,每種表又根據賴子個數0-8分別建表,共36張表,具體如下: |
賴子個數 帶將表 不帶將的表 字牌帶將表 字牌不帶將表 |
0 eye_table_0 table_0 feng_eye_table_0 feng_table_0 |
1 eye_table_1 table_1 feng_eye_table_0 feng_table_1 |
2 eye_table_2 table_2 feng_eye_table_0 feng_table_2 |
3 eye_table_3 table_3 feng_eye_table_0 feng_table_3 |
4 eye_table_4 table_4 feng_eye_table_0 feng_table_4 |
5 eye_table_5 table_5 feng_eye_table_0 feng_table_5 |
6 eye_table_6 table_6 feng_eye_table_0 feng_table_6 |
7 eye_table_7 table_7 feng_eye_table_0 feng_table_7 |
8 eye_table_8 table_8 feng_eye_table_0 feng_table_8 |
步驟: |
1、統計手牌中鬼牌個數 nGui,將鬼牌從牌資料中去除. |
2、不同花色分開處理,分別校驗是否能滿足 將、順子、刻子 |
3、分析東南西北風中發白時,不需要分析順子的情況,簡單很多 |
4、分析單一花色時,直接根據1-9點對應數字得出一個9位的整數,每位上為0-4代表該點數上有幾張牌 |
比如:1筒2筒3筒3筒3筒3筒6筒7筒8筒2萬3萬3萬3萬4萬 |
數字:筒: 1,1,4,0,0,1,1,1,0 得出的數字為114001110 |
萬 0,1,3,1,0,0,0,0,0 得出的數字為13100000 |
5、組合多種花色,判斷是否能胡牌。將賴子分配給不同的花色,有若干種分配方式,只要有一種分配能讓所有花色滿足單一花色胡牌部分,則手牌能胡。 |
如:手上有3個賴子,可以分配萬、筒、條各一張,也可以萬、同、字牌各一張 |
每種花色與賴子組合,如果所有花色都能配型成功則可胡牌 |
檢查配型時,每種花色的牌數量必需是3*n 或者 3*n + 2 |
根據賴子個數、帶不帶將,查詢對應表,看能否滿足3*n 或 3*n+2的牌型 |
非字牌表的產生: |
1、窮舉萬字牌所有滿足胡牌胡可能,將對應的牌型記錄為數字,根據是否有將、放入eye_table_0或table_0中。 |
具體是每次加入一個刻子,順子或是將(將只能加入一對),最多加入四組外帶將牌。 |
2、將table_0中牌去掉一張,放入table_1中,表示去掉的牌用1張賴子代替。eye_table_0中牌去掉一張,放入到eye_table_1中。 |
3、將table_1中牌去掉一張,放入table_2中,表示去掉的牌用1張賴子代替。eye_table_1中牌去掉一張,放入到eye_table_2中。 |
4、將table_2中牌去掉一張,放入table_3中,表示去掉的牌用1張賴子代替。eye_table_2中牌去掉一張,放入到eye_table_3中。 |
5、將table_3中牌去掉一張,放入table_4中,表示去掉的牌用1張賴子代替。eye_table_3中牌去掉一張,放入到eye_table_4中。 |
6、將table_4中牌去掉一張,放入table_5中,表示去掉的牌用1張賴子代替。eye_table_4中牌去掉一張,放入到eye_table_5中。 |
7、將table_5中牌去掉一張,放入table_6中,表示去掉的牌用1張賴子代替。eye_table_5中牌去掉一張,放入到eye_table_6中。 |
8、將table_6中牌去掉一張,放入table_7中,表示去掉的牌用1張賴子代替。eye_table_6中牌去掉一張,放入到eye_table_7中。 |
9、將table_7中牌去掉一張,放入table_8中,表示去掉的牌用1張賴子代替。eye_table_7中牌去掉一張,放入到eye_table_8中。 |
字牌表的產生: |
與非字牌表的產生方法相同,只是第一步中,不能加入順子(除非麻將玩法字牌是能組成順子的)
表的大小:總量在2M左右
表生成耗時:2-3S