由于原来那个五子棋算法有点缺陷,导致电脑有点笨笨,经过优化后好多了,以下是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;
}
}
}
}