三子棋

来源:互联网 发布:民宿 知乎 编辑:程序博客网 时间:2024/06/15 05:26

摘要:同样是利用回溯算法计算模拟电脑下三子棋.

基本思路:

[1]电脑和人下棋,主要的一种思路就是去计算下一步每一个点的位置函数.如果下在这个点使得电脑获胜,那么将返回一个值(1),如果棋盘已满,则返回0,如果对手获胜,则返回-1.假如下的这一步棋不是决定的关键棋,那么电脑将要调用一个函数去模拟人的下棋轨迹.人下棋的时候总是要寻找使得下一步所在的位置函数最小,这样代表自己获胜或者平局.同样的如果这一步也不是最终的位置.那么模拟人的函数也要调用模拟电脑的函数去判断电脑会怎么下.这样直到遍历完所有的可能,则电脑总是可以保持不败.

[2]现在要做的是提高效率,因为有些时候,某些试探是不必要的.比如电脑已经找到了一个位置函数,它的值为a,那么当它调用人的函数时,人一定会返回它所能找到的最小的位置函数来确保自己的胜利.设人已经找到的位置函数值是b.很显然,如果ab,那么人继续递归找到的值如果大于b将不会返回(人需要选取最小的位置函数).如果返回的值小于于b,那么返回给电脑的值将不会改变a.因此不需要继续递归.同时对人有着对应的情况.这称为αβ裁剪.

[3]注意回溯的时候要将棋盘的状态复原.

#include "stdafx.h"#include "math.h"#define N 9#define draw 0#define compwin 1#define  comploss -1#define comp 1#define human -1int FullBoard(int Board[]){    if(Board[0] == N)        return 1;    else        return 0;}int Immediatewin(int Board[],int *Bestmove,int comporhuman){    int x,y,deltax = 0,deltay = 0;    int tempx,tempy,Num[5] = {0};    for (int i = 1;i<=N;i++)    {       if (Board[i]==0)       {           y = i%3 > 0 ?i%3 : 3;           x = (i-y)/3 + 1;           for(int k = -4;k<=4;k++)           {               if(k==0)                 continue;               switch(abs(k))               {               case 1:                   deltax = -1;                   deltay = 0;                   break;               case 2:                   deltax = -1;                   deltay = 1;                   break;               case 3:                   deltax = 0;                   deltay = 1;                   break;               case 4:                   deltax = -1;                   deltay = -1;                   break;               }//end of switch               if(k<0)               {                   deltax = -deltax;                   deltay = -deltay;               }               tempx = (x+deltax);               tempy = (y+deltay);               while(tempx<=3&&tempy<=3&&tempx>=1&&tempy>=1)               {                   if (Board[(tempx-1)*3 + tempy] == comporhuman)//相邻棋子是同类                       Num[abs(k)]++;                   tempx += deltax;                   tempy +=deltay;               }           }           for(int k = 1;k<=4;k++)           {                 if (Num[abs(k)] == 2)                   {                       *Bestmove = i;                         return 1;                   }               Num[k] = 0;           }       }    }    return 0;}void Findhumanmove(int Board[],int *Bestmove,int *value,int alpha,int beta);void FindCompmove(int Board[],int *Bestmove,int *value,int alpha,int beta);int _tmain(int argc, _TCHAR* argv[]){    int Bestmove = 0;    int value = 0,x;    int Board[N+1] = {0};       printf("Comp the Bestmove: %d \nthe humanmove: :",5);       Board[5] = 1;        for (int i = 1;i<=5;i++)        {         scanf(" %d",&x);        Board[x] = human;        FindCompmove(Board,&Bestmove,&value,-1,1);        printf("Comp the Bestmove: %d  :",Bestmove);        Board[Bestmove] = comp;      }    return 0;}void Findhumanmove(int Board[],int *Bestmove,int *value,int alpha,int beta){    int Dc,Response;    if (FullBoard(Board))        *value = draw;    else if (Immediatewin(Board,Bestmove,human))        *value = comploss;    else    {        *value = beta;        if (*value <= alpha)            return;//beta裁剪        for(int i = 1;i<=N;i++)        {            if (Board[i] == 0)            {                Board[i] = human;//Place(Board,i,comp);                Board[0]++;                FindCompmove(Board,&Dc,&Response,alpha,*value);                Board[i] = 0;                Board[0]--;                if(Response < *value)                {                    *value = Response;                     *Bestmove = i;                }            }        }    }}void FindCompmove(int Board[],int *Bestmove,int *value,int alpha,int beta){    int Dc,Response;    if (FullBoard(Board))    {        *value = draw;    }    else if (Immediatewin(Board,Bestmove,comp))        *value = compwin;    else    {        *value = alpha;        if (*value >= beta)            return;//alpha裁剪        for(int i = 1;i<=N;i++)        {            if (Board[i] == 0)            {                Board[i] = comp;//Place(Board,i,comp);                Board[0]++;                Findhumanmove(Board,&Dc,&Response,*value,beta);                Board[i] = 0;                Board[0]--;                if(Response > *value)                {                    *value = Response;                     *Bestmove = i;                }            }        }    }}
0 0
原创粉丝点击