[英]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.