export class CowCard{
/**
* NiuNiuCard constructor.
* @param type 牌型 //type : 1 : 黑桃 2:红桃 3:梅花 4:方块
* @param num 牌号
* @param count 牌点数 >10都作为10
*/
constructor(type, num, count) {
this.type = type;
this.num = num;
this.count = count;
}
}
//判断牛几
export class Cow{
/**
* 辅助函数,用于排序
* @param cards 卡牌的引用
*/
sortCards(cards) {
cards.sort((a, b) => {
if (a.num > b.num || (a.num == b.num && a.type < b.type)) {
return 1;
}
else {
return -1;
}
});
}
/**
* @param cards 玩家的手牌
* @param typeSelected 允许的可选牌型的数组,用于是否开启该牌型,包含数据为
* canShunDou: 能否顺斗; canKanDou: 能否坎斗
* canSameColorLineCow: 能否同花顺
* canBoomCow: 能否×××牛
* canSmallCow: 能否五小牛
* canFlowerCow: 能否五花牛
* canSiHuaNiu: 能否四花牛
* canGourdCow: 能否葫芦牛
* canSameColorCow: 能否同花牛
* canLineCow: 能否顺子牛
* @return resultArray 某一个玩家的结果数组,存放结果
* 'level': 牌的级别,按照同花顺 > 五小牛 > 五花牛 > 四花牛 > ×××牛 > 葫芦牛 > 同花
* > 顺子 > 牛牛 > 牛9-牛5 > 牛4-牛1 > 无牛进行排列
* 注意:坎斗、顺斗以及普通牛是同一级别,都看点数
* 'levelResult': 牌的级别对应的最大牌,用于同级别的判断
*
*/
getCowResult(cards, typeSelected){
let result = {level:-1,levelResult:'',douPai:[]};
//保存一个临时牌组,并按从小到大排序
this.sortCards(cards);
//获取普通牛数据
let r = this.getCowCount(cards);
this.processResult(result, r);
if(typeSelected.canShunDou){
//获取顺斗的数据
r = this.getShunDouPoint(cards);
this.processResult(result, r);
}
/*if(typeSelected.canCanDou){
//获取豹子牛数据
r = this.isLeopardCow(cards);
if(r.level==Cow.COW_LEOPARD){
this.processResult(result, r);
}
}*/
//可能出错
if(typeSelected.canFlowerCow){
//获取五花牛
r = this.isFlowerCow(cards);
if(r.level==Cow.COW_FLOWER){
this.processResult(result, r);
}
}
if(typeSelected.canLineCow){
//获取顺子牛数据
r = this.isLineCow(cards);
if(r.level==Cow.COW_LINE){
this.processResult(result, r);
}
}
if(typeSelected.canSameColorCow){
//获取同花牛
r = this.isSameColorCow(cards);
if(r.level==Cow.COW_SAME_COLOR){
this.processResult(result, r);
}
}
if(typeSelected.canGourdCow){
//获取葫芦牛
r = this.isGourdCow(cards);
if(r.level==Cow.COW_GOURD){
this.processResult(result, r);
}
}
if(typeSelected.canBoomCow){
//获取炸弹牛
r = this.isBoomCow(cards);
if(r.level==Cow.COW_BOOM){
this.processResult(result, r);
}
}
if(typeSelected.canSmallCow){
//获取五小牛
r = this.isSmallCow(cards);
if(r.level==Cow.COW_SMALL){
this.processResult(result, r);
}
}
if(typeSelected.canSameColorLineCow){
//获取同花顺
r = this.isSameColorLineCow(cards);
if(r.level==Cow.COW_SAME_COLOR_LINE){
this.processResult(result, r);
}
}
return result;
}
processResult(playerResult, newResult){
if(playerResult.level < newResult.level){
playerResult.level = newResult.level;
playerResult.levelResult = newResult.maxCard;
playerResult.douPai = newResult.douPai;
}
}
/**
* 判断牛牛点数
* @param cards 玩家的手牌
* @return array:[level:牌力,maxCard: 最大牌]
*/
getCowCount(cards){
let result = {level:-1,maxCard:'',douPai:[]};
//总点数
let cardsTotalPoint = 0;
//计算总点数
cards.forEach(card => {
cardsTotalPoint += card.count;
});
//计算余数
let lave = cardsTotalPoint % 10;
for(let i = 0; i < cards.length - 1; i++){
for(let j = i + 1; j < cards.length; j++){
if((cards[i].count + cards[j].count) % 10 == lave){
//此处是有牛,则取出斗的牌
if(i != 0 && j != 0){
result.douPai.push(cards[0]);
}
if(i != 1 && j != 1){
result.douPai.push(cards[1]);
}
if(i != 2 && j != 2) {
result.douPai.push(cards[2]);
}
if(i != 3 && j != 3){
result.douPai.push(cards[3]);
}
if(i != 4 && j != 4){
result.douPai.push(cards[4]);
}
result.level = this._getCount(lave);
result.maxCard = cards[4];
return result;
}
}
}
result.level = Cow.NONE;
result.maxCard = cards[4];
return result;
}
/*
* 辅助函数,用于处理牛1-牛9的细分结果处理
* @param lave: getNiuniuCount的余数结果
*/
_getCount(lave) {
switch (lave) {
case 0:
return Cow.COW_COW;
case 1:
return Cow.COW_1;
case 2:
return Cow.COW_2;
case 3:
return Cow.COW_3;
case 4:
return Cow.COW_4;
case 5:
return Cow.COW_5;
case 6:
return Cow.COW_6;
case 7:
return Cow.COW_7;
case 8:
return Cow.COW_8;
case 9:
return Cow.COW_9;
default:
return -1;
}
}
/**
* 判断是否为五花牛的函数
* @param cards 某一个玩家的手牌
* @return level: 牌力,maxCard: 最大牌
*/
isFlowerCow(cards){
let result = {level:-1,maxCard:'',douPai:[]};
let flag = false;
cards.some(card => {
if(card.num <= 10){
flag = true;
return true;
}
});
if(flag){
return result;
}
result.level = Cow.COW_FLOWER;
result.maxCard = cards[4];
result.douPai = cards;
return result;
}
/**
* 判断是否为同花牛的函数
* @param cards 某一个玩家的手牌
* @return result:{level:牌力,maxCard: 最大牌}
*/
isSameColorCow(cards){
let result = {level:-1,maxCard:'',douPai:[]};
let type = cards[0].type;
let flag = true;
cards.some(card => {
if(card.type != type){
flag = false;
return false;
}
});
if(flag){
result.level = Cow.COW_SAME_COLOR;
result.maxCard = cards[4];
result.douPai = cards;
}
return result;
}
/**
* 判断是否为同花顺牛的函数
* @param cards
* @return result:{level:牌力, maxCard: 同花顺的最大牌}
*/
isSameColorLineCow(cards){
let result = {level:-1,maxCard:'',douPai:[]};
let r1 = this.isSameColorCow(cards);
let r2 = this.isLineCow(cards);
if(r1.level == Cow.COW_SAME_COLOR && r2.level == Cow.COW_LINE){
result.level = Cow.COW_SAME_COLOR_LINE;
result.maxCard = cards[4];
result.douPai = cards;
}
return result;
}
/**
* 判断是否为炸弹牛的函数
* @param cards
* @return result:{level:牌力, maxCard: 同花顺的最大牌}
*/
isBoomCow(cards){
let result = {level:-1,maxCard:'',douPai:[]};
//假设牌已经按照从小到大排序
//aaaa*
if(cards[0].num == cards[3].num){
result.level = Cow.COW_BOOM;
result.maxCard = cards[0];
result.douPai = cards.slice(0,5);
}
//*aaaa
else if(cards[1].num ==cards[4].num){
result.level = Cow.COW_BOOM;
result.maxCard = cards[1];
result.douPai = cards.slice(1);
}
return result;
}
/**
* 判断是否为五小牛的函数
* @param cards
* @return result:{level:牌力, maxCard: 同花顺的最大牌}
*/
isSmallCow(cards){
let result = {level:-1,maxCard:'',douPai:[]};
let totalCount = 0;
cards.some(card => {
if(card.num > 5){
return false;
}
else{
totalCount += card.num;
}
});
if(totalCount <= 10 && totalCount > 0){
result.level= Cow.COW_SMALL;
result.maxCard = cards[4];
result.douPai=cards;
}
return result;
}
/**
* 判断是否为葫芦牌型的函数
* @param cards
* @return result:{level:牌力, maxCard: 葫芦的最大牌}
*/
isGourdCow(cards){
let result = {level:-1,maxCard:'',douPai:[]};
//aaabb
if(cards[0].num == cards[2].num){
if(cards[3].num == cards[4].num){
result.level = Cow.COW_GOURD;
result.maxCard = cards[0];
result.douPai = cards.slice(0,3);
}
}
//aabbb
if(cards[2].num == cards[4].num){
if(cards[0].num == cards[1].num){
result.level = Cow.COW_GOURD;
result.maxCard = cards[2];
result.douPai = cards.slice(2);
}
}
return result;
}
/**
* 判断是否为四花型的函数
* @param cards
* @return result:{level:牌力, maxCard: 四花的最大牌}
*/
isFourCow(cards){
let result = {level:-1,maxCard:'',douPai:[]};
let flag = true;
cards.some(card => {
if(card.num < 10){
flag = false;
return false;
}
});
if(cards[0].num == 10 && flag){
result.level = Cow.COW_FOUR;
result.maxCard = cards[4];
}
return result;
}
/**
* 判断是否为顺子牛的函数
* @param cards
* @return result:{level:牌力, maxCard: 顺子牛的最大牌}
*/
isLineCow(cards){
let result = {level:-1,maxCard:'',douPai:[]};
//abcde
let temp = cards[0].num;
let num = 0;
if(temp == 1){
//第一张为A
//a 2 3 4 5
if(cards[1].num == 2){
num++;
for(let i=2;i<5;i++){
if(cards[i].num-i == temp){
num++;
}else{
return result;
}
}
}else if(cards[1].num == 10){
num++;
for(let i=2;i<5;i++){
if(cards[i].num-i+1 == 10){
num++;
}else{
return result;
}
}
}
//10 J Q K A
}else{
for(let i=1;i<5;i++){
if(cards[i].num-i == temp){
num++;
}else{
return result;
}
}
}
if(num==4){
result.level = Cow.COW_LINE;
result.maxCard = cards[4];
result.douPai = cards;
}
return result;
}
/**
* 判断是否为豹子牛的函数
* @param cards
* @return result:{level:牌力, maxCard: 豹子牛的最大牌}
*/
isLeopardCow(cards){
let result = {level:-1,maxCard:'',douPai:[]};
//aaa**
if(cards[0].num == cards[2].num){
result.level = Cow.COW_LEOPARD;
result.maxCard = cards[4];
result.douPai = cards.slice(0,3);
}
//*aaa*
else if(cards[1].num == cards[3].num){
//count = cards[0].point + cards[4].point;
result.level = Cow.COW_LEOPARD;
result.maxCard = cards[4];
result.douPai = cards.slice(1,4);
}
//**aaa
else if(cards[2].num == cards[4].num){
result.level = Cow.COW_LEOPARD;
result.maxCard = cards[1];
result.douPai = cards.slice(2);
}
return result;
}
/**
* 获取是否为坎斗的函数
* @param cards 某一个玩家的手牌
* @return result:{level:牌力, maxCard: 坎斗的最大牌}
*/
getKanDouPoint(cards){
let result = {level:-1,maxCard:'',douPai:[]};
let count = -1;
//aaa**
if(cards[0].num == cards[2].num){
count = cards[3].count + cards[4].count;
result.maxCard = cards[4];
}
//*aaa*
else if(cards[1].num == cards[3].num){
count = cards[0].count + cards[4].count;
result.maxCard = cards[4];
}
//**aaa
else if(cards[2].num == cards[4].num){
count = cards[0].count + cards[1].count;
result.maxCard = cards[1];
}
else{
count = -1;
}
count = count % 10;
result.level = this._getCount(count);
return result;
}
/**
* 获取是否为顺斗的函数
* @param cards 某一个玩家的手牌
* @return result:{level:牌力, maxCard: 顺斗的最大牌}
*/
getShunDouPoint(cards){
let result = {level:-1,maxCard:'',douPai:[]};
//枚举所有情况产生点数的数组
let tempResults = {level:-1,maxCard:'',douPai:[]};
//第一种情况abc**
if( (cards[0].num+1 == cards[1].num) && (cards[1].num == cards[2].num - 1)){
tempResults.push({level:(cards[3].count + cards[4].count)%10,maxCard:cards[4],douPai:cards.slice(0,3)});
}
//第二种情况*abc*
if ((cards[1].num+1 == cards[2].num) && (cards[2].num == cards[3].num - 1)){
tempResults.push({level:(cards[0].count + cards[4].count)%10,maxCard:cards[4],douPai:cards.slice(1,4)});
}
//第三种情况**abc
if ((cards[2].num+1 == cards[3].num) && (cards[3].num == cards[4].num - 1)){
tempResults.push({level:(cards[0].count + cards[1].count)%10,maxCard:cards[4],douPai:cards.slice(2)});
}
//第四种情况abbc*
if (cards[0].num+2 == cards[3].num && cards[0].num + 1 == cards[1].num){
tempResults.push({level:(cards[4].count + cards[1].count)%10,maxCard:cards[4],douPai:[cards[0],cards[1],cards[3]]});
}
//第五种情况*bccd;
if(cards[1].num+2 == cards[4].num && cards[3].num + 1 == cards[4].num) {
tempResults.push({level:(cards[0].count + cards[2].count)%10,maxCard:cards[4],douPai:[cards[1],cards[2],cards[4]]});
}
//第六种情况aabbc;
if((cards[0].num+1 == cards[2].num) && (cards[2].num+1 == cards[4].num)){
tempResults.push({level:(cards[0].count + cards[2].count)%10,maxCard:cards[4],douPai:[cards[0],cards[2],cards[4]]});
}
//第七种情况abbcc
if((cards[0].num+1 == cards[2].num) && (cards[2].num+1 == cards[4].num)){
tempResults.push({level:(cards[1].count + cards[3].count)%10,maxCard:cards[4],douPai:[cards[0],cards[1],cards[3]]});
}
//第8种情况abbbc
if(cards[0].num+2 == cards[4].num && cards[0].num + 1 == cards[1].num) {
tempResults.push({level:(cards[1].count * 2)%10,maxCard:cards[4],douPai:[cards[0],cards[1],cards[4]]});
}
//有可能没有结果,直接返回
if(tempResults.length == 0){
return result;
}
//获取最大的可能性结果返回
let level = tempResults[0].level;
let maxIndex = 0;
tempResults.forEach((tempResult,index) => {
if(tempResult.level > level){
level = tempResult;
maxIndex = index;
}
});
//echo tempResult[index].level;
result.level = this._getCount(tempResults[maxIndex].level % 10 );
result.maxCard = tempResults[maxIndex].maxCard;
result.douPai = tempResults[maxIndex].douPai;
return result;
}
}
Cow.NONE = -1; //无牛
Cow.COW_1 = 1; //牛1
Cow.COW_2 = 2; //牛2
Cow.COW_3 = 3; //牛3
Cow.COW_4 = 4; //牛4
Cow.COW_5 = 5; //牛5
Cow.COW_6 = 6; //牛6
Cow.COW_7 = 7; //牛7
Cow.COW_8 = 8; //牛8
Cow.COW_9 = 9; //牛9
Cow.COW_COW = 10; //牛牛
Cow.COW_LINE = 11; //顺子牛
Cow.COW_SAME_COLOR = 12; //同花牛
Cow.COW_GOURD = 13; //葫芦牛
Cow.COW_BOOM = 14; //炸弹牛
Cow.COW_FOUR = 15; //四花牛
Cow.COW_FLOWER = 16; //5花牛
Cow.COW_SMALL = 17; //五小牛
Cow.COW_SAME_COLOR_LINE = 18; //同花顺牛
// Cow.COW_LEOPARD = 18;//豹子牛