# -*- 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