电子游戏中的数学
近年来,随着电子游戏的日益普及,电子游戏业已成为横跨信息技术和文化的重要产业。对电子游戏中的一些数学问题进行研究,成为数学界和相关人士的一个热门话题。
在某电子游戏中,玩家每次下注一元,由机器随机分配给玩家五张扑克牌,然后允许玩家有一次换牌的机会,即可以放弃其中的某几张牌,放弃的牌留下的空缺由机器在剩下的47张牌中再次随机分配。玩家的奖金依据其最后所持有的牌型而定。下面是一份典型的奖金分配表:
牌型 | 奖金(元) |
同花大顺(10到A) | 800 |
同花顺 | 50 |
四张相同点数的牌 | 25 |
满堂红(三张同点加一对) | 8 |
同花 | 5 |
顺子 | 4 |
三张相同点数的牌 | 3 |
两对 | 2 |
一对高分对(J及以上) | 1 |
其它 | 0 |
在上表中,玩家的牌型属于某一类型且不属于任何更高的类型,则赢得该牌型相应的奖金。
若某玩家采取以下策略,当原始的牌型构成一个顺子或更高的牌型时,则放弃换牌的机会;否则,除保留对子或三张相同点数的牌外,将手中其余的牌放弃,由机器再次随机分配。根据上述游戏规则和策略,分析各类牌型出现的可能性,计算采取该策略能获得的期望奖金金额。
用C语言编程模拟情况如下:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<time.h>
typedef struct node
{
int Number;
char Color;
int IsSame;
struct node *link;
}Node,*List;
void Welcome(); /*欢迎界面*/
void FaPai(List H); /*发牌(并且已经按照玩家的策略进行了换牌)*/
void FuZhi_IsSame(List H); /*对IsSame进行赋值*/
int Type(List H); /*判断牌型*/
void JiangLi(int type); /*得到奖励*/
void InitList(List *p); /*初始化链表*/
void InsertList(List H,char color,int number); /*插入链表*/
void DeleteList(List H); /*删除链表*/
void main()
{
List H,p;
int i;
int ans;
char answer='y';
srand(time(NULL));
Welcome();
while(answer=='y')
{
for(i=0;i<1;i++) /*控制进行多少次游戏*/
{
/* printf(" %d",i+1); */
InitList(&H);
/*printf("/nYour pai is :/n/n");*/
FaPai(H);
while(H->link!=NULL)
{
p=H->link;
H->link=p->link;
free(p);
}
}
printf("/n Do you want to test angain?/n");
answer=getch();
putch(answer);
}
getch();
return;
}
void InitList(List *p)
{
List q;
q =(List)malloc(sizeof(Node));
q->Color=0;
q->Number=0;
q->IsSame=0;
q->link=NULL;
*p = q;
return;
}
void InsertList(List H,char color,int number)
{
List p,q;
int i=0;
q =(List)malloc(sizeof(Node));
q->Color=color;
q->Number=number;
q->IsSame=1;
p=H;
while(H->link!=NULL)
{
p=H->link;
if(q->Number>=p->Number)
{
H=H->link;
continue;
}
else
{
i=1;
break;
}
H=H->link;
}
if(i==0)
{
q->link=p->link;
p->link=q;
}
else
{
q->link=H->link;
H->link=q;
}
return;
}
void DeleteList(List H)
{
List p,q;
p=H->link;
q=H;
while(p!=NULL)
{
if(p->IsSame==1)
{
q->link=p->link;
p=p->link;
}
else
{
p=p->link;
q=q->link;
}
}
return;
}
void Welcome()
{
printf("************Welcome our game's room************/n");
printf("* */n");
printf("* */n");
printf("* Fa Pai Game */n");
printf("* */n");
printf("* */n");
printf("***********************************************/n");
return;
}
void FaPai(List H)
{
int i,j,card[52];
int display;
int count;
int no; /*随机的牌*/
int number=0; /*控制显示几张牌*/
int type;
List p;
for(count=0;count<52;count++)
card[count]=count;
for(i=0;i<52;i++)
{
no=rand()%52;
/*the value of no is from 0 to 53*/
if(card[no]==-1)
{
i--;
continue;
}
display=no;
card[no]=-1;
InsertList(H,display/13+3,(display+1)%13+2);
number++;
if(number==5)
{
p=H->link;
printf("/n/n");
printf("/nBefore changing!");
printf("/n/n");
while(p!=NULL)
{
printf("%c%d /t",p->Color,p->Number);
p=p->link;
}
printf("/n/n");
FuZhi_IsSame(H);
type=Type(H);
if(type<=6) /*玩家策略在顺子以上不换牌*/
{
break;
}
else if(type==7) /*玩家策略在三张相同点数的牌要换剩下的俩张牌*/
{
DeleteList(H); /*删除链表中IsSame为1的链接点*/
for(j=0;j<2;j++) /*随机产生新的俩张牌*/
{
no=rand()%52;
if(card[no]==-1)
{
j--;
continue;
}
display=no;
card[no]=-1;
InsertList(H,display/13+3,(display+1)%13+2);
}
FuZhi_IsSame(H);
type=Type(H);
break;
}
else if(type==8) /*玩家策略在俩个对子的牌要换剩下的俩张牌*/
{
DeleteList(H); /*删除链表中IsSame为1的链接点*/
for(j=0;j<1;j++) /*随机产生新的一张牌*/
{
no=rand()%52;
if(card[no]==-1)
{
j--;
continue;
}
display=no;
card[no]=-1;
InsertList(H,display/13+3,(display+1)%13+2);
}
FuZhi_IsSame(H);
type=Type(H);
break;
}
else if(type==9) /*玩家策略在一个高分对子的牌要换剩下的三张牌*/
{
DeleteList(H); /*删除链表中IsSame为1的链接点*/
for(j=0;j<3;j++) /*随机产生新的三张牌*/
{
no=rand()%52;
if(card[no]==-1)
{
j--;
continue;
}
display=no;
card[no]=-1;
InsertList(H,display/13+3,(display+1)%13+2);
}
FuZhi_IsSame(H);
type=Type(H);
break;
}
else if(type==10) /*玩家策略在一个低分对子的牌要换剩下的三张牌*/
{
DeleteList(H); /*删除链表中IsSame为1的链接点*/
for(j=0;j<3;j++) /*随机产生新的三张牌*/
{
no=rand()%52;
if(card[no]==-1)
{
j--;
continue;
}
display=no;
card[no]=-1;
InsertList(H,display/13+3,(display+1)%13+2);
}
FuZhi_IsSame(H);
type=Type(H);
break;
}
else if(type==11) /*玩家策略在一个什么都不是的牌要换所有的五张牌*/
{
DeleteList(H); /*删除链表中IsSame为1的链接点*/
for(j=0;j<5;j++) /*随机产生新的五张牌*/
{
no=rand()%52;
if(card[no]==-1)
{
j--;
continue;
}
display=no;
card[no]=-1;
InsertList(H,display/13+3,(display+1)%13+2);
}
FuZhi_IsSame(H);
type=Type(H);
break;
}
}
}
/*测试插入是否成功,插入好以后就已经按照升序排序了*/
p=H->link;
printf("/n/n");
printf("/nThe result:!");
printf("/n/n");
while(p!=NULL)
{
printf("%c%d /t",p->Color,p->Number);
p=p->link;
}
printf("/n/n");
JiangLi(type);
return;
}
void FuZhi_IsSame(List H)
{
List p,q,w;
w=H->link;
p=H->link;
q=H->link;
while(w!=NULL)
{
w->IsSame=1;
w=w->link;
}
while(p->link!=NULL)
{
while(q->link!=NULL)
{
if(p->Number==q->link->Number)
{
p->IsSame++;
q->link->IsSame++;
}
q=q->link;
}
p=p->link;
q=p;
}
/*测试IsSame是否赋值成功*/
/* p=H->link;
while(p!=NULL)
{
printf("[%c%d]%d/t",p->Color,p->Number,p->IsSame);
p=p->link;
}
printf("/n"); */
return;
}
int Type(List H)
{
List p;
int i,j,temp,max,type;
int same[5]={0};
p=H->link;
/*将所有的IsSame赋值到数组same中*/
for(i=0;i<5;i++)
{
same[i]=p->IsSame;
p=p->link;
}
p=H->link;/*为了下面判断type*/
/*对数组same进行降序排序,找到最大值和第二大值*/
for(i=0;i<5;i++)
{
for(j=i;j<5;j++)
{
if(same[i]<same[j])
{
temp=same[i];
same[i]=same[j];
same[j]=temp;
}
}
}
/*测试IsSame按照升序排序好后的数组same*/
/*printf("/n/n");
printf("The IsSame is :/n/n");
for(i=0;i<5;i++)
printf("%d ",same[i]); */
if(same[0]==4)
type=3; /*四张相同点数的牌*/
else if(same[0]==3)
{
if(same[3]==2)
type=4; /*满堂红*/
else
type=7; /*三张相同点数的牌*/
}
else if(same[0]==2)
{
if(same[2]==2)
type=8; /*俩对*/
else
{
while(p!=NULL)
{
if(p->Number>=11&&p->IsSame==2)
{
type=9; /*一对高分对*/
break;
}
p=p->link;
}
if(p==NULL)
type=10; /*一对小对,属于其它*/
}
}
else if(same[0]==1)
{
if(p->link->link->link->link->Number - p->Number == 4)
{
if(p->Number==10)
{
if(p->Color==p->link->Color && p->Color==p->link->link->Color && p->Color==p->link->link->link->Color && p->Color==p->link->link->link->link->Color)
type=1; /*同花大顺*/
else
type=6; /*顺子*/
}
else
{
if(p->Color==p->link->Color && p->Color==p->link->link->Color && p->Color==p->link->link->link->Color && p->Color==p->link->link->link->link->Color)
type=2; /*同花顺*/
else
type=6; /*顺子*/
}
}
else
{
if(p->Color==p->link->Color && p->Color==p->link->link->Color && p->Color==p->link->link->link->Color && p->Color==p->link->link->link->link->Color)
type=5; /*同花*/
else
type=11; /*其它*/
}
}
return type;
}
void JiangLi(int type)
{
switch(type)
{
case 1:
printf("/n/nYour reward is : 800");
break;
case 2:
printf("/n/nYour reward is : 50");
break;
case 3:
printf("/n/nYour reward is : 25");
break;
case 4:
printf("/n/nYour reward is : 8");
break;
case 5:
printf("/n/nYour reward is : 5");
break;
case 6:
printf("/n/nYour reward is : 4");
break;
case 7:
printf("/n/nYour reward is : 3");
break;
case 8:
printf("/n/nYour reward is : 2");
break;
case 9:
printf("/n/nYour reward is : 1");
break;
case 10:
printf("/n/nYour reward is : 0");
break;
case 11:
printf("/n/nYour reward is : 0");
break;
default:
break;
}
return;
}
结果截屏如下: