743 lines
27 KiB
JavaScript
743 lines
27 KiB
JavaScript
/*===================== cls_card2: 牌的基础类 ======================
|
||
扑克牌的统一定义:
|
||
1,单张牌的定义是一个长度为14的数组 [Id, Flower, Number, ArithF, ArithN, Score, Deal, Start, Play, Index, Over, Tag1, Tag2, Tag3]
|
||
第一位:Id,牌的绝对id,即数组下标,从0开始计数。
|
||
第二位:Flower,牌的物理花色,5:王 4:黑桃 3:红心 2:梅花 1:方块。
|
||
第三位:Number,牌的物理大小,1:A 2:2 ... 9:9 10:10 11:J 12:Q 13:K 53:小王 54:大王。
|
||
第四位:ArithF,牌的算法花色,区别于物理花色,用于牌型计算和比较牌的大小。
|
||
要求是大于0的整数,不能等于0或小于0,默认等于物理花色。
|
||
第五位:ArithN,牌的算法大小,区别于物理大小,用于牌型计算和比较牌的大小。
|
||
要求是大于0的整数,不能等于0或小于0,默认等于物理大小。
|
||
第六位:Score,牌的分值,如5、10、K。
|
||
第七位:Deal,发牌状态。
|
||
-2:规则去除的牌;
|
||
-1:未发的牌(底牌);
|
||
>=0:发牌发到谁手上,即座位号。
|
||
第八位:Start,开局状态,开局时牌在谁手上,与座位编号对应。
|
||
第九位:Play,出牌状态。
|
||
-2:埋的牌;
|
||
-1:未出的牌(手上的牌);
|
||
>=0:牌是第几轮出出去的,从0开始计数。
|
||
第十位:Index,本轮中的出牌顺序号,从0开始计数。
|
||
第十一位:Over,牌局结束时被谁得到,与座位编号对应。
|
||
第十二位:Tag1,扩展属性1。
|
||
第十三位:Tag2,扩展属性2。
|
||
第十四位:Tag3,扩展属性3。
|
||
2,基础牌型的统一定义:
|
||
所有基础牌型都由两个值表示:tong,同,表示一样的牌;shun,顺,表示连续的牌。
|
||
单张:tong=1,shun=1
|
||
对子:tong=2,shun=1
|
||
两连对:tong=2,shun=2
|
||
三连对:tong=2,shun=3
|
||
三个:tong=3,shun=1
|
||
飞机:tong=3,shun=2
|
||
四个:tong=4,shun=1
|
||
五连顺:tong=1,shun=5
|
||
六连顺:tong=1,shun=6
|
||
其他基础牌型以此类推
|
||
|
||
注意:
|
||
1,此牌类是基础扑克牌类、通用扑克牌类;各子游戏可以直接使用,也可以继承此基础类后下编写自己的牌类。
|
||
2,子游戏开发人员不能修改该文件。
|
||
3,访问牌的属性时要求使用Get和Set方法,不能直接通过数组下标的形式访问。
|
||
===================================================================*/
|
||
var cls_card2 = {
|
||
|
||
//新建一张牌
|
||
New: function(id){
|
||
return this.declare(id);
|
||
},
|
||
//牌的数据定义
|
||
declare: function(id){
|
||
//id转物理花色
|
||
var IdToFlower = function(cardid){
|
||
var yu = cardid % 54;
|
||
if (yu == 52 || yu == 53){
|
||
return 5;
|
||
}
|
||
return parseInt(yu / 13) + 1;
|
||
}
|
||
//id转物理数值
|
||
var IdToNumber = function(cardid){
|
||
var yu = cardid % 54;
|
||
if (yu == 52){
|
||
return 53;
|
||
}
|
||
if (yu == 53){
|
||
return 54;
|
||
}
|
||
return yu % 13 + 1;
|
||
}
|
||
|
||
var o_card = [];
|
||
o_card[0] = id;
|
||
o_card[1] = IdToFlower(id);
|
||
o_card[2] = IdToNumber(id);
|
||
o_card[3] = o_card[1];
|
||
o_card[4] = o_card[2];
|
||
o_card[5] = null;
|
||
o_card[6] = null;
|
||
o_card[7] = null;
|
||
o_card[8] = null;
|
||
o_card[9] = null;
|
||
o_card[10] = null;
|
||
o_card[11] = null;
|
||
o_card[12] = null;
|
||
o_card[13] = null;
|
||
return o_card;
|
||
},
|
||
//牌的id,整型,只读
|
||
GetId: function(o_card){
|
||
return o_card[0];
|
||
},
|
||
//牌的物理花色,整型,只读
|
||
GetFlower: function(o_card){
|
||
return o_card[1];
|
||
},
|
||
//牌的物理大小,整型,只读
|
||
GetNumber: function(o_card){
|
||
return o_card[2];
|
||
},
|
||
//牌的算法花色,整型
|
||
GetArithF: function(o_card){
|
||
return o_card[3];
|
||
},
|
||
SetArithF: function(o_card, value){
|
||
o_card[3] = value;
|
||
},
|
||
//牌的算法大小,整型
|
||
GetArithN: function(o_card){
|
||
return o_card[4];
|
||
},
|
||
SetArithN: function(o_card, value){
|
||
o_card[4] = value;
|
||
},
|
||
//牌的分值,整型
|
||
GetScore: function(o_card){
|
||
return o_card[5];
|
||
},
|
||
SetScore: function(o_card, value){
|
||
o_card[5] = value;
|
||
},
|
||
//发牌状态,整型
|
||
GetDeal: function(o_card){
|
||
return o_card[6];
|
||
},
|
||
SetDeal: function(o_card, value){
|
||
o_card[6] = value;
|
||
},
|
||
//开局状态,整型
|
||
GetStart: function(o_card){
|
||
return o_card[7];
|
||
},
|
||
SetStart: function(o_card, value){
|
||
o_card[7] = value;
|
||
},
|
||
//出牌状态,整型
|
||
GetPlay: function(o_card){
|
||
return o_card[8];
|
||
},
|
||
SetPlay: function(o_card, value){
|
||
o_card[8] = value;
|
||
},
|
||
//出牌顺序,整型
|
||
GetIndex: function(o_card){
|
||
return o_card[9];
|
||
},
|
||
SetIndex: function(o_card, value){
|
||
o_card[9] = value;
|
||
},
|
||
//结束时被谁得到,整型
|
||
GetOver: function(o_card){
|
||
return o_card[10];
|
||
},
|
||
SetOver: function(o_card, value){
|
||
o_card[10] = value;
|
||
},
|
||
//扩展属性
|
||
GetTag1: function(o_card){
|
||
return o_card[11];
|
||
},
|
||
SetTag1: function(o_card, value){
|
||
o_card[11] = value;
|
||
},
|
||
GetTag2: function(o_card){
|
||
return o_card[12];
|
||
},
|
||
SetTag2: function(o_card, value){
|
||
o_card[12] = value;
|
||
},
|
||
GetTag3: function(o_card){
|
||
return o_card[13];
|
||
},
|
||
SetTag3: function(o_card, value){
|
||
o_card[13] = value;
|
||
},
|
||
/*
|
||
以下提供几个针对牌数组的基础算法,这两个方法是基于牌的算法花色和算法大小实现的,各子游戏在调用前需要将牌的算法花色和算法大小先设置好。
|
||
|
||
设置算法花色的原则是:
|
||
1,如果对花色没要求则需要将所有牌的算法花色统一。比如斗地主中的五连顺是任何花色都可以一起连顺子的,则需要将所有牌的算法花色全部设置成0,表示都是同一花色,然后在同一花色下取顺子。
|
||
2,如果对花色有要求则需要根据实际情况区分算法花色。比如升级中的两连对是指同一花色下的两连对,则需要将算法花色设置成不同的值,表示不同算法花色之间是不能组成两连对的。
|
||
|
||
设置算法大小的原则是:算法大小即可表示是否连牌,也可表示牌的大小关系。
|
||
1,设置算法大小时要求做到数字连续则表示是连牌。比如A的物理大小是1,K的物理大小是13,1和13是不连续的,此时需要将A的算法大小设置成14,将K的算法大小设置成13,14和13是连续的,表示A和K可以连牌。再比如王牌和A是不能作为连牌出现的,则需要将王的算法大小设置成16,将A的算法大小设置成14,16和14不是连续的,表示王和A不能连牌。
|
||
2,设置算法大小时要求做到数字大小则表示是牌的大小。比如A的物理大小是1,K的物理大小是13,1比13小,但A比K大,此时需要将A的算法大小设置成14,将K的算法大小设置成13,14比13大,表示A比K大。再比如王牌比A大,则需要将王的算法大小设置成16,将A的算法大小设置成14,16大于14,表示王比A大。
|
||
*/
|
||
|
||
//根据算法花色筛选牌
|
||
FilterCardListByArithF: function(o_cardlist, ArithF){
|
||
/*参数说明
|
||
o_cardlist:需要进行筛选的牌数组
|
||
ArithF:要筛选的算法花色,默认不筛选
|
||
|
||
返回值:筛选后的牌数组*/
|
||
var result = [];
|
||
for (var i = 0; i < o_cardlist.length; i++) {
|
||
var o_card = o_cardlist[i];
|
||
var card_ArithF = this.GetArithF(o_card);
|
||
if (!ArithF || card_ArithF == ArithF) {
|
||
result.push(o_cardlist[i]);
|
||
}
|
||
}
|
||
return result;
|
||
},
|
||
|
||
//根据算法大小筛选牌
|
||
FilterCardListByArithN: function(o_cardlist, min_ArithN, max_ArithN){
|
||
/*参数说明
|
||
o_cardlist:需要进行筛选的牌数组
|
||
min_ArithN:要筛选的算法大小最小值,>=,默认不限制
|
||
max_ArithN:要筛选的算法大小最大值,<=,默认不限制
|
||
返回值:筛选后的牌数组*/
|
||
var result = [];
|
||
for (var i = 0; i < o_cardlist.length; i++) {
|
||
var o_card = o_cardlist[i];
|
||
var card_ArithN = this.GetArithN(o_card);
|
||
if ((!min_ArithN || card_ArithN >= min_ArithN) &&
|
||
(!max_ArithN || card_ArithN <= max_ArithN)) {
|
||
result.push(o_cardlist[i]);
|
||
}
|
||
}
|
||
return result;
|
||
},
|
||
|
||
//根据算法大小对牌数组进行排序(冒泡排序法)
|
||
SortCardList: function(o_cardlist, options){
|
||
/*参数说明
|
||
o_cardlist: 需要进行排序的牌数组
|
||
options : 排序选项,长度为2的数组,结构为[大小排序方向,花色排序方向]
|
||
第一位: 算法大小排序方向,0-从小到大排序 1-从大到小排序,默认为0。
|
||
第二位: 物理花色排序方向,算法大小相同时是否再按物理花色排序,默认为0。
|
||
0-根据算法大小排序方向默认选择物理花色排序方向,
|
||
options[0]=0时,物理花色默认按“方块->梅花->红心->黑桃”排序;
|
||
options[0]=1时,物理花色默认按“黑桃->红心->梅花->方块”排序。
|
||
1-不按物理花色排序,在o_cardlist中是什么顺序就什么顺序。
|
||
2-按物理花色从小到大,方块->梅花->红心->黑桃
|
||
3-按物理花色从大到小,黑桃->红心->梅花->方块
|
||
返回值: 排序后的牌数组*/
|
||
var ArithN_direct = 0; //算法大小排序方向
|
||
var Flower_direct = 0; //物理花色排序方向
|
||
if (options) {
|
||
ArithN_direct = parseInt(options[0]);
|
||
Flower_direct = parseInt(options[1]);
|
||
}
|
||
if (!Flower_direct){
|
||
if (ArithN_direct) {
|
||
//算法大小从大到小排序时,默认按“黑桃->红心->梅花->方块”排序
|
||
Flower_direct = 3;
|
||
} else {
|
||
//算法大小从小到大排序时,默认按“方块->梅花->红心->黑桃”排序
|
||
Flower_direct = 2;
|
||
}
|
||
}
|
||
|
||
//j与j+1互换位置
|
||
var doChangej = function(){
|
||
var tmp = o_cardlist[j];
|
||
o_cardlist[j] = o_cardlist[j + 1];
|
||
o_cardlist[j + 1] = tmp;
|
||
}
|
||
|
||
for (var i = 0; i < o_cardlist.length; i++){
|
||
for (var j = 0; j < o_cardlist.length - i - 1; j++){
|
||
var ArithN_j = this.GetArithN(o_cardlist[j]);
|
||
var ArithN_j1 = this.GetArithN(o_cardlist[j + 1]);
|
||
if (ArithN_direct == 0 && ArithN_j > ArithN_j1){
|
||
//从小到大排序
|
||
doChangej();
|
||
continue;
|
||
}
|
||
if (ArithN_direct == 1 && ArithN_j < ArithN_j1){
|
||
//从大到小排序
|
||
doChangej();
|
||
continue;
|
||
}
|
||
if (ArithN_j == ArithN_j1){
|
||
//算法大小相同时
|
||
if (Flower_direct == 1){
|
||
//不按物理花色排序
|
||
continue;
|
||
}
|
||
var Flower_j = this.GetFlower(o_cardlist[j]);
|
||
var Flower_j1 = this.GetFlower(o_cardlist[j + 1]);
|
||
if (Flower_direct == 2 && Flower_j > Flower_j1){
|
||
//按“方块->梅花->红心->黑桃”排序
|
||
doChangej();
|
||
continue;
|
||
}
|
||
if (Flower_direct == 3 && Flower_j < Flower_j1){
|
||
//按“黑桃->红心->梅花->方块”排序
|
||
doChangej();
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return o_cardlist;
|
||
},
|
||
|
||
//获取指定牌型(基础牌型)的各种组合(只组合,无排列)
|
||
GetCardListByCardType: function(o_cardlist, cardtype, options){
|
||
/*参数说明
|
||
o_cardlist:在这些牌中获取指定牌型,必须是经过了从小到大排序后的牌数组。
|
||
cardtype :目标牌型,长度为2的数组,结构为[同,顺]。
|
||
例如单张为[1,1],对子为[2,1],五连顺为[1,5]。
|
||
options :取牌选项,长度为4的数组,结构为[结果数量,取牌方向,拆牌标志,一次标志]
|
||
第一位:结果数量,0-获取所有可能的结果,>0要取的结果数量,默认为0。
|
||
比如,牌数组为[2,3,5,7]时,
|
||
当options[0]=0时,则取单张的结果为2,3,5,7;
|
||
当options[0]=1时,则取单张的结果为2;
|
||
当options[0]=3时,则取单张的结果为2,3,5。
|
||
第二位:取牌方向,0-从小到大取结果,1-从大到小取结果,默认为0。
|
||
第三位:拆牌标志,0-不拆牌,1-拆牌,默认为0。
|
||
比如,牌数组为[2,2,3,5,5,5,7],
|
||
当options[2]=0时,则取单张时会不取对子的牌和三张的牌,即结果为3,7;
|
||
当options[2]=1时,则取单张时会拆掉对子的牌和三张的牌,即结果为2,3,5,7。
|
||
第四位:一次标志,0-相同大小的牌只取一次,1-取所有情况,默认为0。
|
||
比如,牌数组为[红心2, 黑桃2, 方块3, 方块5, 红心5, 黑桃5, 方块7],
|
||
当options[3]=0时,则取单张的结果为:红心2, 方块3, 方块5, 方块7;
|
||
当options[3]=1时,则取单张时结果为:红心2, 黑桃2, 方块3, 方块5, 红心5, 黑桃5, 方块7。
|
||
返回值:满足牌型要求的牌组合数组。
|
||
格式如
|
||
[
|
||
[o_card, o_card, o_card, ...],
|
||
[o_card, o_card, o_card, ...],
|
||
[o_card, o_card, o_card, ...],
|
||
...
|
||
]
|
||
注意:统一用第一张牌的算法大小值表示牌型大小,比如34567是顺子,56789也是顺子,用3表示34567顺子的大小,用5表示56789顺子的大小,5大于3,表示56789的顺子比34567的顺子大*/
|
||
|
||
var cardtype_tong = parseInt(cardtype[0]); //牌型-同
|
||
var cardtype_shun = parseInt(cardtype[1]); //牌型-顺
|
||
var options_count = 0; //结果数量
|
||
var options_direct= 0; //取牌方向
|
||
var options_split = 0; //拆牌标志
|
||
var options_once = 0; //一次标志
|
||
if (options){
|
||
options_count = parseInt(options[0]);
|
||
options_direct= parseInt(options[1]);
|
||
options_split = parseInt(options[2]);
|
||
options_once = parseInt(options[3]);
|
||
}
|
||
|
||
//将牌按大小分组,即相同大小的牌归为一组。如,将[2,2,3,5,5,5,7]这样的牌数组转成[[2,2],[3],[5,5,5],[7]]
|
||
var SameGroupList = [];
|
||
var SameGroup = [];
|
||
for (var i = 0; i < o_cardlist.length; i++){
|
||
var o_card = o_cardlist[i];
|
||
if (SameGroup.length == 0){
|
||
SameGroup.push(o_card);
|
||
} else {
|
||
var card_ArithN = this.GetArithN(o_card);
|
||
var SameGroup_ArithN = this.GetArithN(SameGroup[0]);
|
||
if (card_ArithN == SameGroup_ArithN){
|
||
SameGroup.push(o_card);
|
||
} else {
|
||
SameGroupList.push(SameGroup);
|
||
SameGroup = [];
|
||
SameGroup.push(o_card);
|
||
}
|
||
}
|
||
}
|
||
if (SameGroup.length > 0){
|
||
SameGroupList.push(SameGroup);
|
||
}
|
||
|
||
//将牌分组按牌型的“同”获取各自的组合。例如,将[[2,2],[3],[5,5,5],[7]]这样的牌分组按“同”等于2转成[[[2,2]], [[方5,梅5],[方5,红5],[梅5,红5]]]
|
||
var TongGroupList = [];
|
||
for (var i = 0; i < SameGroupList.length; i++){
|
||
if (SameGroupList[i].length < cardtype_tong){
|
||
// TongGroupList.push([]);
|
||
continue;
|
||
}
|
||
if (SameGroupList[i].length == cardtype_tong){
|
||
TongGroupList.push([SameGroupList[i]]);
|
||
continue;
|
||
}
|
||
if (SameGroupList[i].length > cardtype_tong){
|
||
if (!options_split){ //不允许拆牌
|
||
// TongGroupList.push([]);
|
||
continue;
|
||
}
|
||
if (!options_once){ //同样大小的牌只取一次
|
||
TongGroupList.push([SameGroupList[i].slice(0, cardtype_tong)]);
|
||
} else {
|
||
TongGroupList.push(min_CombineInAry(SameGroupList[i], cardtype_tong));
|
||
}
|
||
}
|
||
}
|
||
|
||
//返回结果
|
||
var resultlist = [];
|
||
var ShunGroup = [];
|
||
//检查ShunGroup是否是连顺,如果是连顺则在ShunGroup取结果保存到resultlist中
|
||
var check_return_ShunGroup = function(){
|
||
var isShun = true;
|
||
for (var j = 0; j < ShunGroup.length; j++){
|
||
if (ShunGroup[j].length == 0) {
|
||
isShun = false;
|
||
break;
|
||
}
|
||
if (j > 0) {
|
||
var j1_ArithN = this.GetArithN(ShunGroup[j-1][0][0]);
|
||
var j_ArithN = this.GetArithN(ShunGroup[j][0][0]);
|
||
//相减等于1表示是顺
|
||
if (j_ArithN - j1_ArithN != 1){
|
||
isShun = false;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (!isShun){
|
||
return false;
|
||
}
|
||
var result = min_CombineByArys(ShunGroup);
|
||
for (var j = 0; j < result.length; j++) {
|
||
var temp = [];
|
||
for (var k = 0; k < result[j].length; k++) {
|
||
temp = temp.concat(result[j][k]);
|
||
}
|
||
resultlist.push(temp);
|
||
|
||
if (options_count && resultlist.length >= options_count) {
|
||
//达到了要取的结果数量
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}.bind(this);
|
||
|
||
//按牌型的“顺”获取符合要求的结果
|
||
if (!options_direct){
|
||
//从小到大取结果
|
||
for (var i = 0; i <= TongGroupList.length - cardtype_shun; i++){
|
||
ShunGroup = TongGroupList.slice(i, i + cardtype_shun);
|
||
if (check_return_ShunGroup()){
|
||
return resultlist;
|
||
}
|
||
}
|
||
} else {
|
||
//从大到小取结果
|
||
for (var i = TongGroupList.length - cardtype_shun; i >= 0; i--){
|
||
ShunGroup = TongGroupList.slice(i, i + cardtype_shun);
|
||
if (check_return_ShunGroup()){
|
||
return resultlist;
|
||
}
|
||
}
|
||
}
|
||
return resultlist;
|
||
},
|
||
GetCardListByCardTypeA: function(o_cardlist, cardtype, options, min_ArithN, max_ArithN){
|
||
/*参数说明
|
||
o_cardlist:同GetCardListByCardType中的参数说明。
|
||
cardtype :同GetCardListByCardType中的参数说明。
|
||
options :同GetCardListByCardType中的参数说明。
|
||
min_ArithN:同FilterCardListByArithN中的参数说明。
|
||
max_ArithN:同FilterCardListByArithN中的参数说明。
|
||
返回值:同GetCardListByCardType中的参数说明。*/
|
||
var cardlist = this.FilterCardListByArithN(o_cardlist, min_ArithN, max_ArithN);
|
||
return this.GetCardListByCardType(cardlist, cardtype, options);
|
||
},
|
||
GetCardListByCardTypeB: function(o_cardlist, cardtype, options, ArithF, min_ArithN, max_ArithN){
|
||
/*参数说明
|
||
o_cardlist:可以是未排序的牌数组,该函数会实现排序。
|
||
cardtype :同GetCardListByCardType中的参数说明。
|
||
options :同GetCardListByCardType中的参数说明。
|
||
ArithF :同FilterCardListByArithF中的参数说明。
|
||
min_ArithN:同FilterCardListByArithN中的参数说明。
|
||
max_ArithN:同FilterCardListByArithN中的参数说明。
|
||
返回值:同GetCardListByCardType中的参数说明。*/
|
||
var cardlist = this.FilterCardListByArithF(o_cardlist, ArithF);
|
||
this.SortCardList(cardlist);
|
||
cardlist = this.FilterCardListByArithN(cardlist, min_ArithN, max_ArithN);
|
||
return this.GetCardListByCardType(cardlist, cardtype, options);
|
||
},
|
||
|
||
//获取指定牌型(扩展牌型)的一种组合(只取一种组合)
|
||
GetCardListByExtendCardTypeA: function(o_cardlist, cardtypelist){
|
||
/*参数说明
|
||
o_cardlist :同GetCardListByCardTypeA中的参数说明。
|
||
cardtypelist:扩展牌型和取牌选项。
|
||
结构为[
|
||
[cardtype, options, min_ArithN, max_ArithN],
|
||
[cardtype, options, min_ArithN, max_ArithN],
|
||
[cardtype, options, min_ArithN, max_ArithN]
|
||
]
|
||
其中cardtype、options、min_ArithN、max_ArithN同GetCardListByCardTypeA中的参数说明。
|
||
例如3带1,cardtypelist=[
|
||
[[3,1], [1,x,x,x], min_ArithN, max_ArithN],
|
||
[[1,1], [1,x,x,x], min_ArithN, max_ArithN]
|
||
]
|
||
3带2,cardtypelist=[
|
||
[[3,1], [1,x,x,x], min_ArithN, max_ArithN],
|
||
[[1,1], [1,x,x,x], min_ArithN, max_ArithN],
|
||
[[1,1], [1,x,x,x], min_ArithN, max_ArithN]
|
||
]
|
||
3带1对,cardtypelist=[
|
||
[[3,1], [1,x,x,x], min_ArithN, max_ArithN],
|
||
[[2,1], [1,x,x,x], min_ArithN, max_ArithN]
|
||
]
|
||
注意:options中第一参数一定为1,表示只取一个结果,如果传的值不等于1,也会按等于1处理。
|
||
|
||
返回值:同GetCardListByCardTypeA中的参数说明。*/
|
||
|
||
var cardlist = o_cardlist;
|
||
var result = [];
|
||
for (var i = 0; i < cardtypelist.length; i++){
|
||
var cardtype = cardtypelist[i][0];
|
||
var options = cardtypelist[i][1];
|
||
if (options[0] != 1){
|
||
options[0] = 1;
|
||
}
|
||
var min_ArithN = cardtypelist[i][2];
|
||
var max_ArithN = cardtypelist[i][3];
|
||
var BaseCardGroup = this.GetCardListByCardTypeA(cardlist, cardtype, options, min_ArithN, max_ArithN);
|
||
if (BaseCardGroup.length == 0){
|
||
return [];
|
||
}
|
||
result = result.concat(BaseCardGroup[0]);
|
||
cardlist = min_ary_deduct(cardlist, BaseCardGroup[0]);
|
||
}
|
||
return [result];
|
||
},
|
||
|
||
//获取牌数组的最大牌型
|
||
GetMaxCardTypeByCardList: function(o_cardlist, option){
|
||
/*参数说明
|
||
o_cardlist: 必须是经过了从小到大排序后的牌数组。
|
||
option: 选项,默认为0
|
||
0-返回"同"最多的最大牌型(如果"同"相同则取"顺"最多的,如果"顺"也相同则取"值"最大的)
|
||
1-返回"顺"最多的最大牌型(如果"顺"相同则取"同"最多的,如果"同"也相同则取"值"最大的)
|
||
返回值:结构为[cardtype, cardlist]。其中,
|
||
cardtype为基础牌型,结构为[同,顺];
|
||
cardlist为满足cardtype的牌数组,牌型相同时取最大值的牌。
|
||
|
||
例如,当option=0时,
|
||
牌数组为[3,7,7,7,9,9,J,J,J,Q,Q], 返回值为[[3,1], [J,J,J]]
|
||
牌数组为[3,7,7,7,8,8,8,9,9,J,J,J,Q,Q], 返回值为[[3,2], [7,7,7,8,8,8]]
|
||
牌数组为[3,7,7,7,8,8,8,9,9,J,J,J,Q,Q,Q],返回值为[[3,2], [J,J,J,Q,Q,Q]]
|
||
当option=1时,
|
||
牌数组为[2,4,5,6,8,9,J,J,Q,Q,K], 返回值为[[1,3], [J,Q,K]]
|
||
牌数组为[2,4,4,5,5,6,6,8,9,J,J,Q,Q,K], 返回值为[[2,3], [4,4,5,5,6,6]]
|
||
牌数组为[2,4,4,5,5,6,6,8,9,J,J,Q,Q,K,K],返回值为[[3,2], [J,J,Q,Q,K,K]]*/
|
||
var result = [];
|
||
|
||
//将o_cardlist按大小分组。
|
||
//如,将[2,2,3,5,5,5,7]这样的牌数组转成[[2,2],[3],[5,5,5],[7]]
|
||
var changeto_SameGroupList = function(){
|
||
var SameGroupList = [];
|
||
var SameGroup = [];
|
||
for (var i = 0; i < o_cardlist.length; i++){
|
||
var o_card = o_cardlist[i];
|
||
if (SameGroup.length == 0){
|
||
SameGroup.push(o_card);
|
||
} else {
|
||
var card_ArithN = this.GetArithN(o_card);
|
||
var SameGroup_ArithN = this.GetArithN(SameGroup[0]);
|
||
if (card_ArithN == SameGroup_ArithN){
|
||
SameGroup.push(o_card);
|
||
} else {
|
||
SameGroupList.push(SameGroup);
|
||
SameGroup = [];
|
||
SameGroup.push(o_card);
|
||
}
|
||
}
|
||
}
|
||
if (SameGroup.length > 0){
|
||
SameGroupList.push(SameGroup);
|
||
}
|
||
return SameGroupList;
|
||
}.bind(this);
|
||
|
||
var SameGroupList = changeto_SameGroupList();
|
||
switch (option){
|
||
case 0: //取"同"最多的牌型 [A,2,2,3,4,4,5,5,7,7,8,8,9,9,J,J,Q,Q,K,K]
|
||
//检查ShunGroup是否是连顺
|
||
var check_ShunGroup_isShun = function(){
|
||
for (var j = 0; j < ShunGroup.length; j++){
|
||
if (ShunGroup[j].length == 0) {
|
||
return false;
|
||
}
|
||
if (j > 0) {
|
||
var j1_ArithN = this.GetArithN(ShunGroup[j-1][0]);
|
||
var j_ArithN = this.GetArithN(ShunGroup[j][0]);
|
||
//相减等于1表示是顺
|
||
if (j_ArithN - j1_ArithN != 1){
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}.bind(this);
|
||
|
||
result[0] = [SameGroupList[0].length, 1];
|
||
result[1] = SameGroupList[0];
|
||
for (var i = 1; i < SameGroupList.length; i++) {
|
||
if (SameGroupList[i].length > result[0][0]){
|
||
result[0] = [SameGroupList[i].length, 1];
|
||
result[1] = SameGroupList[i];
|
||
} else if (SameGroupList[i].length == result[0][0]){
|
||
var ArithN_i = this.GetArithN(SameGroupList[i][0]);
|
||
var ArithN_r = this.GetArithN(result[1][result[1].length - 1]);
|
||
if (ArithN_i - ArithN_r == 1){ //相减等于1表示是顺
|
||
result[0][1] = result[0][1] + 1;
|
||
result[1] = result[1].concat(SameGroupList[i]);
|
||
} else {
|
||
if (i + result[0][1] <= SameGroupList.length){
|
||
var ShunGroup = SameGroupList.slice(i, i + result[0][1]);
|
||
var isShun = check_ShunGroup_isShun();
|
||
if (isShun){
|
||
var check_Tong = true;
|
||
for (var j = 1; j < ShunGroup.length; j++) {
|
||
if (ShunGroup[j].length != result[0][0]){
|
||
check_Tong = false;
|
||
break;
|
||
}
|
||
}
|
||
if (check_Tong) {
|
||
result[1] = [];
|
||
for (var j = 0; j < ShunGroup.length; j++) {
|
||
result[1] = result[1].concat(ShunGroup[j]);
|
||
}
|
||
i = i + result[0][1] - 1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case 1: //取"顺"最多的牌型 [A,3,4,6,8,8,9,9,J,J,J,Q,Q,Q]
|
||
//将SameGroupList转成ShunGroupList
|
||
//如,将[[2,2],[3],[5,5,5],[6,6],[7],[9,9]]转成[[[2,2],[3]], [[5,5,5],[6,6],[7]], [[9,9]]]
|
||
var changeto_ShunGroupList = function(){
|
||
var ShunGroupList = [];
|
||
for (var i = 0; i < SameGroupList.length; i++) {
|
||
var ArithN_i = this.GetArithN(SameGroupList[i][0]);
|
||
var isFound = false;
|
||
for (var j = 0; j < ShunGroupList.length; j++) {
|
||
var ArithN_j = this.GetArithN(ShunGroupList[j][ShunGroupList[j].length - 1][0]);
|
||
if (ArithN_i - ArithN_j == 1) {
|
||
ShunGroupList[j].push(SameGroupList[i]);
|
||
isFound = true;
|
||
break;
|
||
}
|
||
}
|
||
if (!isFound){
|
||
ShunGroupList.push([SameGroupList[i]]);
|
||
}
|
||
}
|
||
return ShunGroupList;
|
||
}.bind(this);
|
||
|
||
//获取ShunGroup中最小的"同"数
|
||
var get_ShunGroup_minTong = function(){
|
||
var min_Tong = ShunGroup[0].length;
|
||
for (var j = 1; j < ShunGroup.length; j++) {
|
||
if (ShunGroup[j].length < min_Tong) {
|
||
min_Tong = ShunGroup[j].length;
|
||
}
|
||
}
|
||
return min_Tong;
|
||
}.bind(this);
|
||
|
||
//根据ShunGroup的min_Tong设置result
|
||
var set_result_byShunGroup_byMinTong = function(){
|
||
result[0] = [min_Tong, ShunGroup.length];
|
||
result[1] = [];
|
||
for (var j = 0; j < ShunGroup.length; j++) {
|
||
result[1] = result[1].concat(ShunGroup[j].slice(0, min_Tong));
|
||
}
|
||
}.bind(this);
|
||
|
||
var ShunGroupList = changeto_ShunGroupList();
|
||
//在ShunGroupList中取最长的"顺"
|
||
for (var i = 0; i < ShunGroupList.length; i++) {
|
||
var ShunGroup = ShunGroupList[i];
|
||
var min_Tong = get_ShunGroup_minTong();
|
||
if (i == 0){
|
||
set_result_byShunGroup_byMinTong();
|
||
} else {
|
||
if (ShunGroup.length > result[0][1]) {
|
||
set_result_byShunGroup_byMinTong();
|
||
} else if (ShunGroup.length == result[0][1]) {
|
||
if (min_Tong >= result[0][0]){
|
||
set_result_byShunGroup_byMinTong();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
return result;
|
||
},
|
||
GetMaxCardTypeByCardListA: function(o_cardlist){
|
||
/*参数说明 o_cardlist:可以是未排序的牌数组,该函数会实现排序。*/
|
||
this.SortCardList(o_cardlist);
|
||
return this.GetMaxCardTypeByCardList(o_cardlist);
|
||
},
|
||
|
||
//新建单张牌类
|
||
NewClass: function(){
|
||
var cls = {};
|
||
cls.New = cls_card2.New;
|
||
cls.declare = cls_card2.declare;
|
||
cls.GetId = cls_card2.GetId;
|
||
cls.GetFlower = cls_card2.GetFlower;
|
||
cls.GetNumber = cls_card2.GetNumber;
|
||
cls.GetArithF = cls_card2.GetArithF;
|
||
cls.SetArithF = cls_card2.SetArithF;
|
||
cls.GetArithN = cls_card2.GetArithN;
|
||
cls.SetArithN = cls_card2.SetArithN;
|
||
cls.GetScore = cls_card2.GetScore;
|
||
cls.SetScore = cls_card2.SetScore;
|
||
cls.GetDeal = cls_card2.GetDeal;
|
||
cls.SetDeal = cls_card2.SetDeal;
|
||
cls.GetStart = cls_card2.GetStart;
|
||
cls.SetStart = cls_card2.SetStart;
|
||
cls.GetPlay = cls_card2.GetPlay;
|
||
cls.SetPlay = cls_card2.SetPlay;
|
||
cls.GetIndex = cls_card2.GetIndex;
|
||
cls.SetIndex = cls_card2.SetIndex;
|
||
cls.GetOver = cls_card2.GetOver;
|
||
cls.SetOver = cls_card2.SetOver;
|
||
cls.GetTag1 = cls_card2.GetTag1;
|
||
cls.SetTag1 = cls_card2.SetTag1;
|
||
cls.GetTag2 = cls_card2.GetTag2;
|
||
cls.SetTag2 = cls_card2.SetTag2;
|
||
cls.GetTag3 = cls_card2.GetTag3;
|
||
cls.SetTag3 = cls_card2.SetTag3;
|
||
cls.FilterCardListByArithF = cls_card2.FilterCardListByArithF;
|
||
cls.FilterCardListByArithN = cls_card2.FilterCardListByArithN;
|
||
cls.SortCardList = cls_card2.SortCardList;
|
||
cls.GetCardListByCardType = cls_card2.GetCardListByCardType;
|
||
cls.GetCardListByCardTypeA = cls_card2.GetCardListByCardTypeA;
|
||
cls.GetCardListByCardTypeB = cls_card2.GetCardListByCardTypeB;
|
||
cls.GetCardListByExtendCardTypeA = cls_card2.GetCardListByExtendCardTypeA;
|
||
cls.GetMaxCardTypeByCardList = cls_card2.GetMaxCardTypeByCardList;
|
||
cls.GetMaxCardTypeByCardListA = cls_card2.GetMaxCardTypeByCardListA;
|
||
return cls;
|
||
}
|
||
}
|