由于比赛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\