扑克牌含义
- 扑克牌全牌只有两色,红色代表白天,黑色代表夜晚。
- 花色分4种黑红梅方代表春夏秋冬四季,每种花色13张代表一季13个星期, 共计52张牌代表全年52个星期。
- 每种花色的13张牌的牌面值(1~13)加起来是91,每季也是91天。
- J 代表武士(Jack)、Q代表王后 Quene、K代表国王 (King)、大王代表太阳、小王代表月亮。
扑克牌设计的一个中心原则是尽可能做到关于原点(图案中心)对称,即具有某种奇怪函数的特性。
- 1-9的数字牌完美的左右对称,除左上角和右下角的数值外。
- JQK 上下对称
- 大小王 不对称
- 方块牌 上下对称
使用16进制表示扑克
- 牌值数据采用16进制
- 每种花色13张
- 16进制第一位表示花色
- 16进制后两位转换为十进制表示面值点数
掩码
掩码 | 十六进制 | 十进制 | 二进制 |
---|---|---|---|
花色 | 0xF0 | 240 | 1111 0000 |
面值 | 0x0F | 15 | 0000 1111 |
花色
花色 | 数值 |
---|---|
0 | 方块 |
1 | 梅花 |
2 | 红桃 |
3 | 黑桃 |
4 | 鬼 |
方块
方块牌值 | 十六进制 | 十进制 |
---|---|---|
2 | 0x02 | 2 |
3 | 0x03 | 3 |
4 | 0x04 | 4 |
5 | 0x05 | 5 |
6 | 0x06 | 6 |
7 | 0x07 | 7 |
8 | 0x08 | 8 |
9 | 0x09 | 9 |
10 | 0x0A | 10 |
J | 0x0B | 11 |
Q | 0x0C | 12 |
K | 0x0D | 13 |
A | 0x01 | 1 |
梅花
梅花牌值 | 十六进制 | 十进制 |
---|---|---|
2 | 0x12 | 18 |
3 | 0x13 | 19 |
4 | 0x14 | 20 |
5 | 0x15 | 21 |
6 | 0x16 | 22 |
7 | 0x17 | 23 |
8 | 0x18 | 24 |
9 | 0x19 | 25 |
10 | 0x1A | 26 |
J | 0x1B | 27 |
Q | 0x1C | 28 |
K | 0x1D | 29 |
A | 0x11 | 17 |
红桃
红桃牌值 | 十六进制 | 十进制 |
---|---|---|
2 | 0x22 | 34 |
3 | 0x23 | 35 |
4 | 0x24 | 36 |
5 | 0x25 | 37 |
6 | 0x26 | 38 |
7 | 0x27 | 39 |
8 | 0x28 | 40 |
9 | 0x29 | 41 |
10 | 0x2A | 42 |
J | 0x2B | 43 |
Q | 0x2C | 44 |
K | 0x2D | 45 |
A | 0x21 | 33 |
黑桃
黑桃牌值 | 十六进制 | 十进制 |
---|---|---|
2 | 0x32 | 50 |
3 | 0x33 | 51 |
4 | 0x34 | 52 |
5 | 0x35 | 53 |
6 | 0x36 | 54 |
7 | 0x37 | 55 |
8 | 0x38 | 56 |
9 | 0x39 | 57 |
10 | 0x3A | 58 |
J | 0x3B | 59 |
Q | 0x3C | 60 |
K | 0x3D | 61 |
A | 0x31 | 49 |
鬼牌
鬼牌牌值 | 十六进制 | 十进制 |
---|---|---|
大鬼 | 0x4E | 78 |
小鬼 | 0x4F | 79 |
ES实现扑克牌的数据结构
/**扑克牌型判断逻辑 */
export default class PokerLogic{
constructor(){
//操作掩码
//花色掩码
this.mask_color = 0xF0;//1111 0000
//数值掩码
this.mask_value = 0x0F;//0000 1111
//扑克牌值数据采用16进制,每种花色13张 16进制第一位表示花色 16进制后两位转换为十进制表示点数
this.card_data = [
//0方块: 2 3 4 5 6 7 8 9 10 J Q K A
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x01,
//1梅花: 2 3 4 5 6 7 8 9 10 J Q K A
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x11,
//2红桃: 2 3 4 5 6 7 8 9 10 J Q K A
0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x21,
//3黑桃: 2 3 4 5 6 7 8 9 10 J Q K A
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x31,
//4鬼:大鬼 小鬼
0x4E, 0x4F
];
}
//获取扑克数值
getValue(number){
const data = this.getData(number);
//满足牌值定义做一个偏移
return data & this.mask_value;
}
//获取扑克花色
getColor(number){
const data = this.getData(number);
return (data & this.mask_color) / 16;
}
/**将服务器扑克数据转换为客户端的扑克数据 */
getData(number){
if(number>0 && number<=this.card_data.length){
return this.card_data[number - 1];
}
return 0;
}
/**将客户端扑克牌数据转换为服务器 */
getNumber(data){
const suit = (data & this.mask_color)/16;//花色
const rank = (data & this.mask_value);//数值
//四花色无鬼
if(suit>=0 && suit<=3){
if(rank>=1 && rank<=13){
return (suit-1)*13 + rank;
}
}else if(suit==5 && (rank==1 || rank==2)){
return (suit-1)*13 + rank;
}
return 0;
}
}
TS实现扑克牌逻辑的数据结构
/**
* 扑克牌牌型逻辑
* 客户端使用十六进制,服务端使用索引值
* */
export default class Poker{
//花色掩码 十进制 240
public MASK_SUIT:number = 0XF0;
//数值掩码 十进制 15
public MASK_RANK:number = 0X0F;
//扑克数据 十六进制
public data:number[] = [
//花色3 黑桃2~A 十进制 50 51 52 53 54 55 56 57 58 59 60 61 49
0X32,0X33,0X34,0X35,0X36,0X37,0X38,0X39,0X3A,0X3B,0X3C,0X3D,0X31,
//花色2 红桃2~A 十进制 34 35 36 37 38 39 40 41 42 43 44 45 33
0X22,0X23,0X24,0X25,0X26,0X27,0X28,0X29,0X2A,0X2B,0X2C,0X2D,0X21,
//花色1 梅花2~A 十进制 18 19 20 21 22 23 24 25 26 27 28 29 17
0X12,0X13,0X14,0X15,0X16,0X17,0X18,0X19,0X1A,0X1B,0X1C,0X1D,0X11,
//花色0 方块2~A 十进制 2 3 4 5 6 7 8 9 10 11 12 13 1
0X02,0X03,0X04,0X05,0X06,0X07,0X08,0X09,0X0A,0X0B,0X0C,0X0D,0X01,
//花色4 大小鬼 十进制 78 79
0X4E,0X4F
];
//构造器
public constructor(){}
//根据面值排序 从大到小
public sortByRank(data:number[]):void{
let self:Poker = this;
data.sort((prev, next)=>{
if(self.getRank(prev) > self.getRank(next)){
return -1;
}else if(self.getRank(prev) < self.getRank(next)){
return 1;
}else{
return 0;
}
});
}
//根据花色排序 从大到小
public sortBySuit(data:number[]):void{
let self:Poker = this;
data.sort((prev, next)=>{
if(self.getSuit(prev) > self.getSuit(next)){
return -1;
}else if(self.getSuit(prev) < self.getSuit(next)){
return 1;
}else{
return 0;
}
});
}
//根据值获取牌数据
public getItemByRank(data:number[], rank:number):number{
for(let i:number=0; i<data.length; i++){
if(this.getRank(data[i]) == rank){
return data[i];
}
}
return 0;
}
//获取数值 1~13
public getRank(index:number):number{
let val = this.getItem(index);
return val & this.MASK_RANK;
}
//获取花色 0~5
public getSuit(index:number):number{
let val = this.getItem(index);
return (val & this.MASK_SUIT) / 16;
}
//将服务器传递过来的扑克索引数据转换为客户端使用的值
public getItem(index:number):number{
if(index>0 && index<=this.data.length){
return this.data[index-1];
}
return 0;
}
//将客户端扑克面值转换为服务器所使用的索引值
public toServer(val:number):number{
//计算花色
let suit = (val & this.MASK_SUIT) / 16;//0方块 1梅花 2红桃 3黑桃 4大小鬼
//计算数值
let rank = val & this.MASK_RANK;//1到13
//花色判断
if(suit>=0 && suit<=3){
//判断面值
if(rank>=0 && rank<=13){
return (suit-1)*13 + rank;
}
}
//大小王
if(suit==5 && (rank==1 || rank==2)){
return (suit-1)*13 + rank;
}
return 0;
}
}