扑克牌斗牛游戏的概率问题

前几天过年跟亲朋好友玩起了斗牛,感觉还是挺刺激的,我发现有时候会连续好几把没有牛(脸黑的不适合这游戏…),让我对这概率产生了兴趣,就随便用c编程模拟计算了一下概率。

玩法简介:一副牌去掉大小王,其中JQK当做点数10,每人5张牌,以三张一卡、两张一卡的形式,当其中三张卡点数和为10的倍数,这叫“牛”,另外两张牌点数和若也为10的倍数,即为“牛牛”,此种牌最大,否则模10即为结果,越大牌也就越大;若没有三张卡点数和为10的倍数,则没有“牛”,此种牌最小。

判断拿到的牌的结果:只有5张牌,可以直接暴力,取三张看是否是10的倍数,即是否有“牛”,没有直接返回0;若有,则计算剩下两张牌模10的结果,如果为0,返回10,否则返回该结果。

计算每种牛概率:首先假设每张牌发到的概率相等,那么可以直接暴力遍历所有种发到的牌的组合数,共有C(5,52)=2598960种可能,显然运算速度太慢了。之后发现好多相同数字组合的重复计算了,因此考虑直接遍历所有数字组合,对每种组合再计算其所有可能牌的组合数,例如:拿到的牌数字为4、4、5、5、10,那么出现这种组合共有C(2,4)*C(2,4)*C(1,4)=144种可能,该组合牌结果为“牛8”,结果数组cnt[8]+=144即可。

结果:
扑克牌斗牛游戏的概率问题_第1张图片
除了“没有牛”和“牛牛”,其他概率差不多相等,而“没有牛”的概率竟然高达三分之一,看来连续几把没抽到“牛”还是挺正常的。。。

c++源码如下:

#include
#include
#include
#include
#include
#include
using namespace std;
vectorcnt;

int judge(vectora){//判断拿到的5张牌的结果
    int sum=0;
    for(int i=0;i10) a[i]=10;
        sum+=a[i];
    }
    int res=0;
    if(sum<=11) return 0;
    for(int i=0;i<5;i++){
        for(int j=i+1;j<5;j++){
            for(int k=j+1;k<5;k++){
                int temp=a[i]+a[j]+a[k];
                if(temp%10==0){
                    res=(sum-temp)%10;
                    if(res==0) res=10;
                    return res;
                }
            }
        }
    }
    return 0;
}

int countnum(vectora){//计算出现这几种大小的牌共有多少种可能
    vectort(15,0);
    for(int i=0;icard(5);
    cnt.resize(11,0);
    int s=0;
    //遍历拿到的牌大小的所有可能
    for(int a=1;a<=13;a++){
        card[0]=a;
        for(int b=a;b<=13;b++){
            card[1]=b;
            for(int c=b;c<=13;c++){
                card[2]=c;
                for(int d=c;d<=13;d++){
                    card[3]=d;
                    for(int e=d;e<=13;e++){
                        if(card[0]==e&&card[1]==e&&card[2]==e&&card[3]==e) continue;
                        card[4]=e;
                        printf("%d %d %d %d %d\n",card[0],card[1],card[2],card[3],card[4]);
                        int ans;
                        ans=judge(card);
                        cnt[ans]+=countnum(card);
                        s++;
                    }
                }
            }
        }
    }

    printf("%d %d\n",52*51*50*49*48/120,s);//理论上所有牌组合数、模拟出来所有数字组合数
    int sum=0;//模拟出来的牌组合数
    for(int i=0;i<11;i++){
        sum+=cnt[i];
    }
    printf("%d\n",sum);
    for(int i=0;i<11;i++){
        printf("%d %d %.3f\n",i,cnt[i],cnt[i]*1.0/sum);//出现各种牛的概率大小
    }
    return 0;
}

你可能感兴趣的:(娱乐)