2015华为软件精英挑战赛德州扑克之蒙特卡洛法模拟胜率

本文介绍了如何使用蒙特卡洛法在500ms内计算德州扑克中手牌的胜率,通过模拟对手的手牌进行决策。文中详细展示了排序、生成随机牌、检查重复牌等函数,以及计算不同牌型价值的算法,用于评估手牌优势,并最终计算胜率。
摘要由CSDN通过智能技术生成

由于比赛500ms的时间限制,想要知道自己的牌力胜率是多大,我们采取了蒙特卡洛法,模拟对手的手牌,计算自己的胜率,依据胜率作出决策

经过几次改进,该模拟算法可以在500ms以内完成,从而可以保证不超时

void sortCards(card mcard[], int num)
{
    int temp = 0,temp2;
    for (int i = 0; i < num; i++)
    for (int j = 0; j < num - i - 1; j++)
    {
        if (mcard[j].point < mcard[j + 1].point)
        {
            temp = mcard[j].point;
            mcard[j].point = mcard[j + 1].point;
            mcard[j + 1].point = temp;

            temp2=mcard[j].color;
            mcard[j].color=mcard[j+1].color;
            mcard[j+1].color=temp2;
        }
    }

}
void sortCardsColor(card mcard[], int num)
{
    int temp = 0,temp2;
    for (int i = 0; i < num; i++)
    for (int j = 0; j < num - i - 1; j++)
    {
        if (mcard[j].color < mcard[j + 1].color)
        {
            temp = mcard[j].point;
            mcard[j].point = mcard[j + 1].point;
            mcard[j + 1].point = temp;

            temp2=mcard[j].color;
            mcard[j].color=mcard[j+1].color;
            mcard[j+1].color=temp2;
        }
    }

}
void produceNumbersCard(card mcard[], int size =RANDSIZE)
{
    srand(time(NULL));

    for (int i = 0; i<size; i++)

        mcard[i].point = ((rand() % (14 - 2 + 1)) + 2);
    srand(time(NULL));
    for (int i = 0; i<size; i++)
        mcard[i].color = ((rand() % (4 - 1 + 1)) + 1);
}
bool isInHadCards(card newCard, card hadCard[],int hadCardSize)
{

     for (int i = 0; i < hadCardSize; i++)
     {
         if (newCard.point == hadCard[i].point&&newCard.color == hadCard[i].color)
         {
           return true;
         }
     }

    return false;
}

long calculTongHuaShun(card th[])
{

    if((th[0].point-th[4].point)==12)
        return 630000+11000000;   //A5432
    long temp=0;
    temp=th[0].point*100000+th[1].point*6000+th[2].point*400+th[3].point*20+th[4].point;
    return temp+11000000;
}

long calculSiTiao(card st[])
{

    if(st[0].point==st[1].point)  //四条在前,单牌在后88883;
        return st[0].point*400+st[4].point+10000000;
    else                         //四条在后,单牌在前52222;
        return st[1].point*400+st[0].point+10000000;
}

