'use strict'; var quick = require('quick-pomelo'); var P = quick.Promise; var _ = require('lodash'); var C = require('../../../../share/constant'); var Handler = function (app) { this.app = app; }; module.exports = function (app) { return new Handler(app); }; var proto = Handler.prototype; // 删除手牌 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); } } // console.warn("删除手牌"); var length = cards.length; for (let i = 0; i < length; ++i) { let pos = handCards.indexOf(cards[i]); if (pos == -1) return false; } 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.groupCards = function (_Cards) { let Cards = _.cloneDeep(_Cards); let CardsCopy = _.cloneDeep(_Cards); // console.error("判断桌子是否存在 "); // let Cards = [101,102,102,102,103,106,106,106,107,108,201,202,202,203,203,205,205,206,206,207,208] // let CardsCopy = [101,102,102,102,103,106,106,106,107,108,201,202,202,203,203,205,205,206,206,207,208] // // // let group1 = _.groupBy(Cards, function (n) { return n % 100 }) // // //// group1 = {"1":[101,201],"2":[102,102,102,202,202],"3":[103,203,203],"5":[205,205],"6":[106,106,106,206,206],"7":[107,207],"8":[108,208]} // // // let map1 = _.map(Object.keys(group1), function (n) { return Number(n) }); // // //// map1 = [1,2,3,5,6,7,8] // let group2 = _.groupBy(Cards, function (n) { return n}) // console.error("group2 = ",group2); // // // // group2 = {"101":[101],"102":[102,102,102],"103":[103],"106":[106,106,106],"107":[107],"108":[108], // // // // "201":[201],"202":[202,202],"203":[203,203],"205":[205,205],"206":[206,206],"207":[207],"208":[208]} // // let map2 = _.map(Object.keys(group2), function (n) { return Number(n) }); // // // map2 [101,102,103,106,107,108,201,202,203,205,206,207,208] // // console.error("group2 = ",JSON.stringify(group2)," map2 ",JSON.stringify(map2)); // // let order2 = _.sortBy((group2, function (n) { return n.length}) // // console.error("group2 = ",group2," order2 ",order2); // var values2 = _.values(group2); // // values2 = [[101],[102,102,102],[103],[106,106,106],[107],[108],[201],[202,202],[203,203],[205,205],[206,206],[207],[208]] // console.error(" values2 ",values2,JSON.stringify(values2)); // var sortVal = _.sortBy(values2, function (n) { return n.length }).reverse(); // //sortVal = [[106,106,106],[102,102,102],[206,206],[205,205],[203,203],[202,202],[208],[207],[201],[108],[107],[103],[101]] // console.error(" sortVal ",sortVal,JSON.stringify(sortVal)); let dspzs = [[201,202,203],[202,207,210]];//大顺的牌值列表 let xspzs = [[201,202,203],[202,207,210]];//小顺的牌值列表 let res = []; let gc = _.groupBy(Cards, function (n) { return n}) let vc = _.values(gc); var sortVal = _.sortBy(vc, function (n) { return n.length }).reverse(); // console.error(" sortVal ",sortVal); // console.error(" Cards111 ",JSON.stringify(Cards)); let tikeList = [];//手牌中的提刻列表 let dashunList = [];//手牌中的大顺列表 let xiaoshunList = [];//手牌中的小顺列表 let duiziList = [];//手牌中的对子列表 let danpaiList = [];//手牌中的单牌列表 for (var i = 0; i < sortVal.length; i++) { if(sortVal[i].length >= 3){ tikeList.push(sortVal[i]); let issccg = this.remove(Cards,sortVal[i]);//从手牌中剔除可组成大顺的牌 if(!issccg){//是否删除成功,不成功说明手牌中没有,据此可知代码出错了 console.error("牌出错了111 ",JSON.stringify(Cards)); return []; } // console.error(" Cards222 ",JSON.stringify(Cards)); } } for (var j = 0; j < dspzs.length; j++) { for (var i = 0; i < 2; i++) {//手牌中剔除刻子之后最多2个大顺 let issccg = this.remove(Cards,dspzs[j]);//从手牌中剔除可组成大顺的牌 // if(issccg) console.error(" Cards222 ",JSON.stringify(Cards)); if(issccg) dashunList.push(dspzs[j]) else break; } } for (var j = 0; j < xspzs.length; j++) { for (var i = 0; i < 2; i++) {//手牌中剔除刻子之后最多2个小顺 let issccg = this.remove(Cards,xspzs[j]);//从手牌中剔除可组成小顺的牌 // if(issccg) console.error(" Cards333 ",JSON.stringify(Cards)); if(issccg) xiaoshunList.push(dspzs[j]) else break; } } let gc2 = _.groupBy(Cards, function (n) { return n}) let vc2 = _.values(gc2); for (var i = 0; i < vc2.length; i++) { if(vc2[i].length == 1) danpaiList = danpaiList.concat(vc2[i]); else if(vc2[i].length == 2) duiziList.push(vc2[i]); else { console.error("牌出错了222 ",JSON.stringify(CardsCopy)); return []; } } danpaiList = _.chunk(danpaiList, 3); // console.warn("手牌中的提刻列表 ",tikeList);// // console.warn("手牌中的大顺列表 ",dashunList);// // console.warn("手牌中的小顺列表 ",xiaoshunList);// // console.warn("手牌中的对子列表 ",duiziList);// // console.warn("手牌中的单牌列表 ",danpaiList);// res = res.concat(tikeList);// res = res.concat(dashunList);// res = res.concat(xiaoshunList);// res = res.concat(duiziList);// res = res.concat(danpaiList);// // console.error(" res ",res); let zlzh = [];//整理之后的牌 for (var i = 0; i < res.length; i++) { zlzh = zlzh.concat(res[i]); } zlzh = _.sortBy(zlzh);///降序排序 let lygdys = _.difference(zlzh,CardsCopy);////另一个队员的人数 let lygdys2 = _.difference(CardsCopy,zlzh);////另一个队员的人数 if(lygdys.length > 0 || lygdys2.length > 0 || zlzh.length != CardsCopy.length){ console.error("111==============================这把派出错了 =======",zlzh); console.error("222==============================这把派出错了 =======",CardsCopy); return []; } return res; // console.error("111==============================这把派没问题 =======",zlzh); }; // 判断桌子是否存在 proto.isTableExist = P.coroutine(function* (msg, session, next) { // let fptj = []; // for (var i = 0; i < 15; i++) { // fptj[i] = 0; // } // console.warn("下面是调试发牌算法"); // let cscs = 1//测试次数 // for (var i = 0; i < cscs; i++) { // let pc = [ // 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, //一到十 // 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, // 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, // 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, // 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, //壹到拾 // 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, // 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, // 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, // ]; // pc = _.shuffle(pc);////随机打乱一个数组 // pc = _.shuffle(pc);////洗第二次牌 // let hc = _.take(pc,20); // hc = [101,103,103,104,104,104,105,106,107,107,110,201,201,202,202,204,205,207,207,209,210] // let tzzh = this.groupCards(hc); // fptj[tzzh.length]++; // } // let cxcs = 0;//出现次数 // for (var i = 0; i < fptj.length; i++) { // if(fptj[i] > 0) console.warn("分为 "+i+" 组出现的次数为 "+fptj[i]); // cxcs+=fptj[i]; // } // if(cxcs != cscs) console.error("次数对不上 ") // console.warn("XXXXXXXXXXXXXX000"); if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } if (!msg.tableId) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } var reload = parseInt(msg.reload) || 0;//ts++重入 1为重入 return this.app.controllers.paohuzi.isTableExistAsync(session.uid, String(msg.tableId),reload).nodeify(next); }); // 加入桌子 proto.joinTable = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } if (!msg.tableId) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } return this.app.controllers.paohuzi.joinTableAsync(session.uid, String(msg.tableId)).nodeify(next); }); //////TL++创建或者加入桌子,用于玩家通过战绩分享进来之后 proto.creatOrjoinTable = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } if (!msg.upId) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } if (!msg.other) { if(msg.other != 0){ return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } } var round = parseInt(msg.round); var type = parseInt(msg.type) || 0; if(!type){ return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } var kind = parseInt(msg.kind) || 1;////游戏类型 = 1代表全名堂 = 2代表大小子 = 3表示土跑胡 if(kind != 1 && kind != 2 && kind != 3){ return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR });/////既不是平搓也不是冲刺 } var playercount = parseInt(msg.playercount) || 3;////游戏人数 = 2表示2人局 = 3表示3人局 = 4表示4人局 var other = parseInt(msg.other) || 1000000;////是个7位数字,百分位至十万分位表示可选十分位表示充囤情况,个位表示封顶情况 if (other < 1000000 || other > 1200000) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } var upId = msg.upId;////TL++主动创建房间的话此值为"",通过战绩分享自动创建的房间此变量有值 // console.warn("创建房间的22other",other,msg.other); if(round != 10 && round != 16 && round != 8){//////游戏局数不合法 return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } if(playercount != 2 && playercount != 3){//////游戏人数不合法 return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } var agentId=msg.agentId || "";//数据库中agenter(推广员)数据表的主键(_id) // console.warn("创建或者加入桌子 agentId "+agentId+" session.uid "+session.uid); return this.app.controllers.paohuzi.creatOrjoinTableAsync(session.uid, round,type, kind,playercount,upId,other,agentId).nodeify(next); // return this.app.controllers.paohuzi.creatOrjoinTableAsync(session.uid, msg).nodeify(next); }); // 创建桌子 proto.createTable = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } if (!msg.other) { if(msg.other != 0){ return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } } var round = parseInt(msg.round); var type = parseInt(msg.type) || 0; if(!type){ return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR });/////充囤和封顶情况错误 } var gameKindTL = parseInt(msg.gameKindTL) || 1;////游戏类型 = 1代表全名堂 = 2代表大小子 = 3表示土跑胡 if(gameKindTL != 1 && gameKindTL != 2 && gameKindTL != 3){ return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR });/////既不是平搓也不是冲刺 } var playerAllCount = parseInt(msg.playerAllCount) || 3;////游戏人数 = 2表示2人局 = 3表示3人局 = 4表示4人局 var other = parseInt(msg.other) || 1000000;////是个7位数字,百分位至十万分位表示可选十分位表示充囤情况,个位表示封顶情况 if (other < 1000000 || other > 1200000) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } var upId = msg.upId || "";////TL++主动创建房间的话此值为"",通过战绩分享自动创建的房间此变量有值 // console.warn("创建房间的other",other,msg.other); if(round != 10 && round != 16 && round != 8){//////游戏局数不合法 return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } if(playerAllCount != 2 && playerAllCount != 3){//////游戏人数不合法 return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } var agentId=msg.agentId || ""; // console.warn("创建桌子, "+agentId+" session.uid "+session.uid);//数据库中agenter(推广员)数据表的主键(_id) return this.app.controllers.paohuzi.createTableAsync(session.uid, round, type,gameKindTL,playerAllCount,upId,other,agentId).nodeify(next);/////修改局数 }); // TL++,得到玩家位置 proto.sendLocation = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return this.app.controllers.paohuzi.sendLocationAsync(session.uid, msg).nodeify(next); }); // 得到玩家位置 proto.getLocation = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return this.app.controllers.paohuzi.getLocationAsync(session.uid, msg).nodeify(next); }); // 离开桌子 proto.leaveTable = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return this.app.controllers.paohuzi.leaveTableAsync(session.uid).nodeify(next); }); // 坐下 proto.seat = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } var chairId = parseInt(msg.chairId); if (!chairId && chairId != 0) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } return this.app.controllers.paohuzi.seatAsync(session.uid, chairId).nodeify(next); }); // 站起 proto.stand = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return this.app.controllers.paohuzi.standAsync(session.uid).nodeify(next); }); // 准备 proto.ready = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return this.app.controllers.paohuzi.readyGameAsync(session.uid).nodeify(next); }); // 开始 proto.startGame = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return this.app.controllers.paohuzi.startGameAsync(session.uid).nodeify(next); }); // 调整牌 proto.adjustCard = P.coroutine(function* (msg, session, next) { console.warn(" 调整牌hander ",msg); if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } var card = parseInt(msg.card); var oldIndex = msg.oldIndex; var newIndex = msg.newIndex; var isfy = parseInt(msg.isfy);//是否复原形式调整牌,若是则不需要传上面那些参数 if (!isfy){ if (!card || card < 101 || card > 210 || (card > 110 && card < 201)) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } let isArr = msg.oldIndex instanceof Array;////////判断参数是否是个数组 if (!oldIndex || !isArr || oldIndex.length != 2 || oldIndex[0] < 0 || oldIndex[1] < 0 || oldIndex[0] > 9 || oldIndex[1] > 3 ) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } isArr = msg.newIndex instanceof Array;////////判断参数是否是个数组 if (!newIndex || !isArr || newIndex.length != 2 || newIndex[0] < 0 || newIndex[1] < 0 || newIndex[0] > 9 || newIndex[1] > 3 ) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } } return this.app.controllers.paohuzi.adjustCardAsync(session.uid, isfy,card,oldIndex,newIndex).nodeify(next); }); // 出牌 proto.outCard = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } var card = parseInt(msg.card); if (!card || card < 101 || card > 210 || (card > 110 && card < 201)) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } var oldIndex = msg.oldIndex; let isArr = msg.oldIndex instanceof Array;////////判断参数是否是个数组 if (!oldIndex || !isArr || oldIndex.length != 2 || oldIndex[0] < 0 || oldIndex[1] < 0 || oldIndex[0] > 9 || oldIndex[1] > 3 ) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } return this.app.controllers.paohuzi.outCardAsync(session.uid, card,oldIndex).nodeify(next); }); // 杠牌 proto.gangCard = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } var card = parseInt(msg.card); var type = parseInt(msg.type); if (!card || !type) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } return this.app.controllers.paohuzi.gangCardAsync(session.uid, card, type).nodeify(next); }); // 碰牌 proto.pengCard = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } var card = parseInt(msg.card); if (!card) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } return this.app.controllers.paohuzi.pengCardAsync(session.uid, card).nodeify(next); }); // 吃牌 proto.eatCard = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } var card = parseInt(msg.card); var type = parseInt(msg.type); if (!card || !type) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } var bi1Type = parseInt(msg.bi1Type) || 0; var bi2Type = parseInt(msg.bi2Type) || 0; return this.app.controllers.paohuzi.eatCardAsync(session.uid, card, type, bi1Type, bi2Type).nodeify(next); }); // 胡牌 proto.succCard = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return this.app.controllers.paohuzi.succCardAsync(session.uid).nodeify(next); }); // 放弃 proto.giveUp = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return this.app.controllers.paohuzi.giveUpAsync(session.uid).nodeify(next); }); /////TL++,海底捞月 proto.haidilaoyue = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return this.app.controllers.paohuzi.haiDiLaoYue(session.uid,msg).nodeify(next); }); /////TL++,操作是否自动出牌 proto.autoOutCard = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return next(null, { code: C.FAILD, msg: "敬请期待" }); // return this.app.controllers.paohuzi.autoOutCard(session.uid).nodeify(next); }); // 聊天 proto.chat = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return this.app.controllers.paohuzi.sendMsgAsync(session.uid, msg).nodeify(next); }); // 收费聊天 proto.vchat = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } var chairId = parseInt(msg.chairId); if (!(chairId >= 0)) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } if (!msg.msg) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } return this.app.controllers.paohuzi.vsendMsgAsync(session.uid, chairId, msg.msg).nodeify(next); }); // 角色信息 proto.roleInfo = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } var chairId = parseInt(msg.chairId); if (!(chairId >= 0)) { return next(null, { code: C.FAILD, msg: C.GAME_PARAM_ERROR }); } return this.app.controllers.paohuzi.roleInfoAsync(session.uid, chairId).nodeify(next); }); // 请求结束 proto.overTable = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return this.app.controllers.paohuzi.overTableAsync(session.uid).nodeify(next); }); // 拒绝结束 proto.refuseOver = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return this.app.controllers.paohuzi.refuseOverAsync(session.uid).nodeify(next); }); // 同意结束 proto.agreeOver = P.coroutine(function* (msg, session, next) { if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } return this.app.controllers.paohuzi.agreeOverAsync(session.uid).nodeify(next); });