博弈树 (15分)
Grade: 15 / Discount: 0.8
下棋属于一种博弈游戏,博弈过程可以用树(博弈树)来表示。假设游戏由两个人( A 和 B )玩,开始由某个人从根结点开始走,两个人轮流走棋,每次只能走一步, 下一步棋只能选择当前结点的孩子结点,谁先走到叶子结点为胜。例如,对于下图所示的博弈树,若 A 先走,可以选 f , B 若选 h ,则 A 选 j 胜。
编写一程序,让计算机和人下棋。当计算机走下一步时,可以根据以下情况决定下一步:
(1) 若存在可以确保取胜的一个孩子结点,则选择该结点作为下一步;
(2) 若存在多个可以确保取胜的孩子结点,则选择其中高度最小的结点作为下一步(若有多个选择,则选最左边的结点);
(3) 若不存在可以确保取胜的一个孩子结点,则选择高度最大的孩子结点作为下一步(若有多个选择,则选最左边的结点);
例: (下面的黑体为输入)
(a,(b,(x)),(c,(d),(e,(g), ),(f)))
a
b
x
c
d
e
g
h
f
Who play first(0: computer; 1: player )?
1
player:
c
computer: d
Sorry, you lost.
Continue(y/n)?
y
Who play first(0: computer; 1: player )?
1
player:
x
illegal move.
player:
b
computer: x
Sorry, you lost.
Continue(y/n)?
y
Who play first(0: computer; 1: player )?
0
computer: c
player:
f
Congratulate, you win.
Continue(y/n)?
n
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define OVERFLOW 0
#define OK 1
int n=0,flag0=0,i=0,p=0,s=0,r[50],k1[30]={0},m=0,t1,m1=1,flag=0,k[30]={0},t[30]={0};
typedef enum{ATOM,LIST} Elemtag;
typedef struct GLNode
{
Elemtag tag;
union{
char atom;
struct{
struct GLNode *hp,*tp;
}ptr;
}asp;
}GList;
Elemtag Node(char *s)
{
if(strlen(s)==1)
return(ATOM);
else
return(LIST);
}
char *Gethead(char *s)
{
int i,j,l;
char *t;
t = (char *) malloc(sizeof(char)*80);
l=strlen(s)-1;
for(i=1,j=0;i<=l;i++)
{
if(s[i]=='(') j++;
if(s[i]==')') j--;
if(j==0)
{
break;
}
}
for(j=0;j<=i-1;j++)
{
t[j]=s[j+1];
}
t[j]='\0';
return t;
}
char *Gettail(char *h)
{
int i,j,l,w;
char *m;
m=(char*)malloc(sizeof(char)*80);
l=strlen(h)-1;
if(h[1]==')')
return((strcpy(m,"()"),m));
for(i=1,j=0;i<=l;i++)
{
if(h[i]=='(') j++;
if(h[i]==')') j--;
if(j==0)break;
}
if(h[i+1]==')'&&(i+1)==l)
{
return(strcpy(m,"()"),m);
}
else
{
m[0]='(';
for(w=1,j=i+2;j<=l;j++)
{
m[w++]=h[j];
}
m[w]='\0';
return (m);
}
}
GList *CreateGList(GList *L, char *S)
{
if(!strcmp(S,"()"))
{
L=NULL;
}
else
{
L=(GList*)malloc(sizeof(GList));
L->tag=Node(S);
if(L->tag==ATOM) {L->asp.atom=S[0];}
else
{
L->asp.ptr.hp = CreateGList(L->asp.ptr.hp,Gethead(S));
L->asp.ptr.tp = CreateGList(L->asp.ptr.tp,Gettail(S));
}
}
return L;
}
int print(GList *L,int i)
{
int j;
if(L)
{
if(L->tag==ATOM)
{
for(j=0;j<(i-1)*4;j++)
{
printf(" ");
}
printf("%c\n",L->asp.atom);
}
else
{
print(L->asp.ptr.hp,i+1);
print(L->asp.ptr.tp,i);
}
}
return ;
}
void print2(GList *L)
{ GList *v;
if(L==NULL||L->tag==ATOM)return;
else
{
if(L->asp.ptr.hp->tag==ATOM)
{
for(v=L->asp.ptr.tp;v!=NULL;r[m]++,v=v->asp.ptr.tp);
m++;
}
print2(L->asp.ptr.hp);
print2(L->asp.ptr.tp);
} return;
}
int depth(GList *p,int t1)
{
GList *q;
for(q=p->asp.ptr.tp;q;q=q->asp.ptr.tp)
{
if(q->asp.ptr.hp->asp.ptr.hp->tag==ATOM)
{
depth(q->asp.ptr.hp,t1+1);
if(q->asp.ptr.hp->asp.ptr.tp==NULL)
{
k[s++]=t1+1;
}
}
}
}
GList *make(GList *p, char key)
{
GList *q=p->asp.ptr.tp;
for(;q;q=q->asp.ptr.tp)
{
if(q->asp.ptr.hp->asp.ptr.hp->tag==ATOM&&q->asp.ptr.hp->asp.ptr.hp->asp.atom==key)
{
return(q->asp.ptr.hp);
}
}
printf("illegal move.\n");
flag0=1;
return p ;
}
GList *made(GList *p)
{
int i1,i3=0,j1=0,w=0,flag1,temp,flag=1,kj,ko,max=0;
GList *q;
while(flag)
{
for(q=p->asp.ptr.tp;q;q=q->asp.ptr.tp)
{
ko=0;kj=0;s=0;
for(i1=0;i1<30;i1++)
{
k[i1]=0;
}
depth(q->asp.ptr.hp,1);
for(i1=0,temp=0;k[i1];i1++)
{
if(k[i1]%2==0)
{
ko++;
}
else
{
kj++;
}
if(temp<k[i1])
{
temp=k[i1];
}
}
k1[i3++]=temp;
if(temp==0)
{
printf("computer: %c\n",q->asp.ptr.hp->asp.ptr.hp->asp.atom);
printf("Sorry, you lost.\n");
return NULL;
}
if(ko==0&&kj>0)
{
t[w++]=temp;
}
if(kj==0&&ko>0)
{
t[w++]=temp;
}
if(kj>0&&ko>0)
{
t[w++]=-1;
}
}
for(i1=0,temp=0,max=0;t[i1];i1++)
{
if(t[i1]==-1)
{
}
else{
if(t[i1]%2!=0&&t[i1]>max)
{
max=t[i1];
temp=i1;
}
}
}
if(temp!=0)
{
for(j1=0;j1<=temp;j1++)
{
p=p->asp.ptr.tp;
}
printf("computer: %c\n",p->asp.ptr.hp->asp.ptr.hp->asp.atom);
return p->asp.ptr.hp;
}
for(i1=0,temp=0;t[i1];i1++)
{
if(t[i1]==-1&&k1[i1]>temp)
{
temp=i1;
max=t[i1];
}
}
if(temp!=0)
{
for(j1=0;j1<=temp;j1++)
{
p=p->asp.ptr.tp;
}
printf("computer: %c\n",p->asp.ptr.hp->asp.ptr.hp->asp.atom);
return p->asp.ptr.hp;
}
printf("Congratulate, you win.\n");
}
}
int main()
{
int n1,n2;
char s[100],c='y',key;
GList *L=NULL,*p;
gets(s);
L=CreateGList(L,s);
print(L,n);
print2(L);
while(c=='y')
{
p=L;
printf("Who play first(0: computer; 1: player )?\n");
scanf("%d",&n1);
if(n1==1)
{
b:printf("player:\n");
getchar();
scanf("%c",&key);
p=make(p,key);
if(flag0==1)
{
flag0=0;
goto b;
}
if(p->asp.ptr.tp==NULL)
{
printf("Congratulate, you win.\n");goto A;
}
}
if(p!=NULL)
{
p=made(p);
if(p!=NULL)
{
goto b;
}
}
A: printf("Continue(y/n)?\n");
for(n1=0;n1<30;n1++)
{
t[n1]=0;
}
getchar();
scanf("%c",&c);
}
return 0;
}