我们如何有效地迭代卡组合?

时间:2017-08-24 08:19:58

标签: c algorithm bitmap bit-manipulation poker

有很多扑克牌可能。我们希望通过删除类似的手来减少这一点,以便我们可以遍历每个可能的组合。

为了做到这一点,可能的组合用长度为52的字符串表示,其中a' 0'表示该卡不存在,并且表示该卡不存在。表示该卡已存在。

所以亲手 2,3,4,5,6的心将是:' 0000000000000000000000000000000000000000000000011111'

2,4,10,心脏和3个俱乐部将是: ' 0000000000000000000000000000000000000101000100000101'

依旧......

这里前13位表示黑桃A,K,Q,... 4,3,2, 接下来的13位是钻石 接下来的13个俱乐部 心灵的最后13个

现在我们需要做的是,从二进制字符串的十进制值,将其减少为类似的扑克手的二进制字符串并返回其十进制值

那么当我说出类似的手时,我的意思是什么: -   - A,Q,7,6,2的黑桃= AQ762的俱乐部= AQ762的心= AQ762的钻石 因此,它们的每个二进制表示都可以简化为心脏的AQ762的二进制表示,这是最小的   - 同样地,2,3,4,5的黑桃和A的钻石相当于A的心脏和2,3,4,5的球杆,所以前者可以减少到后者。

AsKsQsJsTs = 1111100000000000000000000000000000000000000000000000
AcKcQcJcTc = 0000000000000000000000000011111000000000000000000000
AdKdQdJdTd = 0000000000000111110000000000000000000000000000000000
AhKhQhJhTh = 0000000000000000000000000000000000000001111100000000

Ac5s4s3s2s = 0000000001111000000000000010000000000000000000000000
Ah5c4c3c2c = 0000000000000000000000000000000000011111000000000000
Ac5d4d3d2d = 0000000000000000000000111100000000000001000000000000

但我知道:

AKQJTs == AKQJTc == AKQJTd == ... are same, because combination have same strength in poker, we can simplify suits
Ac5432s == Ah5432c == Ah5432d == ... are same

我认为我们可以在诉讼中使用抽象:[1],[2],[3],[4]

[1] - new first suit, suit of highest card
[2] - second suit if we are going down from highest card


65432[1] == 65432s == 65432c == 65432d == ..
6[1]5432[2] == 6c5432s == 6h5432c == 6c5432d == ..

第一套最高牌是[1]和下一个新套装[2] ....

面具将是:

AKQJTs=AKQJTc=AKQJTd=AKQJTh = 0000000000000000000000000000000000000001111100000000 = 7936

Ah5432c=Ac5432d= ... = 0000000000000000000000000000000000011111000000000000 = 126976

如何有效地进行遮罩转换?

喜欢 - simplyfyMask(4362862139015168) = 7936 simplyfyMask(1040187392) = 126976

PS:如果我将使用另一个面具:Aces - 0,1,2,3,Kings - 4,5,6,7,Jacks - 8,9,10,11 - bits?

1 个答案:

答案 0 :(得分:0)

在您提供的示例中: simplyfyMask(1040187392)= 126976 你可以进一步减少这个:
from - 0000000000000000000000000000000000011111000000000000
至 - - - 0000000000000000000000000000000000000011000000001110
因为他们有像扑克手一样的等级

这是一个python代码(希望这有帮助,我不是C程序员,所以没有用C语言回答)

def replaceByindex(string, index, value) :
    li = list(string)
    li[index] = value
    return ''.join(li)

def checkFlush(string) :
    for suit in range(4) :
        count = 0
        # print(suit,'-th suit check for flush')
        for card in range(13) :
            if string[suit*13 + card] != '0' :
                count += 1
        if count == 0 :
            continue
        elif count == 5 :
            # print('Flushed')
            return True
        else :
            # print(count,'cards counted for',suit,'-th suit')
            return False

def unFlushify(string) :
    if checkFlush(string) :
        for card in range(13) :
            index = 51 - card
            if string[index] == '2' :
                string = replaceByindex(string,index-13,'2')
                string = replaceByindex(string,index,'0')
                break
    return string

def  simplifyMask(num) :
    num = bin(num)
    num = num[2:]
    size = len(num)
    num = '0'*(52-size) + num
    # print(num, len(num))
    count = 0
    i = 0
    if not checkFlush(num) :
        while i<52 and count<5 :
            if num[i] == '1' :
                count += 1
                tgt_index = 39 + i%13
                updated = False
                while tgt_index>i and num[tgt_index] != '0' :
                    tgt_index -=13
                if tgt_index <= i :
                    num = replaceByindex(num,i,'2')
                else :
                    num = replaceByindex(num,i,'0')
                    num = replaceByindex(num,tgt_index,'2')
            i+=1
        num = unFlushify(num)
    else :
        while i<52 and count<5 :
            if num[i] == '1' :
                count+=1
                num = replaceByindex(num,i,'0')
                num = replaceByindex(num,39+i%13,'2')
    return num.replace('2','1')


num = int(input())
number = simplifyMask(num)
print(int(number,2),number)

我认为自己是编码的初学者,所以这可能不是最有效的代码片段,但这可以让你了解如何继续。 :)