井字棋
半天搞不定,程序是参照《PCGAME》那本书写的,但是电脑就是走不对。
就要交作业了
厚着脸皮来求个现成的算法
最好有注释,和最初调用的代码。thx

解决方案 »

  1.   

    那我贴一下吧
    不过是在C#下面写的,应该差不多吧
    b_type为当前电脑要下的棋子,b表示下一子的类型,Anti01()函数用来变换子的类型。
    done[]为某位是否走过,type[]是该位已走子的类型,2为空
    CheckWin检测获胜和CheckWinAdd为估值,这两个函数是没有问题的。
    private int AlphaBeta(int nPly,int nAlpha,int nBeta,int b)
    {
    if(CheckWin(type,b_type)==b_type)return 999;
    else if(CheckWin(type,Anti01(b_type))==Anti01(b_type))return -999; //胜负已分,返回估值
             if(nPly <= 0)//叶子节点返回估值
    {
    int []typetemp = new int [10];
    int aaa=0,bbb=0,e=0;
    for (int f=1;f<10;f++)
    {
         typetemp[f]=type[f];
    }
                      for(int k=1;k<10;k++)
    {
    if (done[k]==false) {
                        typetemp[k]=b_type;
    aaa=CheckWinAdd(typetemp,b_type);//MAX
    }
    for (int f=1;f<10;f++)
    {
    typetemp[f]=type[f];
    }
    for(int k=1;k<10;k++)
    {
    if(done[k]==false)
    typetemp[k]=Anti01(b_type);
    bbb=CheckWinAdd(typetemp,Anti01(b_type));//MIN
    }
    e=aaa-bbb;
    return e;//e就是设定的估值
    }
    for(int j=1;j<10;j++)//对每一可能的走法
    {
    int score=nAlpha;
    if (done[j]==false)
    {
    done[j]=true;
    type[j]=b;//生成新节点
    score = -AlphaBeta(nPly-1,-nBeta,-nAlpha,Anti01(b));//递归搜索子节点 type[j]=2;
    done[j]=false;//撤销搜索过的节点
    }
    if(score > nAlpha)nAlpha = score;//保存最大值
    if(nAlpha >= nBeta)break;//beta剪枝
    }
    return nAlpha;//返回极大值
    }主函数里调用为
    for (i=1;i<10;i++)
    {
             if (done[i]==false)
    {
    done[i]=true;
    type[i]=b_type;
    power[i]=-AlphaBeta(3,0,0,Anti01(b_type));
    type[i]=2;
    done[i]=false;
    }
    }
    得到每一个位置的估值power[],后面再通过比较这个值决定走哪个位置,后面的程序也没有问题。运行之后没走过的位置的power[]值都相同!:(
    感觉迭代或者主函数调用的时候有问题。
    大家帮我吧~~~