五子棋新版本

由于原来那个五子棋算法有点缺陷,导致电脑有点笨笨,经过优化后好多了,以下是C语言版本的,比以前智能多了

用二维数组存储实际的数据,1代表人的棋子,-1代表计算机的棋子,0代表没有下子的空位。根据二 维数组中的数据,映射输出一个棋盘
2 电脑下棋算法:
电脑下棋的时候,对于每一个棋子,检查是自己的棋还是对手的棋,然后检查在这个棋的右 右上 上
左上 左 左小 下 右下等八个方向上的棋子个数,如果在某一个方向上的棋子较多,则记录这个点,用   循环的方法检查所有的棋子,得到可下的两个连续棋子最多的点,一个是自己方的,一个是敌方的,然   后比较这两个,如果对方的比自己的多,则和对方交换数据。然后在得到的自己的可下棋的地方下棋。
3 双方任一方下一步棋,就会检查棋盘,看是否有一方获胜
4 检查棋盘算法:
对于每一个棋子,检查其四周八个方向是否有5个连续相同的棋子(电脑的或者人的)出现,如果出现, 则其获胜,或者时候出现棋盘下满的现象,如果棋盘下满的话,则平局
5 双方任一方下一步棋,则清屏,重新输出棋盘

代码:

#include<stdio.h>
#include<time.h>
#include<windows.h>
#include<stdlib.h>
#include<conio.h>

