| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456 |
- '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));
- let dqdpd = [0,0]//当前的判断
- for (let x = 0; x < spkzzh.length; ++x) {
- let copyCards = this.deepCloneTL(cards)
- let bdCount = baidaCount;
- let huCards22 = [];
- // 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]这种组合是不行的,剩下的就不用判断了
- 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}
- };
|