斗地主农民手牌的58684015种可能性

# -*- coding: utf-8 -*-


'''
计算斗地主一手牌的所有可能组合数

原创算法
'''


#计算Cn x  组合数
def get_combinations(n , x) :
    t1 = n - x 
    if t1 < x :
        x = t1
        
    
    if x == 0 :
        return 1
    if x == 1 :
        return n
    
    tmp1 = 1
    tmp2 = 1
    for i in range(0 , x ) :
        tmp1 *= (n - i)
        tmp2 *= (i+1)
    return tmp1 / tmp2
    
#计算 x 张牌不含大小王的可能组合数
def func1( x ) :
    #a代表张数为1的扑克数  b .. 2   c .. 3   d .. 4
    result = 0l
    #a可能是0 到 13的任何数  因为扑克是A到K共13种
    for a in range(0 , 14) :
        sum1 = a
        #b可能是0 到 13的任何数  因为扑克是A到K共13种
        for b in range(0 , 14) :
            sum2 = sum1 + b
            #单张与对子必须是不同的,相加不能超过13 
            if sum2 > 13 :
                break
            for c in range(0 , 14) :
                sum3 = sum2 + c
                #单张与对子与三条必须是不同的,相加不能超过13
                if sum3 > 13 :
                    break
                for d in range(0 , 14) :
                    sum4 = sum3 + d 
                    #单张与对子与三条与四条必须是不同的,相加不能超过13
                    if sum4 > 13 :
                        break
                    #如果符合此约束,则此手牌成立 , x为总张数
                    if a + 2*b + 3*c + 4*d == x :
                        '''
                        print '-------------'
                        print a
                        print b
                        print c
                        print d
                        '''
                        #组合分配 单牌是 C13 a种可能性  对子是 C(13-a) b 种可能性  。。。。。。。
                        #单 * 对 * 三 * 四 = 此情况下总组合数 , 将其累加到总组合数中
                        result += get_combinations(13 , a ) * get_combinations(13 - a , b)\
                        * get_combinations(13 - a - b , c) * get_combinations(13 - a - b - c , d)
                    
    return result




#农民17张牌的总可能性   无王 + 2*单王 + 双王
result = func1( 17 ) + 2 * func1( 16 ) + func1( 15 )
print result
#58684015


#地主20张牌的总可能性   无王 + 2*单王 + 双王
result = func1( 20 ) + 2 * func1( 19 ) + func1( 18 )
print result
#153009740

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值