簡體   English   中英

存放二十一點手牌的最佳方法?

[英]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'。

將卡存儲為整數:

  • 1 =王牌
  • 2 = 2
  • 3 = 3
  • ...
  • 9 = 9
  • 10 = 10
  • 11 =傑克
  • 12 =女王
  • 13 =國王

出於顯示目的,使用轉換函數將整數轉換為它們的名稱:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM