[英]Best way to store a BlackJack hand?
首先,我还是C语言的新手,所以请让我知道您可以提出的任何建议(尤其是关于处理数组的建议)。
我想将BlackJack手存储在C中。我得出的结论是,手或卡片必须是字符串,因为卡片可以是两个字符: A, J, Q, K
或数字: 1, 2.. 10
,其中10实际上应该是两个字符的字符串。
现在,我尝试将组成一手牌的卡片存储到这样的数组中:
char* hand;
hand[1] = "A";
hand[2] = "2";
问题是10
,它占用数组的两个索引而不是一个。 我可以解决的一种方法是,创建一个具有5个字符串的结构(BlackJack牌中的最大牌数),每张牌一个。 但是,如果由于某种原因我想拿几千张纸牌怎么办? 那么存储手的最佳方法是什么?
您可能会发现此站点很有趣。
http://www.computerpokercompetition.org/
他们举办年度AI扑克比赛。 他们的服务器是用C编写的,您可以从上述站点下载代码。
基本上,它们将卡存储为整数。 这是处理卡的最有效方法。 卡座中只有52种类型的卡。 如果有小丑的话,更多。 因此,您可以将其映射为0到51之间的整数值。它们使用以下函数来打印出一张卡,因为整数卡号不会告诉您太多。 注意,他们基于等级和套件来构建字符串。
int printCard( const uint8_t card, const int maxLen, char *string )
{
if( 3 > maxLen ) {
return -1;
}
string[ 0 ] = rankChars[ rankOfCard( card ) ];
string[ 1 ] = suitChars[ suitOfCard( card ) ];
string[ 2 ] = 0;
return 2;
}
不要将卡存储为字符串(例如"9"
),而是存储为字符(例如'9'
)。 对于值10
您可以使用替换字符,例如'T'
。 示例代码:
char hand[MAX_HAND_LEN];
int hand_len;
get_hand(hand, hand_len);
for (int i = 0; i < hand_len; i++) {
if (hand[i] == 'T') {
putchar('1');
putchar('0');
} else {
putchar(hand[i]);
}
putchar(' ');
}
putchar('\n');
这样,您既不会浪费不必要的内存(因为一张卡现在只需要一个字节的存储空间),也不会牺牲代码的简单性或可读性。
我在这里写了一篇关于这个问题的文章。 使用字符串是一个非常糟糕的主意。 整数更好,最好的使用顺序是将低序位放在一起,即使用2c,2d,2h,2s,3c,3d,...,Ks,Ac,Ad,Ah,As 。 这样,您甚至不必分开等级和西装就可以进行数学计算。 那么,手就是整数数组。 通过这种表示,我可以在数分钟内完成数十亿手操作。 我的库中用于计算二十一点手总数的函数如下所示(OJ_CARD宏扩展为整数常量,因此比较很快):
int ojb_total(const oj_cardlist_t *sp) {
int i, c, t = 0, ace = 0, soft = 0;
for (i = 0; i < sp->length; ++i) {
c = sp->cards[i];
if (c >= OJ_CARD(OJR_ACE, OJS_CLUB)) {
ace = 1;
++t;
} else if (c >= OJ_CARD(OJR_TEN, OJS_CLUB)) {
t += 10;
} else {
t += OJ_RANK(c) + 2;
}
}
if (ace && t < 12) {
t += 10;
soft = 1;
}
return soft ? -t : t;
}
这是来自通用卡片模拟库的,而且速度非常快,但是如果我真的想要二十一点模拟的弹球到墙壁的速度,却什么也没做,我根本就不会代表卡片,只需要一个“ {1,2,3,4,5,6,7,8,9,10,10,10,10}的多个副本”,然后从中进行处理。
我会说没有唯一的最佳方法。 但是, char *hand;
没有定义字符串数组; 您可以使用char *hand[5]
,而10将不接受两个索引; 或者您可以使用char hand[5]
并将10存储为单个字符,例如'0'或'T'。
将卡存储为整数:
出于显示目的,使用转换函数将整数转换为它们的名称:
string GetCardNameFromNumber(int cardNumber)
{
switch(cardNumber)
{
case 1:
return "A";
case 11:
return "J";
case 12:
return "Q";
case 13:
return "K";
default:
return cardNumber.ToString();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.