| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458 |
- 'use strict';
- //// 为什么选择 Lodash ?
- //// Lodash 通过降低 array、number、objects、string 等等的使用难度从而让 JavaScript 变得更简单。
- //// Lodash 的模块化方法 非常适用于:
- //// 遍历 array、object 和 string
- //// 对值进行操作和检测
- //// 创建符合功能的函数
- var _ = require('lodash');
- var quick = require('quick-pomelo');
- var logger = quick.logger.getLogger('fhmj', __filename);
- // 所有牌
- const CARDS = [
- 11, 12, 13, 14, 15, 16, 17, 18, 19, // 筒
- 21, 22, 23, 24, 25, 26, 27, 28, 29, // 万
- 31, 32, 33, 34, 35, 36, 37, 38, 39, // 条
- // 51, // 中
- 11, 12, 13, 14, 15, 16, 17, 18, 19, // 筒
- 21, 22, 23, 24, 25, 26, 27, 28, 29, // 万
- 31, 32, 33, 34, 35, 36, 37, 38, 39, // 条
- // 51, // 中
- 11, 12, 13, 14, 15, 16, 17, 18, 19, // 筒
- 21, 22, 23, 24, 25, 26, 27, 28, 29, // 万
- 31, 32, 33, 34, 35, 36, 37, 38, 39, // 条
- // 51, // 中
- 11, 12, 13, 14, 15, 16, 17, 18, 19, // 筒
- 21, 22, 23, 24, 25, 26, 27, 28, 29, // 万
- 31, 32, 33, 34, 35, 36, 37, 38, 39, // 条
- // 51, // 中
- ];
- // 块类型
- const STYLE = {
- NULL: 0, // 无效
- CHI: 1, // 吃牌
- SUN: 2, // 顺序
- PENG: 3, // 碰子
- KE: 4, // 刻子
- GANG: 5, // 杠子
- ANGANG: 6, // 暗杠
- ZMGANG: 7, // 自摸明杠
- BUDA:8, // TL++不搭
- // LIANGBD:9, // TL++两张百搭和一张普通牌组成一个块
- // SANBD:10, // TL++三张百搭和一张普通牌组成一个块
- };
- // 椅子数
- const CHAIR_COUNT = 4;
- const CARDS_COUNT = 13;
- // 构造方法
- var Logic = function (type,gameKindTL,playerAllCount,other) {
- // 类型
- this.type = type;
- this.other = other;//////TL++2人3人的游戏规则
- this.jiangmaType = -1;////奖码类型:-1:不奖码,1:159奖码,2:摸几奖几,3:一码全中
- this.jiangmaCount = -1;////奖码张数
- if(this.other & 1){
- this.jiangmaType = 1;
- if(this.other & 8) this.jiangmaCount = 2;
- else if(this.other & 16) this.jiangmaCount = 4;
- else if(this.other & 32) this.jiangmaCount = 6;
- }
- else if(this.other & 2){
- this.jiangmaType = 2;
- this.jiangmaCount = 0;
- }
- else if(this.other & 4){
- this.jiangmaType = 3;
- this.jiangmaCount = 1;
- }
- this.hzCount = 0;/////红中个数
- if(this.other & 64) this.hzCount = 8;
- else if(this.other & 1024) this.hzCount = 6;
- else if(this.other & 2048) this.hzCount = 8;
- this.isQGHJM = false;/////是否抢杠胡奖码
- if(this.other & 128) this.isQGHJM = true;
- this.isHZHG = false;/////是否荒庄荒杠
- if(this.other & 256) this.isHZHG = true;
- this.isWGHZJYM = false;/////无红中胡加一码
- if(this.other & 512) this.isWGHZJYM = true;
- this.isZNZM = this.type == 2;/////是否只能自摸,拉杠情况可以胡
- // console.warn("logic 奖码类型:-1:不奖码,1:159奖码,2:摸几奖几,3:一码全中 "+this.jiangmaType)
- // console.warn("logic 奖码张数 "+this.jiangmaCount)
- // console.warn("logic 是否红中赖子 "+this.isHZLZ)
- // console.warn("logic 是否抢杠胡奖码 "+this.isQGHJM)
- // console.warn("logic 是否荒庄荒杠 "+this.isHZHG)
- // console.warn("logic 无红中胡加一码 "+this.isWGHZJYM)
- // console.warn("logic 是否只能自摸 "+this.isZNZM)
- // 七对
- // this.has7d = true;/////TL++因为奉化麻将当中本身就可以胡7对
- // 全牌
- var cards = _.clone(CARDS);
- // 添加红中红中
- if (this.hzCount > 0){
- for (let i = 0; i < this.hzCount; ++i) {
- cards[cards.length] = 51;
- }
- }
-
- this.castCount = 0;
- this.disCount = 0;
- this.lastCount = cards.length;//////设置剩余牌数为了测试海底捞月
- this.cardsPool = cards;
- this.cardsyl = _.clone(cards);
- //////以下变量全是TL++
- this.gameKindTL = gameKindTL || 1;////平搓还是冲刺 = 1代表平搓 = 2代表冲刺
- this.playerAllCount = playerAllCount || 4;////游戏人数 = 2表示2人局 = 3表示3人局 = 4表示4人局
- this.setCardFilerIndex = 0
- this.baiDaCard = 51;/////TL++,拿到百搭牌
- this.baiDaList = [0,0,0];/////TL++,拿到百搭牌数组
- this.sbyBDList = []//////得到某人手中的百搭牌数组
-
- this.chuPaiCountTL = 0//////TL++,记录出牌的个数,为了判断天胡和地胡
- this.moPaiCountTL = 0//////TL++,记录出牌的个数,为了判断天胡和地胡
- this.lastMoPaiChairID = 0//////TL++,最后一个摸牌玩家的id
-
- this.addThisIsHu = 0//////TL++,胡牌判断时加上这张能不能胡
- this.isSeleCatcedCard = false//////判断能否胡牌的那张牌是自己抓的还是别人打出来的
- this.currChairIDTL = 0/////当前判断胡的chairID,用于得到当前玩家的胡牌情况
- this.isLaGang = false;//////TL++,是否刚刚被拉杠用于判断是否被拉杠胡
- this.isGuoHuList = [[false,0],[false,0],[false,0],[false,0],]/////TL++,各个玩家在本轮是否点击了过胡和点击过牌时的台数
- this.setCardFileName = '';/////设置手牌的文件名
- this.cardGroupIndex = 0;////要设置的牌型种类
-
- this.isZHYZ = false;/////是不是最后1张
- this.isMZWF = [0,1,2,3];/////是不是满足位风
- // console.warn("ppppppppppp 长度 "+cards.length+" cards "+cards);
- };
- Logic.setHCfileNameList =[/////全部设置牌型的文件名
- "setHandCard_tianhu",
- ]
- // 导出常量
- Logic.CARDS = CARDS;
- Logic.STYLE = STYLE;
- Logic.CHAIR_COUNT = CHAIR_COUNT;
- Logic.CARDS_COUNT = CARDS_COUNT;
- // 导出类
- module.exports = Logic;
- // 原型对象
- var proto = Logic.prototype;
- /////TL++为了得到百搭牌数组用于判断是否需要补花和手牌中百搭牌个数
- proto.setBDList = function () {
- this.baiDaList = [this.baiDaCard,this.baiDaCard,this.baiDaCard]/////TL++,拿到百搭牌
- };
- ///////TL++在table类中出牌函数中调用,为了判断天胡和地胡
- proto.chuPaiTL = function () {
- // console.warn("111c天胡判断不正确",this.chuPaiCountTL);
- this.chuPaiCountTL += 1//////这个其实并不是真实的出牌个数,因为这个方法的调用在判断吃碰杠胡之前调用的
- }
- ///////TL++在table类中出牌函数中调用,为了判断天胡和地胡
- proto.moPaiTL = function () {
- // console.warn("111c天胡判断不正确",this.chuPaiCountTL);
- this.moPaiCountTL += 1//////TL++,记录出牌的个数,为了判断天胡和地胡 += 1
- }
-
- ///////TL++重置默认数据,在每局游戏开始的洗牌函数中调用
- proto.resetDataOnGameStart = function () {
-
- this.chuPaiCountTL = 0//////TL++出牌个数
- this.moPaiCountTL = 0//////TL++,记录摸牌的个数,为了判断天胡和地胡
- this.lastMoPaiChairID = 0//////TL++,最后一个摸牌玩家的id
- this.addThisIsHu = 0//////TL++,胡牌判断时加上这张能不能胡
- this.isSeleCatcedCard = false//////判断能否胡牌的那张牌是自己抓的还是别人打出来的
- this.isLaGang = false;//////TL++,是否刚刚被拉杠用于判断是否被拉杠胡
- this.isGuoHuList = [[false,0],[false,0],[false,0],[false,0],]/////TL++,各个玩家在本轮是否点击了过胡和点击过牌时的台数
- this.isZHYZ = false;/////是不是最后1张
- }
- // 重新洗牌
- proto.shuffle = function () {
- this.castCount = 0;
- this.disCount = 0;
- this.cardsPool = _.clone(this.cardsyl);
- this.lastCount = this.cardsPool.length;
- this.cardsPool = _.shuffle(this.cardsPool);////随机打乱一个数组
- this.cardsPool = _.shuffle(this.cardsPool);////洗第二次牌
- // this.cardsPool = _.shuffle(this.cardsPool);////洗第三次牌
- };
- // 填充数组
- proto.fillDeep = function (array, o, isMore) {
- for (let i = 0; i < array.length; ++i) {
- if (!isMore) {
- array[i] = _.clone(o);
- } else {
- array[i] = _.cloneDeep(o);/////深度拷贝,就是重新分配内存空间,浅拷贝则是两个变量共用一个内存对象
- }
- }
- return array;
- };
- //////TL++ 深复制一个object类型的数据
- proto.deepCloneTL = function (obj){
- let objClone = Array.isArray(obj)?[]:{};
- if(obj && typeof obj==="object"){
- for(let key in obj){
- if(obj.hasOwnProperty(key)){
- //判断ojb子元素是否为对象,如果是,递归复制
- if(obj[key]&& typeof obj[key] ==="object"){
- objClone[key] = this.deepCloneTL(obj[key]);
- }else{
- //如果不是,简单复制
- objClone[key] = obj[key];
- }
- }
- }
- }
- return objClone;
- };
- // 获取类型
- proto.getType = function (card) {
- return Math.floor(card / 10);
- };
- // 获取牌值
- proto.getValue = function (card) {
- return card % 10;
- };
- // 手牌排序
- proto.sort = function (handCards) {
- return _.sortBy(handCards);///降序排序
- };
- // 删除手牌 /////TL++参数isBuHua表示是否因为补花而造成的删除牌
- proto.remove = function (handCards, cards) {
- if (typeof (cards) == 'number') {
- if (cards == handCards[handCards.length - 1]) {
- return (handCards.pop(), true);
- } else {
- let pos = handCards.indexOf(cards);
- if (pos == -1) return false;
- return (handCards.splice(pos, 1), true);
- }
- }
- var length = cards.length;
- if (length > 1 && cards[0] == cards[length - 1]) {
- if (cards[0] == handCards[handCards.length - 1]) {
- handCards.pop();
- length -= 1;
- }
- let pos = handCards.indexOf(cards[0]);
- if (pos == -1) return false;
- handCards.splice(pos, length);
- } else {
- for (let i = 0; i < length; ++i) {
- let pos = handCards.indexOf(cards[i]);
- if (pos == -1) return false;
- handCards.splice(pos, 1);
- }
- }
- return true;
- };
- // 调整手牌
- proto.adjust = function (handCards) {
- var length = handCards.length;
- if (length < 2) return false;
- if (handCards[length - 1] < handCards[length - 2]) {
- let moCard = handCards.pop();
- let pos = _.findIndex(handCards, (i) => (i >= moCard));
- if (pos == -1) handCards.push(moCard);
- else handCards.splice(pos, 0, moCard);
- }
- return true;
- };
- // 投骰子
- proto.dice = function () {
- return _.random(1, 6);
- };
- // 剩余牌数
- proto.leaveCount = function () {
-
- return this.lastCount;
- };
- //////TL++,人工设置测试牌型
- proto.setTestSendCardsTL = function () {
- this.setCardFileName = '';
- let fileName = "setHandCard_tianhu"
- if(!fileName) return;/////文件名字不存在
- // console.warn("设置手牌的文件名",fileName);
- this.setCardFileName = fileName
- var SetHandCardTL = require('./setcard/' + fileName);
- if(!SetHandCardTL) return;
- //////TL++,设置手牌的文件
- this.setHandCardTL = new SetHandCardTL();
-
- ////console.error("洗牌之后的牌",this.cardsPool);
- let ccc = this.setHandCardTL.getSCFP(this.cardGroupIndex)
- if(ccc){//////已经设置的手牌发完了就随机发牌
- this.cardsPool = ccc/////设置手牌的地方 设置牌
- this.cardGroupIndex += 1; ////此句是否存在代表是否只发某一种牌型
- // SetHandCardTL.cardGroupIndex += 1; ////此句是否存在代表是否只发某一种牌型
- // if(SetHandCardTL.cardGroupIndex == 1) SetHandCardTL.cardGroupIndex = 0
- }
- else{
- this.setCardFilerIndex += 1;
- this.cardGroupIndex = 0;
- // SetHandCardTL.cardGroupIndex = 0;
- if(Logic.setCardFilerIndex < Logic.setHCfileNameList.length) this.setTestSendCardsTL()
- }
- }
- // 初始手牌
- proto.handCards = function (chBanker,_PJHF,_over,recordid,_ctime) {
- this.resetDataOnGameStart()//////TL++
- this.shuffle();
- // if(this.hzCount == 8) {
- // // this.cardsPool = [21,51,33,33,15,26,24,29,26,35,14,29,17,11,19,14,13,38,29,35,23,51,17,51,27,19,33,28,22,21,17,51,21,13,38,34,39,39,38,34,26,14,36,33,37,39,19,27,17,37,12,24,28,31,32,22,11,23,12,15,25,29,34,36,16,36,18,12,21,11,32,13,11,22,19,38,24,15,35,32,16,27,39,37,31,18,51,28,16,51,25,27,32,16,51,14,31,18,51,35,15,26,23,28,22,34,12,36,31,25,23,37,13,25,18,24]
- this.setTestSendCardsTL()///////设置手牌的地方,设置发牌 不需要设置的时候注释掉这个方法就可以了
- this.lastCount = this.cardsPool.length;//////设置剩余牌数设置剩余牌数,测试完这句要删掉
- // }
- let dqjs = _over + 1;
- _PJHF.writexpJson(this.deepCloneTL(this.cardsPool),dqjs,recordid,_ctime);
-
- //// 下面这个是随机发牌但是起手发lzgs张癞子的逻辑
- // let lzgs = 6//癞子个数
- // let djg = 0;
- // for (let i = 0; i < this.cardsPool.length; i++) {
- // if(this.cardsPool[i] == 51){
- // let xx = this.cardsPool[djg]
- // this.cardsPool[djg] = 51;
- // this.cardsPool[i] = xx;
- // djg++
- // if(djg >= lzgs){
- // break
- // }
- // }
- // }
- /////TL++设置百搭牌数组
- this.setBDList()
- var result = [];
- var castCount = 0;
- for (let i = 0; i < this.playerAllCount; ++i) {
- let cardCount = CARDS_COUNT;
- if (i == chBanker) cardCount += 1;
- let cards = this.cardsPool.slice(castCount, castCount + cardCount);
- castCount += cardCount;
- result.push({ cards: this.sort(cards) });
- }
- this.castCount += castCount
- this.lastCount -= castCount;
- // this.lastCount -= this.disCountTL;////因为翻出来的百搭牌不能被摸走
- // console.error("发的手牌",result);
- return result;
- };
- // 是否无牌
- proto.isNoCards = function () {
- return this.lastCount <= 0;
- };
- // 摸牌函数
- proto.moCard = function (isgang) {
- // console.error("摸排摸排---------",isgang,this.disCountTL,this.lastCount);
- var card = 0;
- if (this.lastCount > 0) {
- card = this.cardsPool[this.castCount++];
- this.lastCount -= 1;
- }
- return { card: card };
- };
- // 是否将牌
- proto.isJang = function (lcard, rcard) {
- return lcard == rcard;
- };
- // 可否碰牌
- proto.isPeng = function (handCards, card) {
- if(card == 51) return false;
- for (let i = 0; i < handCards.length - 1; ++i) {
- if (handCards[i] == card && handCards[i + 1] == card) {
- return true;
- }
- }
- return false;
- };
- // 碰牌 TL++参数chirID为了判断圈风和位风
- proto.peng = function (chirID,handCards, card) {
- if (this.isPeng(handCards, card)) {
- return { style: STYLE.PENG, cards: [card, card, card], disc: [card] };
- }
- };
- // 吃牌,1-@**左吃, 2-*@*中吃, 3-@**右吃
- proto.chi = function (handCards, card, type) {
- var chis = this.chiAnalyze(handCards, card, type);
- if (chis[0]) {
- let res = { style: STYLE.CHI, type: type, disc: [card] };
- if (type == 1) {
- res.cards = [card, card + 1, card + 2];
- if (this.getValue(card) < 7) {
- res.disc.push(card + 3);
- }
- } else if (type == 2) {
- res.cards = [card - 1, card, card + 1];
- } else {
- res.cards = [card - 2, card - 1, card];
- if (this.getValue(card) > 3) {
- res.disc.push(card - 3);
- }
- }
- return res;
- }
- };
- // 杠牌,1-普通杠, 2-暗杠, 3-自摸明杠 TL++参数chirID为了判断圈风和位风
- proto.gang = function (chirID,handCards, card, type) {
- // 结果
- var res = null;
- // 明杠
- if (type == 1) {
- let gang = this.gangAnalyze(handCards, card);
- if (gang) {
- res = { style: STYLE.GANG, cards: [card, card, card] };
- }
- }
- // 暗杠
- else if (type == 2) {
- let anGang = this.anGangAnalyze(handCards, card);
- if (anGang[0]) {
- res = { style: STYLE.ANGANG, cards: [card, card, card] };
- }
- }
- return res;
- };
- // 自摸明杠,1-普通杠, 2-暗杠, 3-自摸明杠 TL++参数chirID为了判断圈风和位风
- proto.zmGang = function (chirID,handCards, huCards, card) {
- var zmGang = this.zmGangAnalyze(handCards, huCards, card);
- if (zmGang[0]) {
- return { style: STYLE.ZMGANG, cards: [card, card, card] };
- }
- };
- // 吃牌分析,1-@**左吃, 2-*@*中吃, 3-@**右吃, type可以不传
- proto.chiAnalyze = function (handCards, card, type) {
- // 结果集合
- var result = [];
- // 排除风字
- if (handCards.length < 2 || card > 40) return result;
- // 查找句子
- var length = handCards.length;
- for (let i = 0; i < length; ++i) {
- // 牌面值
- let value = this.getValue(card);
- // @**左吃,吃类型(可以不指定)
- if (!type || type == 1) {
- if (value < 8 && i < length - 1) {
- if (handCards[i] == card + 1 && handCards[i + 1] == card + 2) {
- result.push({ type: 1, card: card });
- }
- }
- }
- // *@*中吃,吃类型(可以不指定)
- if (!type || type == 2) {
- if (value > 1 && value < 9 && i < length - 1) {
- if (handCards[i] == card - 1 && handCards[i + 1] != card - 1) {
- for (let j = i + 1; j < i + 5 && j < length; ++j) {
- if (handCards[j] == card + 1) {
- result.push({ type: 2, card: card });
- break;
- }
- }
- }
- }
- }
- // **@右吃,吃类型(可以不指定)
- if (!type || type == 3) {
- if (value > 2 && i < length - 1) {
- if (handCards[i] == card - 2 && handCards[i + 1] == card - 1) {
- result.push({ type: 3, card: card });
- }
- }
- }
- }
- return result;
- };
- // 普通杠分析,1-普通杠, 2-暗杠, 3-自摸明杠
- proto.gangAnalyze = function (handCards, card) {
- // 结果对象
- var result = null;
- if(card == 51 || this.lastCount <= 0) return result;//红中不能碰杠
- var length = handCards.length;
- if (length < 3) return result;
- // 查找同牌
- for (let i = 0; i < length - 2; ++i) {
- if (handCards[i] == card && handCards[i + 1] == card && handCards[i + 2] == card) {
- result = { type: 1, card: card };
- break;
- }
- }
- return result;
- };
- // 暗杠分析,1-普通杠, 2-暗杠, 3-自摸明杠, card可以不传
- proto.anGangAnalyze = function (handCards, card) {
- // 结果对象
- var result = [];
- if(this.lastCount <= 0) return result;//红中不能碰杠
- var length = handCards.length;
- if (length < 4) return result;
- // 查找同牌
- var moCard = handCards[length - 1];
- for (let i = 0; i < length - 3; ++i) {
- // 指定杠牌,可以不指定
- if (card && handCards[i] != card) continue;
- // 判定是否刻子
- if (handCards[i] == handCards[i + 1] && handCards[i] == handCards[i + 2]) {
- // 手上有杠牌
- if (handCards[i] == handCards[i + 3]) {
- if(handCards[i] != 51){
- result.push({ type: 2, card: handCards[i] });
- }
- }
- // 刚摸到杠牌
- else if (handCards[i] == moCard) {
- if(handCards[i] != 51){
- result.push({ type: 2, card: moCard });
- }
- }
- }
- }
- return result;
- };
- // 自摸杠分析,1-普通杠, 2-暗杠, 3-自摸明杠, card可以不传
- proto.zmGangAnalyze = function (handCards, huCards, card) {
- // 返回结果
- var result = [];
- if(card == 51 || this.lastCount <= 0) return result;//红中不能碰杠
- // 遍历句子
- for (let i = 0; i < huCards.length; ++i) {
- if (huCards[i].style != STYLE.PENG) {
- continue;
- }
- let _card = huCards[i].cards[0];
- if (card && _card != card) continue;
- let pos = handCards.indexOf(_card);
- if (pos != -1) {
- result.push({ type: 3, card: _card });
- if (card) break;
- }
- }
- return result;
- };
- // 分析牌型
- proto.parseBlock = function (card1, card2, card3) {
- // 刻子
- if (card1 && card1 == card2 && card1 == card3) {
- return { style: STYLE.KE, cards: [card1, card2, card3] };
- }
- // 顺子(排除风字)
- var cards = this.sort([card1, card2, card3]);
- if (cards[2] < 40) {
- if (cards[2] == cards[1] + 1 && cards[1] == cards[0] + 1) {
- return { style: STYLE.SUN, cards: cards };
- }
- }
- };
- // TL++,得到手牌中百搭牌的个数
- proto.getBDCount = function (cards) {
- ////TL++,整个for循环判断手牌中的百搭牌个数
- let baiDaCount = 0
- for (let i = 0; i < cards.length; ++i) {
- if(cards[i] == this.baiDaCard) baiDaCount = baiDaCount + 1
- }
- return baiDaCount
- }
- // TL++,得到手牌中百搭牌的shuzu数组
- proto.getBDListZZ = function (cards) {
- this.sbyBDList = []//////重置某人手牌中的百搭牌数组
- ////TL++,整个for循环判断手牌中的百搭牌个数
- let baiDaCount = 0
- let baiDali = []
- for (let i = 0; i < cards.length; ++i) {
- if(cards[i] == this.baiDaCard){
- baiDali[baiDaCount] = cards[i]
- baiDaCount = baiDaCount + 1
- }
- }
- return baiDali
- }
- // TL++,得到手牌中百搭牌的index数组
- proto.getBDIndexList = function (cards) {
- ////TL++,整个for循环判断手牌中的百搭牌个数
- let baiDali = []
- for (let i = 0; i < cards.length; ++i) {
- let cardTL = cards[i];
- if(this.baiDaList[0] && cardTL == this.baiDaList[0]) baiDali[baiDali.length] = i;
- else if(this.baiDaList[1] && cardTL == this.baiDaList[1]) baiDali[baiDali.length] = i;
- else if(this.baiDaList[2] && cardTL == this.baiDaList[2]) baiDali[baiDali.length] = i;
- }
- return baiDali
- }
- // TL++,得到手牌中百搭牌的index,用于删除手牌中的百搭牌
- proto.getBDIndex = function (cards) {
- ////TL++,整个for循环判断手牌中的百搭牌个数
- let baiDali = []
- for (let i = 0; i < cards.length; ++i) {
- let cardTL = cards[i];
- if(this.sbyBDList[0] && cardTL == this.sbyBDList[0]) baiDali[baiDali.length] = i;
- if(this.sbyBDList[1] && cardTL == this.sbyBDList[1]) baiDali[baiDali.length] = i;
- if(this.sbyBDList[2] && cardTL == this.sbyBDList[2]) baiDali[baiDali.length] = i;
- }
- return baiDali
- }
- // TL++,得到默认手牌中百搭牌当的数组 cards: 手牌去除百搭之后的牌
- proto.getBDMakeList = function (cards,isNeedAllZi) {
- if(cards.length == 0){
- ////手上就剩百搭牌的时候 需要把所有牌都当一遍
- let reslist = [
- 11, 12, 13, 14, 15, 16, 17, 18, 19, // 筒
- 21, 22, 23, 24, 25, 26, 27, 28, 29, // 万
- 31, 32, 33, 34, 35, 36, 37, 38, 39, // 条
- ]
- return reslist;
- }
- ////TL++,整个for循环按照手牌情况确定百搭牌当的范围
- let makeList = this.deepCloneTL(cards)
- for (let i = 0; i < cards.length; ++i) {
- let cardTL = cards[i];
- let type = this.getType(cardTL);
- let vale = this.getValue(cardTL);
- if(type < 4){
- if(vale == 1){
- let makeValue = cardTL + 1;
- if(makeList.indexOf(makeValue) == -1) makeList[makeList.length] = makeValue;
- let makeValue2 = cardTL + 2;
- if(makeList.indexOf(makeValue2) == -1) makeList[makeList.length] = makeValue2;
- }
- else if(vale == 9){
- let makeValue = cardTL - 1;
- if(makeList.indexOf(makeValue) == -1) makeList[makeList.length] = makeValue;
- let makeValue2 = cardTL - 2;
- if(makeList.indexOf(makeValue2) == -1) makeList[makeList.length] = makeValue2;
- }
- else if(vale == 2){
- let makeValue = cardTL - 1;
- if(makeList.indexOf(makeValue) == -1) makeList[makeList.length] = makeValue;
- let makeValue2 = cardTL + 1;
- if(makeList.indexOf(makeValue2) == -1) makeList[makeList.length] = makeValue2;
- let makeValue3 = cardTL + 2;
- if(makeList.indexOf(makeValue3) == -1) makeList[makeList.length] = makeValue3;
- }
- else if(vale == 8){
- let makeValue = cardTL - 1;
- if(makeList.indexOf(makeValue) == -1) makeList[makeList.length] = makeValue;
- let makeValue2 = cardTL - 2;
- if(makeList.indexOf(makeValue2) == -1) makeList[makeList.length] = makeValue2;
- let makeValue3 = cardTL + 1;
- if(makeList.indexOf(makeValue3) == -1) makeList[makeList.length] = makeValue3;
- }
- else if(vale > 2 && vale < 8){
- let makeValue = cardTL - 1;
- if(makeList.indexOf(makeValue) == -1) makeList[makeList.length] = makeValue;
- let makeValue2 = cardTL + 1;
- if(makeList.indexOf(makeValue2) == -1) makeList[makeList.length] = makeValue2;
- let makeValue3 = cardTL - 2;
- if(makeList.indexOf(makeValue3) == -1) makeList[makeList.length] = makeValue3;
- let makeValue4 = cardTL + 2;
- if(makeList.indexOf(makeValue4) == -1) makeList[makeList.length] = makeValue4;
- }
- }
- }
- // let makeList2 = makeList.concat([41,42,43,44,51,52,53])/////给当的数组拼接字牌
- // var xx = [1,1,2,3,4,1,2]
- // var xx22 = _.uniq(xx)
- // console.warn("数组去重",xx,xx22);///[ 1, 1, 2, 3, 4, 1, 2 ] [ 1, 2, 3, 4 ]
- // xx[1] = 6
- // console.warn("22数组去重",xx,xx22);////[ 1, 6, 2, 3, 4, 1, 2 ] [ 1, 2, 3, 4 ]
- return _.uniq(makeList);
- }
- // 提取成句 card:手上的所有牌删除2张用来做将的牌之后剩下的牌 整理是否为刻子或者顺子
- proto._dumpFixed = function (cards, huCards) {
- // if(this.currChairIDTL == 0){
- // console.error("sscc提取成句没有百搭cards",cards);
- // console.error("sscc提取成ju没有百搭huCards",huCards);
- // }
- for (let i = 0; i < cards.length - 2; ++i) {
- let card = cards[i];
- if (card <= 0) continue;
- if (card == cards[i + 1] && card == cards[i + 2]) {
- huCards.push({ style: STYLE.KE, cards: [card, card, card] });
- cards[i] = 0; cards[i + 1] = 0; cards[i + 2] = 0;
- i += 2; continue;
- }
- if (card > 40 || this.getValue(card) > 7) continue;
- let second = -1, third = -1;
- for (let j = i + 1; j < cards.length; ++j) {
- if (cards[j] == card + 1) second = j;
- if (cards[j] == card + 2) third = j;
- if (cards[j] > card + 2) break;
- if (second != -1 && third != -1) break;
- }
- if (second != -1 && third != -1) {
- huCards.push({ style: STYLE.SUN, cards: [card, cards[second], cards[third]] });
- cards[i] = 0; cards[second] = 0; cards[third] = 0;
- }
- }
- };
- proto._dumpFixedc = function (cards,huCards,baidaCount) {
- let spkzgs = 4 - huCards.length;//手牌可组个数
- let spkzzh = [];//手牌可组组合(1为刻2为顺)
- if(spkzgs == 1) spkzzh = [[1],[2]];
- else if(spkzgs == 2) spkzzh = [[1,1],[1,2],[2,2],[2,1]];
- else if(spkzgs == 3) spkzzh = [[1,1,1],[1,2,1],[1,1,2],[1,2,2],[2,2,2],[2,1,2],[2,2,1],[2,1,1]];
- else if(spkzgs == 4){
- spkzzh = [[1,1,1,1],[1,2,1,1],[1,1,2,1],[1,1,1,2],
- [1,2,2,1],[1,1,2,2],[1,2,1,2],[1,2,2,2],
- [2,2,2,2],[2,1,2,2],[2,2,1,2],[2,2,2,1],
- [2,1,1,2],[2,2,1,1],[2,1,2,1],[2,1,1,1]
- ]
- }
- //找到目标牌
- var getMBCard = (cscards) => {
- for (let i = 0; i < cscards.length; ++i) {
- let card = cscards[i];
- if (card <= 0) continue;
- else return card;
- }
- return -100;
- };
-
- // let mbpailist = [12,15,15,15,16,17,18,25,26,27]
- // let islog = true;
- // if(mbpailist.length == cards.length){
- // for (let i = 0; i < cards.length; ++i) {
- // if(mbpailist[i] != cards[i]) islog = false;
- // }
- // }
- // else{
- // islog = false;
- // }
- // let mbpailist2 = [15,15,16,17,18,25,26,27,28,28,28]
- // if(islog) console.warn("_dumpFixedc 提取成句 baidaCount "+baidaCount+" cards "+cards+ " indexof "+mbpailist2.indexOf(15));
- console.warn("所有的判断组合 长度 "+spkzzh.length+" spkzzh "+JSON.stringify(spkzzh) )
- let dqdpd = [0,0]//当前的判断
- for (let x = 0; x < spkzzh.length; ++x) {
- let copyCards = this.deepCloneTL(cards)
- let bdCount = baidaCount;
- let huCards22 = [];
- console.warn("当前的判断组合 "+dqdpd+" spkzzh[x] "+spkzzh[x]+" x "+x);
- // if(islog && x == 5) console.warn("当前的判断组合 "+dqdpd+" spkzzh[x] "+spkzzh[x]+" x "+x);
- for (let y = 0; y < spkzzh[x].length; ++y) {
- let ckORcs = spkzzh[x][y]//成刻或成顺(1为刻2为顺)
- // if(islog && x == 5) console.warn("当前的判断 "+dqdpd+" ckORcs "+ckORcs);
- if(ckORcs == 1){
- let mbCard = getMBCard(copyCards);//目标card(mbCard这次应该成刻)
- if(mbCard > 0){
- let index1 = copyCards.indexOf(mbCard);
- if(index1 != -1) copyCards[index1] = 0;
- else console.error("这里不正常,都没有目标牌");
- let cj = [mbCard];//成句
- let index2 = copyCards.indexOf(mbCard);
- if(index2 != -1){
- cj[cj.length] = mbCard;
- copyCards[index2] = 0;
- }
- else {
- if(bdCount > 0){
- cj[cj.length] = 51;
- bdCount -= 1;
- }
-
- }
- let index3 = copyCards.indexOf(mbCard);
- if(index3 != -1){
- cj[cj.length] = mbCard;
- copyCards[index3] = 0;
- }
- else {
- if(bdCount > 0){
- cj[cj.length] = 51;
- bdCount -= 1;
- }
-
- }
- if(cj.length == 3){
- huCards22.push({ style: STYLE.KE, cards: cj });
- }
- else{
- //mbCard不能成刻,说明spkzzh[x]这种组合是不行的,剩下的就不用判断了
- console.warn("mbCard不能成刻,说明spkzzh[x]这种组合是不行的,剩下的就不用判断了");
- break;
- }
- }
- else{
- //手牌全部都判断过了
- if(bdCount >= 3){
- huCards22.push({ style: STYLE.KE, cards: [51, 51, 51] });
- bdCount -= 3;
- }
- //因为手里最多8张百搭,最多可以有6张百搭做成2个百搭刻,所以需要两次if
- if(bdCount >= 3){
- huCards22.push({ style: STYLE.KE, cards: [51, 51, 51] });
- bdCount -= 3;
- }
- break;
- }
- }
- else if(ckORcs == 2){
- let mbCard = getMBCard(copyCards);//目标card(mbCard这次应该成刻)
- // if(islog && x == 5) console.warn("mbCard "+mbCard+" copyCards "+copyCards);
- if (mbCard < 40){
- if(mbCard > 0){
- let index1 = copyCards.indexOf(mbCard);
- if(index1 != -1) copyCards[index1] = 0;
- else console.error("这里不正常,都没有目标牌");
- let cj = [mbCard];//成句
- if(this.getValue(mbCard) <= 7){
- let index2 = copyCards.indexOf(mbCard+1);
- if(index2 != -1){
- cj[cj.length] = copyCards[index2];
- copyCards[index2] = 0;
- }
- else {
- if(bdCount > 0){
- cj[cj.length] = 51;
- bdCount -= 1;
- }
-
- }
- let index3 = copyCards.indexOf(mbCard+2);
- if(index3 != -1){
- cj[cj.length] = copyCards[index3];
- copyCards[index3] = 0;
- }
- else {
- if(bdCount > 0){
- cj[cj.length] = 51;
- bdCount -= 1;
- }
-
- }
- }
- else if(this.getValue(mbCard) == 8){
- let index2 = copyCards.indexOf(mbCard+1);
- if(index2 != -1){
- cj[cj.length] = copyCards[index2];
- copyCards[index2] = 0;
- }
- else {
- if(bdCount > 0){
- cj[cj.length] = 51;
- bdCount -= 1;
- }
-
- }
- if(bdCount > 0){
- cj[cj.length] = 51;
- bdCount -= 1;
- }
- }
- else if(this.getValue(mbCard) == 9){
- if(bdCount > 1){
- cj[cj.length] = 51;
- cj[cj.length] = 51;
- bdCount -= 2;
- }
- }
- if(cj.length == 3){
- huCards22.push({ style: STYLE.SUN, cards: cj });
- }
- else{
- //mbCard不能成顺,说明spkzzh[x]这种组合是不行的,剩下的就不用判断了
- break;
- }
- }
- else{
- //手牌全部都判断过了
- if(bdCount >= 3){
- huCards22.push({ style: STYLE.SUN, cards: [51, 51, 51] });
- bdCount -= 3;
- }
- //因为手里最多8张百搭,最多可以有6张百搭做成2个百搭刻,所以需要两次if
- if(bdCount >= 3){
- huCards22.push({ style: STYLE.SUN, cards: [51, 51, 51] });
- bdCount -= 3;
- }
- break;
- }
- }
- }
- // if(y < spkzzh[x].length-1) dqdpd=[x,y+1];
- // else dqdpd=[x+1,0];
- }
- // if(islog && x == 5) console.warn("提取成句 组合 "+" spkzzh[x] "+spkzzh[x]+" huCards22 "+JSON.stringify(huCards22) );
- if(huCards22.length + huCards.length == 4){
- //已经可以胡牌了,其他的组合就不需要判断了
- for (var i = 0; i < huCards22.length; i++) {
- huCards.push(huCards22[i]);
- }
- break;
- }
- }
- };
- //////TL++,判断一手张牌是否为百搭牌
- proto.judgeACardISBD = function (card) {
- return card == this.baiDaCard;
- }
- // 胡牌分析 chairID(TL++这个参数) 手牌 加上这张判断能不能胡 手上的吃碰杠牌 是否自己摸上来的
- proto.huAnalyze = function (chairID,handCards, card, huCards, isTouch) {
- // console.error("sscc777胡牌分析card",card);
- // console.error("sscc777胡牌分析handCards",handCards);
- // console.error("sscc777胡牌分析huCards",huCards);
- // console.error("sscc777胡牌分析isTouch",isTouch);
- // this.isHanDa = false;//////TL++,是否还搭(百搭牌用作原牌型,不累计)
- this.isPaoDa = false/////TL++,当前是不是抛搭,因为是抛搭的话不能打倒胡(吃胡)
- this.isQiDui = false;//////TL++,是否7对
- let tempAllTai = 0/////临时总台数
- let tempres = {}///本函数的返回值
- this.addThisIsHu = card//////TL++,胡牌判断时加上这张能不能胡
- this.isSeleCatcedCard = isTouch//////判断能否胡牌的那张牌是自己抓的还是别人打出来的
- this.currChairIDTL = chairID/////当前判断胡的chairID,用于得到当前玩家的花牌情况
- this.dangAfterBDListTL = [];/////7月18日+的
- // console.warn("胡牌分析 isGuoHuList ",this.isGuoHuList," chairID ",chairID," isTouch ",isTouch);
- if(this.isGuoHuList[chairID][0]){
- // console.warn("此人点过胡了 ",chairID," isTouch ",(!isTouch));
- if(!isTouch){
- // console.warn("不是此人摸牌 ",chairID,isTouch);
- return false;
- }
- }
- let baiDaCount22 = 0
- let bdIndexlist = []
- if (!isTouch){
- baiDaCount22 = this.getBDCount(handCards)
- this.sbyBDList = this.getBDListZZ(handCards)
- handCards = handCards.concat(card);/////不是自己抓的就把这张牌拼接进手牌中
- handCards = this.sort(handCards);
- bdIndexlist = this.getBDIndexList(handCards)
- }
- else{
- handCards = this.sort(handCards);
- baiDaCount22 = this.getBDCount(handCards)
- this.sbyBDList = this.getBDListZZ(handCards)
- bdIndexlist = this.getBDIndexList(handCards)
- }
- // console.warn("判断13不搭手上百搭牌个数出错了?????",baiDaCount22,this.sbyBDList,bdIndexlist)
- handCards = this.sort(handCards);
- var huRes = { card: card, jiang: 0, huCards: [] };
- // 重设将牌
- var resetHuRes = (jiang) => {
- huRes.jiang = jiang;
- huRes.huCards = [];
- for (let huCard of huCards) huRes.huCards.push(huCard);
- };
- // 手牌不全
- var length = handCards.length;
- if (length % 3 != 2) return;
- let hucardTL = huCards//////TL++,保存碰杠牌的初始值,因为这个参数会在下面的代码中被修改掉
- if(baiDaCount22 == 4 && this.hzCount == 4){
- //选择4红中规则的时候,手里有4张红中的话可以直接胡,6红中8红中不可直接胡
- // tempres = huCards
- return huRes;
- }
-
- if(baiDaCount22 == 0){/////没有百搭的时候
- // 确定将牌
- for (let i = 0; i < length - 1; ++i) {
- if (!this.isJang(handCards[i], handCards[i + 1])) continue;
- resetHuRes(handCards[i]);////设置将牌
- let cards = handCards.slice(0, i);////手牌数组的前i个元素
- cards = cards.concat(handCards.slice(i + 2));////给数组cards拼接上手牌的第 i+2 个以后的全部数组元素 这句是将手牌删除2张将牌之后得到的牌
- this._dumpFixed(cards, huRes.huCards);
- i += 1;/////TL++,为了减少运算
- if(huRes.huCards.length >= 4){
- return huRes;
- }
- }
- }
- else{/////有百搭的时候
- let card2 = []//////用于存放手牌中将所有百搭牌去掉之后的手牌
- for (let xx = 0; xx < this.sbyBDList.length; ++xx){
- card2 = handCards.slice(0,bdIndexlist[xx] - xx)////得到数组中的前bdIndexlist[xx] 个元素
- card2 = card2.concat(handCards.slice(bdIndexlist[xx]+1 - xx))////得到数组中的最后bdIndexlist[xx] +1 个元素
- handCards = card2
- // console.error("有百搭删除掉百搭牌",handCards,card2);
- }
- // console.warn("删除百搭之后的手牌222",handCards);
- let bdzs = this.sbyBDList.length;/////百搭张数
- let copyhandCards = this.deepCloneTL(handCards)
- var huResTL = [];
- for (let huCard of huCards) huResTL.push(huCard);
- // console.warn("去掉百搭之后的手牌 copyhandCards "+copyhandCards);
- if(copyhandCards.length == 0) return huRes;
- //下面的for循环是用手牌的两张牌做将牌看能不能胡牌
- for (let i = 0; i < copyhandCards.length - 1; ++i) {
- let cards22 = this.deepCloneTL(copyhandCards)
- if (!this.isJang(cards22[i], cards22[i + 1])) continue;
-
- let huRes3 = { card: card, jiang: 0, huCards: [] };
- // 重设将牌
- huRes3.jiang = cards22[i];
- huRes3.huCards = [];
- for (let huCard of huCards) huRes3.huCards.push(huCard);
-
- let cards2 = cards22.slice(0, i);////手牌数组的前i个元素
- cards2 = cards2.concat(cards22.slice(i + 2));////给数组cards拼接上手牌的第 i+2 个以后的全部数组元素 这句是将手牌删除2张将牌之后得到的牌
-
- this._dumpFixedc(cards2, huRes3.huCards,bdzs);
- console.warn("判胡 2张手牌做将length "+huRes3.huCards.length+" jiang "+huRes3.jiang+" huRes3.huCards "+JSON.stringify(huRes3.huCards));
- if (huRes3.huCards.length >= 4){
- return huRes3;
- }
- i += 1;/////TL++,为了减少运算
- }
- //下面的for循环是用一张手牌和一张百搭牌做将牌看能不能胡牌
- let bcjp = 0;///////本次的将牌
- for (let i = 0; i < copyhandCards.length; ++i) {
- let cards22 = this.deepCloneTL(copyhandCards);
- if(cards22[i] == bcjp) continue;
-
- let huRes3 = { card: card, jiang: 0, huCards: [] };
- // 重设将牌
- huRes3.jiang = cards22[i];
- huRes3.huCards = [];
- for (let huCard of huCards) huRes3.huCards.push(huCard);
- bcjp = cards22[i]; ///////本次的将牌
-
- let cards2 = cards22.slice(0, i);////手牌数组的前i个元素
- cards2 = cards2.concat(cards22.slice(i + 1));////给数组cards拼接上手牌的第 i+2 个以后的全部数组元素 这句是将手牌删除2张将牌之后得到的牌
- console.warn("判胡 1张手牌做将length "+huRes3.huCards.length+" jiang "+huRes3.jiang+" huRes3.huCards "+JSON.stringify(huRes3.huCards));
- this._dumpFixedc(cards2, huRes3.huCards,bdzs-1);
- if (huRes3.huCards.length >= 4){
- return huRes3;
- }
- }
- }
-
-
- };
- // // TL++胡牌提示 chairID(TL++这个参数) 手牌 手上的吃碰杠牌 这个是胡牌提示里不统计台数
- proto.hutip = function (chairID,_handCards, _huCards,_allhuCards,outCards) {
- return {
- renyi:0,//////是否可胡任意牌,0表示不满足1表示满足
- kehuData:[]/////对象数组,分别表示打哪张可胡哪几张数据
- };////服务端运算量太大放到前端去计算了
- this.yscs = 0
- // console.warn("hutip777胡牌提示handCards ",chairID,_handCards,_huCards,this.yscs);
- // console.error("sscc777胡牌提示huCards",_huCards);
- let hutipRes = [];
- let handCards1 = _.clone(_handCards);
- // if(chairID == 1) console.warn("sscc777胡牌提示handCards1 ",chairID,_handCards);
- let huCards = _.clone(_huCards);
- let allhuCards = _.clone(_allhuCards);////用统计胡牌提示的剩余牌
- let baiDaCount22 = this.getBDCount(_handCards);
- let dangPaiList = this.getBDMakeList(handCards1);
-
-
- if(baiDaCount22 == 4 && this.hzCount == 4){
- //选择4红中规则的时候,手里有4张红中的话可以直接胡,6红中8红中不可直接胡
- let kehuData2 = {
- renyi:1,//////是否可胡任意牌,0表示不满足1表示满足
- kehuData:[]/////对象数组,分别表示打哪张可胡哪几张数据
- };
- return kehuData2;
- }
- if(baiDaCount22 < this.hzCount && this.hzCount > 0 && _handCards.indexOf(this.baiDaCard) == -1 && this.baiDaCard < 60){
- dangPaiList[dangPaiList.length] = this.baiDaCard;
- }
- // if(chairID == 1) console.warn("hutip777胡牌提示 dangPaiList ",dangPaiList.length,dangPaiList);
- let kdcdp = 0;////可打出的牌 就是打出这个牌之后可以胡
- let dczhkhdp = [];////打出kdcdp之后可以胡的牌
- let yjpdgdsp = 0;////已经判断过的手牌 为了减少运算量判断过的手牌就不再判断了
- // let yjpdgdzh = [];////已经判断过的组合 把28换成26 和 把26换成28 的结果是一样的所以可以剔除以减少运算
- for (var i = 0; i < handCards1.length; i++) {
- if(this.judgeACardISBD(handCards1[i])) continue;
- kdcdp = handCards1[i];////可打出的牌
- dczhkhdp = [];
- if(handCards1[i] == yjpdgdsp) continue;////已经判断过的手牌 为了减少运算量判断过的手牌就不再判断了
- yjpdgdsp = handCards1[i];////已经判断过的手牌 为了减少运算量判断过的手牌就不再判断了
-
- var huResTL = [];
- for (let huCard of huCards) huResTL.push(huCard);
- let copyhandCards = this.deepCloneTL(_handCards)
- for (let x = 0; x < copyhandCards.length; ++x) {
- if(this.judgeACardISBD(copyhandCards[x])){
- copyhandCards[x] = 0;////剔除手里的百搭去判断抛搭
- }
- }
- copyhandCards[i] = 0;///剔除手里的百搭和打出那张之后剩下的手牌去判断抛搭
- let copyhandCardsqbd = _.compact(_.clone(copyhandCards));
- copyhandCardsqbd = this.sort(copyhandCardsqbd);
- // let ispd = this.hutipJudgePAODA(baiDaCount22,copyhandCardsqbd,dangPaiList,huResTL.length,kdcdp);////打出kdcdp之后是否抛搭
- //上面是旧的算法,下面是新的算法
- let ispd = false;
- if(copyhandCardsqbd.length == 0){
- ispd = true;//手上全是百搭肯定抛搭了
- }
- else{
- if(baiDaCount22 > 0){
- ispd = this.hutipJudgePAODA2(baiDaCount22-1,copyhandCardsqbd,huResTL,kdcdp);////打出kdcdp之后是否抛搭
- }
- }
- // console.warn("打出kdcdp之后是否抛搭 ",kdcdp,ispd,this.yscs);
- if(ispd){
- ////打出kdcdp之后可以抛搭了
- let data = {
- "canTing": kdcdp,////表示打出这张牌之后可以听牌
- "youjin": 1,////打出这张牌之后是不是游金(抛搭)这个在象山麻将里面没有用
- "tpxq": dczhkhdp
- }
- hutipRes[hutipRes.length] = data;
- }
- else{
- ////打出kdcdp之后不能抛搭
- for (var k = 0; k < dangPaiList.length; k++) {
- this.yscs++;
- let handCards = _.clone(handCards1);
- // console.error("222sscc777胡牌提示huCards",i,handCards[i] , dangPaiList[k],handCards);
- handCards[i] = dangPaiList[k];
-
- handCards = this.sort(handCards);
- // 手牌不全
- var length = handCards.length;
- if (length % 3 != 2) return;
- // console.warn("pandau 0ceccewcde -------开始调用 hutip33");
- let huRes22 = this.hutip33(chairID,handCards, dangPaiList[k], huCards,false);
- if (huRes22) {
- // console.warn("胡牌提示 打出 "+kdcdp+" 如果摸到 "+dangPaiList[k]+" 可以胡");
- ////打出kdcdp如果摸到dangPaiList[k]可以胡
- let syzs = this.getACardSYZS(dangPaiList[k],_handCards,allhuCards,outCards);
- // console.warn("111????????????????????????????????",dangPaiList[k],syzs);
- dczhkhdp[dczhkhdp.length] = [dangPaiList[k],-1,syzs];////[可胡的牌,剩余张数]
- }
- }
- // console.warn("222????????????????????????????????",dczhkhdp.length);
- if(dczhkhdp.length > 0){
- ////至此表示打出handCards[i]之后可以听牌
- let data = {
- "canTing": kdcdp,////表示打出这张牌之后可以听牌
- "youjin": 0,////打出这张牌之后是不是游金(抛搭)这个在象山麻将里面没有用
- "tpxq": dczhkhdp
- }
- hutipRes[hutipRes.length] = data;
- }
- }
- }
- // console.warn("333????????????????????????????????",hutipRes);
- // console.warn("222sscc777胡牌提示handCards ",chairID,_handCards,_huCards,this.yscs);
- let kehuData3 = {
- renyi:0,//////是否可胡任意牌,0表示不满足1表示满足
- kehuData:hutipRes/////对象数组,分别表示打哪张可胡哪几张数据
- };
- return kehuData3;
- // return hutipRes;
- };
- ////TL++得到一张牌的剩余张数 用于胡牌提示提示该张的剩余张数
- proto.getACardSYZS = function (card,_handCards,allhuCards,outCards) {
- ////下面这段是适合胡牌提示里用的剩余牌数统计
- let yjcxdzs = 0;////该牌已经出现的张数
- for (var i = 0; i < _handCards.length; i++) {
- if(card == _handCards[i]) yjcxdzs++;////该牌已经出现在自己手牌里的张数
- }
- // console.warn("111得到一张牌的剩余张数 手牌张数",yjcxdzs,_handCards);
- for (var i = 0; i < allhuCards.length; i++) {
- if(allhuCards[i].length == 0) continue;////该玩家没有碰杠牌
- // console.warn("222得到一张牌的剩余张数 碰杠杠牌",card,yjcxdzs,i,JSON.stringify(_.clone(allhuCards[i])));
- for (var k = 0; k < allhuCards[i].length; k++) {
- let pgp = allhuCards[i][k].cards;
- if(!pgp) continue;
- for (var j = 0; j < pgp.length; j++) {
- if(card == pgp[j]) yjcxdzs++;////该牌已经出现在自己手牌里的张数
- }
- }
- }
- for (var i = 0; i < outCards.length; i++) {
- if(outCards[i].length == 0) continue;////该玩家没有碰杠牌
- // console.warn("2得到一张牌的剩余张数 打出去的牌",card,yjcxdzs,i,JSON.stringify(_.clone(outCards[i])));
- for (var k = 0; k < outCards[i].length; k++) {
- if(card == outCards[i][k]) yjcxdzs++;////该牌已经出现在所有打出去牌里的张数;
- }
- }
- let zs = 4
- if(card == 51) zs = this.hzCount;
- // if(this.judgeACardISBD(card)) zs = 3;
- let syzs = zs - yjcxdzs;////剩余张数 = 总张数 - 已经出现的张数
- // console.warn("333得到一张牌的剩余张数",card,syzs);
- return syzs;
- };
- //////TL++,胡牌提示判断抛搭
- proto.hutipJudgePAODA2 = function (_baidacount,_hd,_huCards,_addThisIsHu) {
- // console.warn("胡牌提示判断抛搭 _baidacount "+_baidacount+" _hd.length "+_hd.length +" _hd "+_hd);
- let cards2 = this.deepCloneTL(_hd);
-
- let huRes3 = { card: 0, jiang: 0, huCards: [] };
- huRes3.huCards = [];
- for (let huCard of _huCards) huRes3.huCards.push(huCard);
- this._dumpFixedc(cards2, huRes3.huCards,_baidacount);
- // console.warn("胡牌提示 判断判断抛搭 length "+huRes3.huCards.length+" huRes3.huCards "+ JSON.stringify(huRes3.huCards));
- if (huRes3.huCards.length >= 4){
- // console.warn("胡牌提示 判断判断抛搭 可以抛搭222 length "+huRes3.huCards.length+" huRes3.huCards "+ JSON.stringify(huRes3.huCards));
- return true;
- }
- // console.warn("不能抛搭");
- return false;
- }
- // 胡牌分析 chairID(TL++这个参数) 手牌 加上这张判断能不能胡 手上的吃碰杠牌 是否自己摸上来的
- proto.hutip33 = function (chairID,handCards, card, huCards, isTouch) {
- // console.error("sscc777胡牌分析card",card);
- // console.error("sscc777胡牌分析handCards",handCards);
- // console.error("sscc777胡牌分析huCards",huCards);
- // console.error("sscc777胡牌分析isTouch",isTouch);
- let tempres = {}///本函数的返回值
- this.addThisIsHu = card//////TL++,胡牌判断时加上这张能不能胡
- this.isSeleCatcedCard = isTouch//////判断能否胡牌的那张牌是自己抓的还是别人打出来的
- this.currChairIDTL = chairID/////当前判断胡的chairID,用于得到当前玩家的花牌情况
- this.dangAfterBDListTL = [];/////7月18日+的
-
- let baiDaCount22 = 0
- let bdIndexlist = []
-
- handCards = this.sort(handCards);
- baiDaCount22 = this.getBDCount(handCards)
- this.sbyBDList = this.getBDListZZ(handCards)
- bdIndexlist = this.getBDIndexList(handCards)
- // console.warn("判断13不搭手上百搭牌个数出错了?????",baiDaCount22,this.sbyBDList,bdIndexlist)
- // 手牌不全
- var length = handCards.length;
- // console.warn("胡牌提示 length "+length+" baiDaCount22 "+baiDaCount22);
- if (length % 3 != 2) return;
- if(baiDaCount22 == 0){/////没有百搭的时候
- var huRes = { card: card, jiang: 0, huCards: [] };
- // 重设将牌
- var resetHuRes = (jiang) => {
- huRes.jiang = jiang;
- huRes.huCards = [];
- for (let huCard of huCards) huRes.huCards.push(huCard);
- };
- // let hucardTL = huCards//////TL++,保存碰杠牌的初始值,因为这个参数会在下面的代码中被修改掉
- // 确定将牌
- for (let i = 0; i < length - 1; ++i) {
- if (!this.isJang(handCards[i], handCards[i + 1])) continue;
- resetHuRes(handCards[i]);////设置将牌
- let cards = handCards.slice(0, i);////手牌数组的前i个元素
- cards = cards.concat(handCards.slice(i + 2));////给数组cards拼接上手牌的第 i+2 个以后的全部数组元素 这句是将手牌删除2张将牌之后得到的牌
- this._dumpFixed(cards, huRes.huCards);
- i += 1;/////TL++,为了减少运算
- // let tempres22 = this.outHures(huRes,handCards,hucardTL);
- if(huRes.huCards.length >= 4){
- return true;
- }
- }
- }
- else{/////有百搭的时候
- let card2 = []//////用于存放手牌中将所有百搭牌去掉之后的手牌
- for (let xx = 0; xx < this.sbyBDList.length; ++xx){
- card2 = handCards.slice(0,bdIndexlist[xx] - xx)////得到数组中的前bdIndexlist[xx] 个元素
- card2 = card2.concat(handCards.slice(bdIndexlist[xx]+1 - xx))////得到数组中的最后bdIndexlist[xx] +1 个元素
- handCards = card2
- // console.error("有百搭删除掉百搭牌",handCards,card2);
- }
- // console.warn("胡牌提示 删除百搭之后的手牌222",handCards);
- let bdzs = this.sbyBDList.length;/////百搭张数
- let copyhandCards = this.deepCloneTL(handCards)
-
- // console.warn("去掉百搭之后的手牌 copyhandCards "+copyhandCards);
- if(copyhandCards.length == 0) return true;
- //下面的for循环是用手牌的两张牌做将牌看能不能胡牌
- for (let i = 0; i < copyhandCards.length - 1; ++i) {
- let cards22 = this.deepCloneTL(copyhandCards)
- if (!this.isJang(cards22[i], cards22[i + 1])) continue;
-
- let huRes3 = { card: card, jiang: 0, huCards: [] };
- // 重设将牌
- huRes3.jiang = cards22[i];
- huRes3.huCards = [];
- for (let huCard of huCards) huRes3.huCards.push(huCard);
-
- let cards2 = cards22.slice(0, i);////手牌数组的前i个元素
- cards2 = cards2.concat(cards22.slice(i + 2));////给数组cards拼接上手牌的第 i+2 个以后的全部数组元素 这句是将手牌删除2张将牌之后得到的牌
-
- this._dumpFixedc(cards2, huRes3.huCards,bdzs);
- if (huRes3.huCards.length >= 4){
- // console.warn("胡牌提示 判断结果222 length "+huRes3.huCards.length+" huRes3.huCards "+ JSON.stringify(huRes3.huCards));
- return true;
- }
- i += 1;/////TL++,为了减少运算
- }
- //下面的for循环是用一张手牌和一张百搭牌做将牌看能不能胡牌
- let bcjp = 0;///////本次的将牌
- for (let i = 0; i < copyhandCards.length; ++i) {
- let cards22 = this.deepCloneTL(copyhandCards);
- if(cards22[i] == bcjp) continue;
- let huRes3 = { card: card, jiang: 0, huCards: [] };
- // 重设将牌
- huRes3.jiang = cards22[i];
- huRes3.huCards = [];
- for (let huCard of huCards) huRes3.huCards.push(huCard);
- bcjp = cards22[i]; ///////本次的将牌
-
- let cards2 = cards22.slice(0, i);////手牌数组的前i个元素
- cards2 = cards2.concat(cards22.slice(i + 1));////给数组cards拼接上手牌的第 i+2 个以后的全部数组元素 这句是将手牌删除2张将牌之后得到的牌
- this._dumpFixedc(cards2, huRes3.huCards,bdzs-1);
- // console.warn("胡牌提示 判断结果233 length "+huRes3.huCards.length+" huRes3.huCards "+ JSON.stringify(huRes3.huCards));
- if (huRes3.huCards.length >= 4){
- return true;
- }
- }
- }
- return false;
-
- };
- // 获得奖码列表和计算奖码分数函数
- proto.getJiangmaInfo = function (isMZJYM) {
- // console.warn("获得奖码列表函数 奖码类型:-1:不奖码,1:159奖码,2:摸几奖几,3:一码全中 "+this.jiangmaType)
- let jiangmaList = []
- let jmzs = 0;//奖码张数
- if(this.jiangmaType == 2){
- //摸几奖几
- jmzs = this.getValue(this.addThisIsHu);//胡的那张牌的牌值
- if(this.addThisIsHu == 51) jmzs = 10;
- }
- else{
- //159奖码 一码全中
- jmzs = this.jiangmaCount;
- if(isMZJYM ){
- //满足无红中加1码
- jmzs++;
- }
- }
- if(this.isLaGang){
- // console.warn("现在 是 拉杠胡了");
- if(!this.isQGHJM){
- //没有选择抢杠胡奖码
- jmzs = 0;
- // console.warn("现在 是 拉杠胡了 选则了抢杠胡不奖码 现在不奖码");
- }
- }
- else{
- // console.warn("现在 不是 拉杠胡了");
- }
- let castC1 = this.castCount;//已经消耗的
- let lastC1 = this.lastCount;
- for (var i = 0; i < jmzs; i++) {
- let card = 0;
- if (lastC1 > 0) {
- card = this.cardsPool[castC1++];
- lastC1 -= 1;
- }
- if(card > 0) jiangmaList[i] = card;
- else break;
- }
- // console.warn("获得奖码列表函数 奖码列表 ",jiangmaList," 长度 ",jiangmaList.length," addThisIsHu ",this.addThisIsHu)
-
- //下面是计算奖码分数
- let mafen = 0;
- if(this.jiangmaType == 1 || this.jiangmaType == 2){
- //159奖码 摸几奖几
- let count = 0
- for (var i = 0; i < jiangmaList.length; i++) {
- let pz = this.getValue(jiangmaList[i]);//牌值
- if (pz == 1 || pz == 5 || pz == 9 || jiangmaList[i] == 51 ){
- count++
- }
- }
- mafen = 2 * count;
- }
- else if(this.jiangmaType == 3){
- //一码全中
- let count = this.getValue(jiangmaList[0]);
- if(jiangmaList[0] == 51) count = 10;
- mafen = count;
- }
- // console.warn("获得奖码分数 mafen ",mafen)
- return { jiangmaList:jiangmaList,mafen:mafen}
- };
|