long calculLuHua(card Lh[])
{
    if(Lh[0].point==Lh[1].point&&Lh[1].point==Lh[2].point) //表示三条在前
        return Lh[0].point*400+Lh[3].point+9000000;
    else              //表示两条在前
        return Lh[2].point*400+Lh[0].point+9000000;
}
long calculTongHua(card th[])
{
   long temp=0;
   temp=th[0].point*100000+th[1].point*6000+th[2].point*400+th[3].point*20+th[4].point;
   return temp+7000000;
}
long calculShunZi(card sz[])
{
    long temp=0;
    temp=sz[0].point*100000+sz[1].point*6000+sz[2].point*400+sz[3].point*20+sz[4].point;
    return temp+5000000;
}
long calculSanTiao(card sant[])
{
    int k=0;  //记录第一个三条出现的位置
    for(int i=0;i<3;i++)
    {   //如果三张牌连续相等
        if(sant[i].point==sant[i+1].point&&sant[i+1].point==sant[i+2].point)
        {
           k=i;
        }
    }
    switch(k)
    {
    case 0: return sant[0].point*400+sant[3].point*20+sant[4].point+4000000;//55543
    case 1: return sant[1].point*400+sant[0].point*20+sant[4].point+4000000;//65553
    case 2: return sant[2].point*400+sant[0].point*20+sant[1].point+4000000;//76555
    }
}
long calculLiangDui(card Ld[])
{
    int fk=0,sk=0;  //分别用来记录第一对与第二对的位置
    if(Ld[0].point==Ld[1].point)
        fk=0;
    else if(Ld[1].point==Ld[2].point)
        fk=1;
    if(Ld[2].point==Ld[3].point)
        sk=2;
    else if(Ld[3].point==Ld[4].point)
        sk=3;

    if(fk==0&&sk==2)   //66553
        return Ld[0].point*400+Ld[2].point*20+Ld[4].point+3000000;
    else if(fk==1&&sk==3)//76655
        return Ld[1].point*400+Ld[3].point*20+Ld[0].point+3000000;
    else                  //77566
        return Ld[0].point*400+Ld[3].point*20+Ld[2].point+3000000;
}
long calculYiDui(card yd[])
{
    int ydk=0;  //记录一对的位置
    for(int i=0;i<4;i++)
    {
       if(yd[i].point==yd[i+1].point)
       {
           ydk=i;
           break;
       }
    }
    switch(ydk)
    {
    //77654
    case 0: return yd[0].point*6000+yd[2].point*400+yd[3].point*20+yd[4].point+2000000;
   //87754
    case 1: return yd[1].point*6000+yd[0].point*400+yd[3].point*20+yd[4].point+2000000;
    //98775
    case 2: return yd[2].point*6000+yd[0].point*400+yd[1].point*20+yd[4].point+2000000;
    //98766
    case 3: return yd[3].point*6000+yd[0].point*400+yd[1].point*20+yd[2].point+2000000;
    }
}
long calculGaoPai(card gp[])
{
    long temp=0;
    temp=gp[0].point*100000+gp[1].point*6000+gp[2].point*400+gp[3].point*20+gp[4].point;
    return temp;
}
long mycalcul7Card(card seven[])
{
    card tsc[7];
    for (int i = 0; i<7; i++)
    {
        tsc[i].point = seven[i].point;
        tsc[i].color = seven[i].color;
    }

    sortCards(tsc, 7);

    //是否有同花顺
    card tTHS[5];
    int tempTHSpoint = 0, tempTHSsize = 1;
    card tempTHSFive[5];  //储存已经找到的五张最大顺子
    card tempTHS[7];
    {
        tempTHSpoint = tsc[0].point;
        tempTHS[0].point = tsc[0].point;
        tempTHS[0].color = tsc[0].color;
    }
    //去重 9987654.
    for (int i = 1; i<7; i++)
    {
        if (tempTHSpoint != tsc[i].point)
        {
            tempTHSpoint = tsc[i].point;
            tempTHS[tempTHSsize].point = tsc[i].point;
            tempTHS[tempTHSsize].color = tsc[i].color;
            tempTHSsize++;
        }
    }
    if (tempTHSsize >= 5) //表示去重之后还有至少5张牌
    {

        int j = 0;
        sortCards(tempTHS, tempTHSsize);
        //进行是否是顺子除了A5432
        for (int i = 0; i <= tempTHSsize - 5; i++)
        {
            if (tempTHS[i].point == tempTHS[i + 1].point + 1\
                &&tempTHS[i + 1].point == tempTHS[i + 2].point + 1\
                &&tempTHS[i + 2].point == tempTHS[i + 3].point + 1\
                &&tempTHS[i + 3].point == tempTHS[i + 4].point + 1\
                )
            {
                for (j = i; j<i + 5; j++) //把这五张顺子储存下来
                {
                    tempTHSFive[j - i].point = tempTHS[j].point;
                    tempTHSFive[j - i].color = tempTHS[j].color;
                }
                //判断这个顺子是否是同花
                sortCardsColor(tempTHSFive, 5);
                if (tempTHSFive[0].color == tempTHSFive[1].color\
                    &&tempTHSFive[1].color == tempTHSFive[2].color\
                    &&tempTHSFive[2].color == tempTHSFive[3].color\
        

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值