博弈树

 博弈树 (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;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值