502 lines
16 KiB
JavaScript
502 lines
16 KiB
JavaScript
/*================= 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;
|
||
}
|
||
} |