typedef struct Temp
{
   int num,x,y;//可以下子最大数目num,坐标x,y
}Temp;
typedef struct Chess
{
   int length,width,Mat[20][20];//棋盘的范围和存储矩阵,矩阵中,1表示人的棋子,-1表示电脑的棋子,0表示空位
   int cnumber,pnumber,Flag;两方棋子的个数,是否结束的标志 Flag
   int cwin,pwin;//计算机落子处为-1,人落子处为1
}Chess;
/
void SetTemp(Temp *T,int x1,int y1,int n);
void Initchess(Chess *C,int l,int w);
void Printwindow(Chess *C);
void SetChess(Chess *C,int l,int w);
void Computermove(Chess *C);
void Playermove(Chess *C);
void Checkwin(Chess *C,int flag);
void Findplace(Chess *C,int x1,int y1,Temp *T, int flag);
///
int main(void)
{
   clock_t start;
   const int cwin=-1,pwin=1;
   Chess C;
   SetChess(&C,10,18);
   start=clock();
   Printwindow(&C);
   while(1)
   {
Playermove(&C);
if(C.Flag==1)
   break;
Computermove(&C);
if(C.Flag==1)
   break;
   }
   printf("用时 %d分%d秒",((int)(clock()-start)/CLK_TCK)/60,((int)(clock()-start)/CLK_TCK)%60);
   system("pause");
   return 1;
}
//
void SetTemp(Temp *T,int x1,int y1,int n)
{
T->x=x1;
    T->y=y1;
    T->num=n;
}
/
void Initchess(Chess *C,int l,int w)
{
int i,j;
C->cnumber=0;
C->pnumber=0;
C->cwin=-1;
C->pwin=1;
C->Flag=0;
for(i=0;i<20;i++)
   for(j=0;j<20;j++)
    C->Mat[i][j]=0;
}
void Printwindow(Chess *C)
{
int i,j,k,l,m;
    system("cls");
     printf(" ");
for(j=0,l=0;j<(C->width-1)*4-12;j++,l++)//输出横行数字
     if(j!=0&&(l=l%3)==0)
{ if(j/3<10)
      printf("%d ",j/3);
   else printf("%d",j/3);
}
    else printf(" ");
printf("/n");
for(i=0,k=0;i<C->length*2+1;i++,k++)
     if((k=k%2)==0)
{ printf("   ");
   for(m=0;m<(C->width-1)*4+5;m++)
       printf("-");
         printf("/n");
}
   else
   { if(i/2+1<10)
       printf(" ");
    printf("%d ",i/2+1);
    for(j=0,l=0;j<(C->width-1)*4-12;j++,l++)
    { if((l=l%3)==0)
   printf("|");
         if(l==0||l==2) printf(" ");
          if(l==1&&i/2<C->length&&j/3<C->width)
   { if(C->Mat[i/2][j/3]==1)
      printf("X");
      if(C->Mat[i/2][j/3]==-1)
      printf("O");
      if(C->Mat[i/2][j/3]==0)
     printf(" ");
   }
    }
    printf("/n");
    }
}///
void SetChess(Chess *C,int l,int w)
{
C->length=l;
C->width=w;
C->cnumber=0;
C->pnumber=0;
Initchess(C,l,w);
}
void Checkwin(Chess *C,int flag)
{
for(int i=0;i<C->length;i++)
   for(int j=0;j<C->width;j++)
   { if((j+4<C->width)&&C->Mat[i][j]==flag&&C->Mat[i][j+1]==flag&&C->Mat[i][j+2]==flag&&C->Mat[i][j+3]==flag&&C->Mat[i][j+4]==flag)
   { if(flag==-1)
   { printf("O(∩_∩)O哈哈~,你输了,继续努力吧!/n");C->Flag=1;return;}
     if(flag==1)
{ printf("恭喜,你赢了!/n");C->Flag=1;return;}
   }
     if((i+4<C->length)&&C->Mat[i][j]==flag&&C->Mat[i+1][j]==flag&&C->Mat[i+2][j]==flag&&C->Mat[i+3][j]==flag&&C->Mat[i+4][j]==flag)
     { if(flag==-1)
{    printf("O(∩_∩)O哈哈~,你输了,继续努力吧!/n");C->Flag=1;return;}
        if(flag==1)
   { printf("恭喜,你赢了!/n");C->Flag=1;return;}
   }
     if((i+4<C->length)&&(j-4>=0)&&C->Mat[i][j]==flag&&C->Mat[i+1][j-1]==flag&&C->Mat[i+2][j-2]==flag&&C->Mat[i+3][j-3]==flag&&C->Mat[i+4][j-4]==flag)
      { if(flag==-1)
{ printf("O(∩_∩)O哈哈~,你输了,继续努力吧!/n");C->Flag=1;return;}
        if(flag==1)
   { printf("恭喜,你赢了!/n");C->Flag=1;return;}
     }
if((i+4<C->length)&&(j+4<C->width)&&C->Mat[i][j]==flag&&C->Mat[i+1][j+1]==flag&&C->Mat[i+2][j+2]==flag&&C->Mat[i+3][j+3]==flag&&C->Mat[i+4][j+4]==flag)
      { if(flag==-1)
{ printf("O(∩_∩)O哈哈~,你输了,继续努力吧!/n");C->Flag=1;return;}
        if(flag==1)
   { printf("恭喜,你赢了!/n");C->Flag=1;return;}
}
    if((C->cnumber+C->pnumber)>=C->length*C->width)
   { printf("两方平局~//(≧▽≦)/~啦啦啦!/n");C->Flag=1;return; }
   }
}
void Computermove(Chess *C)
{
Temp Tc,Tp;
int i,j;
SetTemp(&Tc,5,8,0);
SetTemp(&Tp,5,8,0);
for(i=0;i<C->length;i++)
   for(j=0;j<C->width;j++)
    if(C->Mat[i][j]==C->cwin)
     Findplace(C,i,j,&Tc,C->cwin);
    else if(C->Mat[i][j]==C->pwin)
    Findplace(C,i,j,&Tp,C->pwin);
if(Tc.num<Tp.num&&Tp.num>=3)
   Tc=Tp;
C->Mat[Tc.x][Tc.y]=C->cwin;
C->cnumber++;
Printwindow(C);
Checkwin(C,C->cwin);
}
void Playermove(Chess *C)
{
int x,y;
int flag=1;
while(flag)
{  
   printf("请输入落子位置:(如:5   5)/n位置=");
      if(scanf("%d %d",&x,&y)!=2)
   { fflush(stdin);
     Printwindow(C);
     continue;
   }
   x--;
   y--;
     if(x>=0&&y>=0&&x<C->length&&y<C->width&&C->Mat[x][y]==0)
{ C->Mat[x][y]=C->pwin;
    break;
}
     Printwindow(C);
printf("此位置 %d %d 不能下子,请重新下子!/n",++x,++y);
}
C->pnumber++;
Printwindow(C);
Checkwin(C,C->pwin);
}
void Findplace(Chess *C,int x,int y,Temp *T, int flag)
{
int i,j,num,x1,y1,cflag=-1,pflag=1,space;
if(flag==1)如果flag为1,则查找对方最大的子数目
{ cflag=1;
    pflag=-1;
}
{/// 第一个方向 右方
for(j=0,num=0,space=0;j<=6;j++)
{ if((y+j)<C->width&&C->Mat[x][y+j]==pflag)
     break;
    if((y+j)<C->width&&C->Mat[x][y+j]==cflag)
num++;
if((y+j)<C->width&&C->Mat[x][y+j-1]==cflag&&C->Mat[x][y+j]==0)
{ if(space==1)
    { break;}
   if(space==0)
   { x1=x;
     y1=y+j;
   space=1;
   if(num>T->num)
    SetTemp(T,x1,y1,num);
      }
   if((y+j+1)<C->width&&C->Mat[x][y+j+1]==0)
    break;
}
}
}
{ /第二个方向 右上方
for(i=0,j=0,num=0,space=0;i<=6;i++,j++)
{ if((x-i)>=0&&(y+j)<C->width&&C->Mat[x-i][y+j]==pflag)
     break;
    if((x-i)>=0&&(y+j)<C->width&&C->Mat[x-i][y+j]==cflag)
     num++;
if((x-i)>=0&&(y+j)<C->width&&C->Mat[x-i+1][y+j-1]==cflag&&C->Mat[x-i][y+j]==0)
{ if(space==1)
    { break;}
   if(space==0)
   { x1=x-i;
     y1=y+j;
   space=1;
   if(num>T->num)
    SetTemp(T,x1,y1,num);
   }
   if((x-i-1)>=0&&(y+j+1)<C->width&&C->Mat[x-i-1][y+j+1]==0)
    break;
}
}
}  
{///第三个方向 上方
for(i=0,num=0,space=0;i<=6;i++)
{ if((x-i)>=0&&C->Mat[x-i][y]==pflag)
     break;
    if((x-i)>=0&&C->Mat[x-i][y]==cflag)
num++;
if((x-i)>=0&&C->Mat[x-i+1][y]==cflag&&C->Mat[x-i][y]==0)
{ if(space==1)
    { break;}
   if(space==0)
   { x1=x-i;
     y1=y;
   space=1;
   if(num>T->num)
    SetTemp(T,x1,y1,num);
   }
   if((x-i-1)>=0&&C->Mat[x-i-1][y]==0)
    break;
}
}
} /
{ /第四个方向 左上方
for(i=0,j=0,num=0,space=0;i<=6;i++,j++)
{ if((x-i)>=0&&(y-j)>=0&&C->Mat[x-i][y-j]==pflag)
     break;
    if((x-i)>=0&&(y-j)>=0&&C->Mat[x-i][y-j]==cflag)
num++;
if((x-i)>=0&&(y-j)>=0&&C->Mat[x-i+1][y-j+1]==cflag&&C->Mat[x-i][y-j]==0)
{ if(space==1)
    { break;}
   if(space==0)
   { x1=x-i;
     y1=y-j;
   space=1;
   if(num>T->num)
    SetTemp(T,x1,y1,num);
   }
   if((x-i-1)>=0&&(y-j-1)>=0&&C->Mat[x-i-1][y-j-1]==0)
    break;
}
}
}
{/第五个方向 左方
for(j=0,num=0,space=0;j<=6;j++)
{ if((y-j)>=0&&C->Mat[x][y-j]==pflag)
     break;
    if((y-j)>=0&&C->Mat[x][y-j]==cflag)
num++;
if((y-j)>=0&&C->Mat[x][y-j+1]==cflag&&C->Mat[x][y-j]==0)
{ if(space==1)
    { break;}
   if(space==0)
   { x1=x;
     y1=y-j;
   space=1;
   if(num>T->num)
    SetTemp(T,x1,y1,num);
   }
   if((y-j-1)>=0&&C->Mat[x][y-j-1]==0)
    break;
}
}
}
{ /第六个方向 左下方
for(i=0,j=0,num=0,space=0;i<=6;i++,j++)
{ if((x+i)<C->length&&(y-j)>=0&&C->Mat[x+i][y-j]==pflag)
     break;
    if((x+i)<C->length&&(y-j)>=0&&C->Mat[x+i][y-j]==cflag)
num++;
if((x+i)<C->length&&(y-j)>=0&&C->Mat[x+i-1][y-j+1]==cflag&&C->Mat[x+i][y-j]==0)
{ if(space==1)
    { break;}
   if(space==0)
   { x1=x+i;
     y1=y-j;
   space=1;
   if(num>T->num)
    SetTemp(T,x1,y1,num);
   }
   if((x+i+1)<C->length&&(y-j-1)>=0&&C->Mat[x+i+1][y-j-1]==0)
    break;
}
}
}
{///第七个方向 下方
for(i=0,num=0,space=0;i<=6;i++)
{ if((x+i)<C->length&&C->Mat[x+i][y]==pflag)
     break;
    if((x+i)<C->length&&C->Mat[x+i][y]==cflag)
num++;
if((x+i)<C->length&&C->Mat[x+i-1][y]==cflag&&C->Mat[x+i][y]==0)
{ if(space==1)
    { break;}
   if(space==0)
   { x1=x+i;
     y1=y;
   space=1;
   if(num>T->num)
    SetTemp(T,x1,y1,num);
   }
   if((x+i+1)<C->length&&C->Mat[x+i+1][y]==0)
    break;
}
}
} /
{ /第八个方向 右下方
for(i=0,j=0,num=0,space=0;i<=6;i++,j++)
{ if((x+i)<C->length&&(y+j)<C->width&&C->Mat[x+i][y+j]==pflag)
     break;
    if((x+i)<C->length&&(y+j)<C->width&&C->Mat[x+i][y+j]==cflag)
num++;
if((x+i)<C->length&&(y+j)<C->width&&C->Mat[x+i-1][y+j-1]==cflag&&C->Mat[x+i][y+j]==0)
{ if(space==1)
    { break;}
   if(space==0)
   { x1=x+i;
     y1=y+j;
   space=1;
   if(num>T->num)
    SetTemp(T,x1,y1,num);
   }
   if((x+i+1)<C->length&&(y+j+1)<C->width&&C->Mat[x+i+1][y+j+1]==0)
    break;
}

}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值