/*================= cls_aset2: 小局基础类 ================= 注意: 1,此牌类是基础小局类;各子游戏需要继承此基础类后下编写自己的小局类。 2,子游戏开发人员不能修改该文件。 =========================================================*/ var cls_aset2 = { //================ 新建一小局 ================ New: function(){ //定义小局 var o_aset = this.declare(); //初始化牌列表 this.initcardlist(o_aset); //除掉不要的牌 this.deletecard(o_aset); //设置每张牌的分值 this.setcardscore(o_aset); return o_aset; }, //小局的数据定义 declare: function(){ var o_aset = {}; //玩家列表 o_aset.playerlist = []; //在此定义和存储玩家的状态,比如准备状态、叫分的分值、游戏的得分等等,格式如[[], [], ...], [{}, {}, ...], [player, player, ...] //牌列表 o_aset.cardlist = []; //格式为[[], [], [], ...],里面的每个小数组就是一张牌 //庄(位置) o_aset.zhuang = -1; //控制权(位置) o_aset.control = -1; //当前是第几轮出牌 o_aset.play = 0; //当前是本轮的第几个出牌 o_aset.index = 0; return o_aset; }, //初始化牌列表 initcardlist: function(o_aset){ //几副牌 var card_count = this.get_cardcount(); //牌类 var card_class = this.get_cardclass(); //初始化 for (var i = 1; i <= card_count; i++){ //几副牌 for (var j = 1; j <= 4; j++){ //方块、梅花、红心、黑桃四种花色 for (var k = 1; k <= 13; k++){ //A到K var id = (i - 1) * 54 + (j - 1) * 13 + k - 1; //牌的绝对id //新建一张牌 var card_object = card_class.New(id); o_aset.cardlist.push(card_object); } } //小王 var card_object = card_class.New((i - 1) * 54 + 53 - 1); o_aset.cardlist.push(card_object); //大王 var card_object = card_class.New((i - 1) * 54 + 54 - 1); o_aset.cardlist.push(card_object); } }, //几副牌 get_cardcount: function(){ return 1; }, //小局对应的牌类 get_cardclass: function(){ return cls_card2; }, //除掉不要的牌 deletecard: function(o_aset){ for (var i = 0; i < o_aset.cardlist.length; i++){ var o_card = o_aset.cardlist[i]; this.get_cardclass().SetDeal(o_card, -1); } //下面的代码是3人二七王除掉3、4的例子。类似功能需要在子游戏中重写该方法 // for (var i = 0; i < o_aset.cardlist.length; i++){ // var o_card = o_aset.cardlist[i]; // var card_number = this.get_cardclass().GetNumber(o_card); // if (card_number == 3 || card_number == 4){ // this.get_cardclass().SetDeal(o_card, -2); // } // } }, //设置每张牌的分值 setcardscore: function(o_aset){ for (var i = 0; i < o_aset.cardlist.length; i++){ var o_card = o_aset.cardlist[i]; var card_deal = this.get_cardclass().GetDeal(o_card); if (card_deal != -2){ this.get_cardclass().SetScore(o_card, 0); } } //下面的代码是设置5、10、K分值的例子。类似功能需要在子游戏中重写该方法 // for (var i = 0; i < o_aset.cardlist.length; i++){ // var o_card = o_aset.cardlist[i]; // var card_deal = this.get_cardclass().GetDeal(o_card); // if (card_deal != -2){ // var card_number = this.get_cardclass().GetNumber(o_card); // switch (card_number){ // case 5: // this.get_cardclass().SetScore(o_card, 5); // break; // case 10: // this.get_cardclass().SetScore(o_card, 10); // break; // case 13: // this.get_cardclass().SetScore(o_card, 10); // break; // } // } // } }, //===================== 发牌 ===================== DealCard: function(o_aset, o_desk){ //需要发牌的位置列表 var seatlist = this.get_dealseatlist(o_aset, o_desk); //每人需要发多少张牌 var dealcount = this.get_dealcount(o_aset, o_desk); //需要留几张底牌 var bottomcount = this.get_bottomcount(o_aset, o_desk); //注意:dealcount * seatlist + bottomcount必须等于除掉不要的牌之后的牌的总数 //发牌数组 var tmplist = []; for (var i = 0; i < seatlist.length; i++){ for (var j = 0; j < dealcount; j++){ tmplist.push(seatlist[i]); } } for (var i = 0; i < bottomcount; i++){ tmplist.push(-1); } //随机发牌 for (var i = 0; i < o_aset.cardlist.length; i++){ var o_card = o_aset.cardlist[i]; var card_deal = this.get_cardclass().GetDeal(o_card); if (card_deal != -2){ var idx = min_random(0, tmplist.length - 1); this.get_cardclass().SetDeal(o_card, tmplist[idx]); this.get_cardclass().SetStart(o_card, tmplist[idx]); this.get_cardclass().SetPlay(o_card, -1); this.get_cardclass().SetOver(o_card, tmplist[idx]); //将发牌数组的最后一位移至该位置 if (idx < tmplist.length - 1) { tmplist[idx] = tmplist[tmplist.length - 1]; }; //发牌数组长度减一 tmplist.length = tmplist.length - 1; } } }, DealCardByList: function(o_aset, o_desk){ //需要发牌的位置列表 var seatlist = this.get_dealseatlist(o_aset, o_desk); //每人需要发多少张牌 var dealcount = this.get_dealcount(o_aset, o_desk); //需要留几张底牌 var bottomcount = this.get_bottomcount(o_aset, o_desk); //注意:dealcount * seatlist + bottomcount必须等于除掉不要的牌之后的牌的总数 //发牌数组 var tmplist = []; for (var i = 0; i < seatlist.length; i++){ for (var j = 0; j < dealcount; j++){ tmplist.push(seatlist[i]); } } for (var i = 0; i < bottomcount; i++){ tmplist.push(-1); } //随机发牌 for (var i = 0; i < o_aset.cardlist.length; i++){ var o_card = o_aset.cardlist[i]; var card_deal = this.get_cardclass().GetDeal(o_card); if (card_deal != -2){ var idx = min_random(0, tmplist.length - 1); this.get_cardclass().SetDeal(o_card, tmplist[idx]); this.get_cardclass().SetStart(o_card, tmplist[idx]); this.get_cardclass().SetPlay(o_card, -1); this.get_cardclass().SetOver(o_card, tmplist[idx]); //将发牌数组的最后一位移至该位置 if (idx < tmplist.length - 1) { tmplist[idx] = tmplist[tmplist.length - 1]; }; //发牌数组长度减一 tmplist.length = tmplist.length - 1; } } }, //需要发牌的位置列表 get_dealseatlist: function(o_aset, o_desk){ var seatlist = []; for (var i = 0; i < o_desk.o_room.seatlist.length; i++){ if (o_desk.o_room.seatlist[i]){ if (o_desk.o_room.seatlist[i].gameinfo.isbet){ seatlist.push(i); } } } return seatlist; }, //每人需要发多少张牌 get_dealcount: function(o_aset, o_desk){ return 0; }, //需要留几张底牌 get_bottomcount: function(o_aset, o_desk){ return 0; }, //==================== 拿底牌 ==================== PutBottomCard: function(o_aset, seat){ var bottomcardlist = this.GetBottomCards(o_aset); for (var i = 0; i < bottomcardlist.length; i++) { var o_card = bottomcardlist[i]; this.get_cardclass().SetStart(o_card, seat); } }, //===================== 埋牌 ===================== BuryCard: function(o_aset, seat, cardidlist){ /*参数: seat:哪个位置要埋牌 cardidlist:要埋的牌的id 返回值:true表示执行成功,false表示执行失败。*/ if (this.canBuryCard(o_aset, seat, cardidlist)){ this.doBuryCard(o_aset, seat, cardidlist); return true; } else { return false; } }, get_burycardcount: function(){ return 8; }, //检查是否可埋牌 canBuryCard: function(o_aset, seat, cardidlist){ //检查控制权 if (seat != o_aset.control){ return false; } //检查埋牌数量 if (cardidlist.length != this.get_burycardcount()){ return false; } //检查要埋的牌是否在玩家手上 var inhandcardids = this.GetCardIdsInhand(o_aset, seat); return min_ary_include(inhandcardids, cardidlist); }, //埋牌 doBuryCard: function(o_aset, seat, cardidlist){ var cardlist = this.CardIdsToCards(o_aset, cardidlist); for (var i = 0; i < cardlist.length; i++) { var o_card = cardlist[i]; this.get_cardclass().SetPlay(o_card, -2); } }, //===================== 出牌 ===================== PlayCard: function(o_aset, seat, cardidlist, mode){ /*参数: seat:哪个位置要出牌 cardidlist:要出的牌的id mode:出牌模式 0-需要跟随上一家出牌 1-需要跟随第一家出牌 返回值:true表示执行成功,false表示执行失败。*/ var can = this.canPlayCard(o_aset, seat, cardidlist, mode); //检查是否可出 if (can.result){ //可出 this.doPlayCard(o_aset, seat, cardidlist); //出下去 return true; } else { //不可出 return false; } }, //检查是否可出牌 canPlayCard: function(o_aset, seat, cardidlist, mode){ var can = {}; //返回的结果 can.result = false; //是否可以出出去 can.cards = null; //牌(对象) can.cardtype = null; //牌型 can.value = null; //大小 can.flower = null; //花色 //检查控制权 if (seat != o_aset.control){ can.result = false; return can; } //检查要出的牌是否在玩家手上 var inhandcardids = this.GetCardIdsInhand(o_aset, seat); if (!min_ary_include(inhandcardids, cardidlist)){ can.result = false; return can; } return can; }, //第一个出牌时分析选中的牌是否可以出出去(主要是分析牌型) canPlayCard_first: function(o_aset, cardidlist){ var can = {}; //返回的结果 can.result = false; //是否可以出出去 can.cards = null; //牌(对象) can.cardtype = null; //牌型 can.value = null; //大小 can.flower = null; //花色 return can; }, //不是第一个出牌时分析选中的牌是否可以出出去(主要是分析牌型是否符合前面出牌的牌型) canPlayCard_second: function(o_aset, cardidlist, mode){ var can = {}; //返回的结果 can.result = false; //是否可以出出去 can.cards = null; //牌(对象) can.cardtype = null; //牌型 can.value = null; //大小 can.flower = null; //花色 return can; }, //出牌 doPlayCard: function(o_aset, seat, cardidlist){ var cardlist = this.CardIdsToCards(o_aset, cardidlist); for (var i = 0; i < cardlist.length; i++) { var o_card = cardlist[i]; this.get_cardclass().SetPlay(o_card, o_aset.play); this.get_cardclass().SetIndex(o_card, o_aset.index); } }, //=================== 可跟随的牌 =================== CanFollowCard: function(o_aset, seat, mode){ //根据第一个人或上一个人出的牌,分析seat这个位置上的人必出的牌和可出的牌 }, //==================== 小局结算 ===================== CloseAccount: function(o_aset, o_desk){ }, //================ 获取各种情况的牌 ================ //获取开局时玩家发到手上的牌 GetDealCardsBySeat: function(o_aset, seat){ return this.GetCardsByDealstate(o_aset, seat); }, GetDealCardIdsBySeat: function(o_aset, seat){ var cardlist = this.GetDealCardsBySeat(o_aset, seat); return this.CardsToCardIds(cardlist); }, //获取底牌 GetBottomCards: function(o_aset){ return this.GetCardsByDealstate(o_aset, -1); }, GetBottomCardIds: function(o_aset){ var cardlist = this.GetBottomCards(o_aset); return this.CardsToCardIds(cardlist); }, //获取玩家当前手上有的牌 GetCardsInhand: function(o_aset, seat){ var cardlist = []; for (var i = 0; i < o_aset.cardlist.length; i++){ var o_card = o_aset.cardlist[i]; var card_start = this.get_cardclass().GetStart(o_card); if (card_start == seat){ var card_play = this.get_cardclass().GetPlay(o_card); if (card_play == -1 || card_play == null){ cardlist.push(o_card); } } } return cardlist; }, GetCardIdsInhand: function(o_aset, seat){ var cardlist = this.GetCardsInhand(o_aset, seat); return this.CardsToCardIds(cardlist); }, //获取埋牌 参数:seat谁埋的牌,可以不传,默认只有一个人会埋牌 GetBuryCards: function(o_aset, seat){ return this.GetCardsByPlaystate(o_aset, -2, seat); }, GetBuryCardIds: function(o_aset, seat){ var cardlist = this.GetBuryCards(o_aset, seat); return this.CardsToCardIds(cardlist); }, //获取上一轮出牌 GetPriorPlayCard: function(o_aset, round){ }, //获取下一轮出牌 GetNextPlayCard: function(o_aset, round){ }, //================== 各种底层函数 ================== //根据发牌状态获取牌列表 GetCardsByDealstate: function(o_aset, dealstate){ var cardlist = []; for (var i = 0; i < o_aset.cardlist.length; i++){ var o_card = o_aset.cardlist[i]; var card_deal = this.get_cardclass().GetDeal(o_card); if (card_deal == dealstate){ cardlist.push(o_card); } } return cardlist; }, //根据出牌状态获取牌列表 GetCardsByPlaystate: function(o_aset, playstate, seat){ var cardlist = []; for (var i = 0; i < o_aset.cardlist.length; i++){ var o_card = o_aset.cardlist[i]; var card_play = this.get_cardclass().GetPlay(o_card); if (card_play == playstate){ if (seat != null){ var card_start = this.get_cardclass().GetStart(o_card); if (card_start == seat){ cardlist.push(o_card); } } else { cardlist.push(o_card); } } } return cardlist; }, //将牌对象列表转换成牌id列表 CardsToCardIds: function(cardlist){ var cardidlist = []; for (var i = 0; i < cardlist.length; i++){ var o_card = cardlist[i]; var card_id = this.get_cardclass().GetId(o_card); cardidlist.push(card_id); } return cardidlist; }, //将牌id列表转换成牌对象列表 CardIdsToCards: function(o_aset, cardidlist){ var cardlist = []; for (var i = 0; i < cardidlist.length; i++){ var o_card = o_aset.cardlist[cardidlist[i]]; cardlist.push(o_card); } return cardlist; }, //新建小局类 NewClass: function(){ var cls = {}; cls.New = cls_aset2.New; cls.declare = cls_aset2.declare; cls.initcardlist = cls_aset2.initcardlist; cls.get_cardcount = cls_aset2.get_cardcount; cls.get_cardclass = cls_aset2.get_cardclass; cls.deletecard = cls_aset2.deletecard; cls.setcardscore = cls_aset2.setcardscore; cls.DealCard = cls_aset2.DealCard; cls.get_dealseatlist = cls_aset2.get_dealseatlist; cls.get_dealcount = cls_aset2.get_dealcount; cls.get_bottomcount = cls_aset2.get_bottomcount; cls.PutBottomCard = cls_aset2.PutBottomCard; cls.BuryCard = cls_aset2.BuryCard; cls.get_burycardcount = cls_aset2.get_burycardcount; cls.canBuryCard = cls_aset2.canBuryCard; cls.doBuryCard = cls_aset2.doBuryCard; cls.PlayCard = cls_aset2.PlayCard; cls.canPlayCard = cls_aset2.canPlayCard; cls.canPlayCard_first = cls_aset2.canPlayCard_first; cls.canPlayCard_second = cls_aset2.canPlayCard_second; cls.doPlayCard = cls_aset2.doPlayCard; cls.CanFollowCard = cls_aset2.CanFollowCard; cls.CloseAccount = cls_aset2.CloseAccount; cls.GetDealCardsBySeat = cls_aset2.GetDealCardsBySeat; cls.GetDealCardIdsBySeat = cls_aset2.GetDealCardIdsBySeat; cls.GetBottomCards = cls_aset2.GetBottomCards; cls.GetBottomCardIds = cls_aset2.GetBottomCardIds; cls.GetCardsInhand = cls_aset2.GetCardsInhand; cls.GetCardIdsInhand = cls_aset2.GetCardIdsInhand; cls.GetBuryCards = cls_aset2.GetBuryCards; cls.GetBuryCardIds = cls_aset2.GetBuryCardIds; cls.GetPriorPlayCard = cls_aset2.GetPriorPlayCard; cls.GetNextPlayCard = cls_aset2.GetNextPlayCard; cls.GetCardsByDealstate = cls_aset2.GetCardsByDealstate; cls.GetCardsByPlaystate = cls_aset2.GetCardsByPlaystate; cls.CardsToCardIds = cls_aset2.CardsToCardIds; cls.CardIdsToCards = cls_aset2.CardIdsToCards; return cls; } }