#include<graphics.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<math.h>
#include<time.h>
#include<windows.h>
#define inf 0x3f3f3f3f//定义最大值
MOUSEMSG m;
int a[15][15];//棋盘数组
int w[]={0,1,-1,0,1,-1,-1,1};
int s[]={1,0,0,-1,1,-1,1,-1};
int flag1,flag2;
int final;
int step;//标记当前下子方
int pk;
int X,Y;
int CHOOSE;//控制人机对战难度变量
int sum1,sum2;
void Show();//主界面函数
void PtoP();
void PtoC();
void Change();
void choose();
struct node
{
int ax,ay;
int total;
}Cha[66];
/*
**函数名:Search
**函数功能:寻找棋盘内可行点
**入口参数:无
**出口参数:无
*/
void Search()
{
final=0;//结构体清零
int xx,yy;//定义当前落子方变量
if(step==1)
{
xx=2;
yy=1;
}
else if(step==2)
{
xx=1;
yy=2;
}
for(int i=1;i<=8;i++)//遍历棋盘上所有点
for(int j=1;j<=8;j++)
{
if(a[i][j]==0){
int ss=0;//当前棋子可吃掉的棋子数
for(int h=0;h<8;h++)//分别向棋子八个方向寻找可吃掉的棋子
{
int nx=i,ny=j;
while(1)
{
nx+=w[h];//往当前方向前进
ny+=s[h];
if(nx>=1&&ny>=1&&nx<=8&&ny<=8)
{
if(a[nx][ny]!=xx) break;//找到第一个不是对方棋子的位置便停下
}
else break;
}
if(nx>=1&&ny>=1&&nx<=8&&ny<=8)
{
if(a[nx][ny]==yy&&(abs(i-nx)>1||abs(j-ny)>1))//判断当前方向是否可吃子
{
ss+=abs(i-nx)>abs(j-ny)?abs(i-nx):abs(j-ny);
}
}
}
if(ss>0)
{
Cha[final].ax=i;
Cha[final].ay=j;
Cha[final++].total=ss;
}
}
}
}
/*
**函数名:choose
**函数功能:选择人机对战难度
**入口参数:无
**出口参数:无
*/
void choose()
{
initgraph(900,600);//初始化图形界面
loadimage(NULL,"难度1.jpg");//加载背景图片
int flag=-1;//设置循环变量
while(1)
{
m = GetMouseMsg(); //获取鼠标坐标
switch(m.uMsg)
{
case WM_LBUTTONDOWN:
X=m.x;
Y=m.y;
for(int i=0;i<3;i++)//可删
{
if(X>=395&&X<=520&&Y>=270&&Y<=325)
{
flag=1;
CHOOSE=1;
break;
}
if(X>=395&&X<=520&&Y>=500&&Y<=555)
{
flag=1;
CHOOSE=3;
break;
}
}
if(flag!=(-1)) break;
}
if(flag!=(-1)) break;
}
}
/*
**函数名:getmouse
**函数功能:获取鼠标坐标
**入口参数:无
**出口参数:无
*/
void getmouse()
{
int flag=0;
while(1)
{
m = GetMouseMsg();
switch(m.uMsg)//对获得的鼠标坐标进行定义
{
case WM_LBUTTONDOWN:
if(m.x>=0&&m.y>=0&&m.x<=45&&m.y<=20)
{
int t;
t=MessageBox(NULL,"正在游戏中,确定关闭吗?","系统提示",MB_YESNO);
if(t==IDNO) continue;//对应的 yes or no==no
else Show();
}
X=((m.x-120)/50)+1;//将鼠标坐标换算成数组下标
Y=((m.y-120)/50)+1;
for(int i=0;i<final;i++)
{
if(Cha[i].ax==X&&Cha[i].ay==Y)//若当前点可行则推出循环
{
flag=1;
break;
}
}
if(flag==1) break;
}
if(flag==1) break;
}
}
/*
**函数名:Change
**函数功能:更新数组和棋盘信息
**入口参数:无
**出口参数:无
*/
void Change()
{
a[X][Y]=step;
int xx,yy;
if(step==1)
{
xx=2;
yy=1;
}
else if(step==2)
{
xx=1;
yy=2;
}
if(step==1) sum1++;
else sum2++;
final=0;
for(int h=0;h<8;h++)//往八个方向吃子
{
int nx=X,ny=Y;
while(1)
{
nx+=w[h];
ny+=s[h];
if(nx>=1&&ny>=1&&nx<=8&&ny<=8)
{
if(a[nx][ny]!=xx) break;
}
else break;
}
if(nx>=1&&ny>=1&&nx<=8&&ny<=8)
{
if(a[nx][ny]==yy&&(abs(X-nx)>1||abs(Y-ny)>1))//若当前方向可以吃子则进行吃子操作
{
nx=X;
ny=Y;
while(1)
{
nx+=w[h];
ny+=s[h];
if(nx>=1&&ny>=1&&nx<=8&&ny<=8)
{
if(a[nx][ny]!=xx) break;
else
{
a[nx][ny]=yy;
Cha[final].ax=nx;
Cha[final++].ay=ny;
if(step==1)
{
sum1++;
sum2--;
}
else
{
sum2++;
sum1--;
}
}
}
else break;
}
}
}
}
//更新棋盘上的棋子
for(int i=0;i<final;i++)
{
if(step==1) setcolor(WHITE);
else setcolor(BLACK);
for(int j=2;j<=20;j++) circle(120+(Cha[i].ax-1)*50+25,120+(Cha[i].ay-1)*50+25,j);
}
if(step==1) setcolor(WHITE);
else setcolor(BLACK);
for(int j=2;j<=20;j++) circle(120+(X-1)*50+25,120+(Y-1)*50+25,j);
}
/*
**函数名:Jiemian
**函数功能:画棋盘函数
**入口参数:无
**出口参数:无
*/
void Jiemian()
{
int i,j;
for(i=0;i<9;i++) line(120,120+i*50,520,120+i*50);
for(i=0;i<9;i++) line(120+i*50,120,120+i*50,520);
}
/*
**函数名:Begin
**函数功能:初始化棋盘
**入口参数:无
**出口参数:无
*/
void Begin()
{
for(int i=1;i<=8;i++)
for(int j=1;j<=8;j++)
{
if(a[i][j]==1)
{
setcolor(WHITE);
for(int h=2;h<=20;h++) circle(120+(i-1)*50+25,120+(j-1)*50+25,h);
}
else if(a[i][j]==2)
{
setcolor(BLACK);
for(int h=2;h<=20;h++) circle(120+(i-1)*50+25,120+(j-1)*50+25,h);
}
}
}
/*
**函数名:Over
**函数功能:判断输赢函数
**入口参数:无
**出口参数:无
*/
void Over()
{
int t;
//提示输赢并询问是否再来一盘
if(sum1>sum2)
{
t=MessageBox(NULL,"白棋胜!再来一局吗?","Over!",MB_YESNO);
if(t==IDNO) Show();
else
{
if(pk==2) PtoP();
else if(pk==1) PtoC();
}
}
else if(sum2>sum1)
{
t=MessageBox(NULL,"黑棋胜!再来一局吗?","Over!",MB_YESNO);
if(t==IDNO) Show();
else
{
if(pk==2) PtoP();
else if(pk==1) PtoC();
}
}
else
{
t=MessageBox(NULL,"平局!再来一局吗?","Over!",MB_YESNO);
if(t==IDNO) Show();
else
{
if(pk==2) PtoP();
else if(pk==1) PtoC();
}
}
}
/*
**函数名:PtoP
**函数功能:人人对战函数
**入口参数:无
**出口参数:无
*/
void PtoP()
{
//初始化棋盘数组和棋盘界面
char play[66];
pk=2;
initgraph(900,600);
loadimage(NULL,"对战.jpg");
Jiemian();
memset(a,0,sizeof(a));
a[4][4]=a[5][5]=1;
a[4][5]=a[5][4]=2;
sum1=sum2=2;
Begin();
step=1;
while(1)
{
//实时显示棋子数
setcolor(RED);
memset(play,'\0',sizeof(play));
sprintf(play,"%d",sum1);
outtextxy(820,212,play);
memset(play,'\0',sizeof(play));
sprintf(play,"%d",sum2);
outtextxy(820,300,play);
if(step==1)//若step为1则白棋走,否则黑棋走
{
setcolor(RED);
outtextxy(700,170,"白棋走");
Search();//寻找可行点
if(final>0)//若存在可行点
{
getmouse();//获取数组下标
Change();//更新棋盘
if(sum1+sum2==64)
{
Over();
break;
}
else
{
flag1=flag2=0;//将死棋变量全部置零
step=2;
}
}
else//若不存在可行点
{
if(flag2==1) //若上一步对方也死棋则游戏结束,判断输赢,否则将己方死棋变量赋值为1,继续循环
{
Over();
break;
}
else
{
flag1=1;
step=2;
}
}
}
setcolor(RED);
memset(play,'\0',sizeof(play));
sprintf(play,"%d",sum1);
outtextxy(820,212,play);
memset(play,'\0',sizeof(play));
sprintf(play,"%d",sum2);
outtextxy(820,300,play);
if(step==2)
{
setcolor(RED);
outtextxy(700,170,"黑棋走");
Search();
if(final>0)
{
getmouse();
Change();
if(sum1+sum2==64)
{
Over();
break;
}
else
{
flag1=flag2=0;
step=1;
}
}
else
{
if(flag1==1)
{
Over();
break;
}
else
{
flag2=1;
step=1;
}
}
}
setcolor(RED);
memset(play,'\0',sizeof(play));
sprintf(play,"%d",sum1);
outtextxy(820,212,play);
memset(play,'\0',sizeof(play));
sprintf(play,"%d",sum2);
outtextxy(820,300,play);
}
}
/*
**函数名:Getmax
**函数功能:寻找可行点最吃子最多的坐标
**入口参数:无
**出口参数:无
*/
void Getmax()
{
int max=-1;
for(int i=0;i<final;i++)
{
if(max<Cha[i].total)
{
max=Cha[i].total;
X=Cha[i].ax;
Y=Cha[i].ay;
}
}
}
/*
**函数名:Getmin
**函数功能:寻找可行点最差解坐标
**入口参数:无
**出口参数:无
*/
void Getmin()
{
int min=inf;
for(int i=0;i<final;i++)
{
if(min>Cha[i].total)
{
min=Cha[i].total;
X=Cha[i].ax;
Y=Cha[i].ay;
}
}
}
/*
**函数名:PtoC
**函数功能:人机对战函数
**入口参数:无
**出口参数:无
*/
void PtoC()
{
pk=1;
initgraph(900,600);
loadimage(NULL,"对战.jpg");
Jiemian();
memset(a,0,sizeof(a));
a[4][4]=a[5][5]=1;
a[4][5]=a[5][4]=2;
sum1=sum2=2;
Begin();
step=1;
char play[66];
while(1)
{
setcolor(RED);
memset(play,'\0',sizeof(play));
sprintf(play,"%d",sum1);
outtextxy(820,212,play);
memset(play,'\0',sizeof(play));
sprintf(play,"%d",sum2);
outtextxy(820,300,play);
if(step==1)
{
setcolor(RED);
outtextxy(700,170,"白棋走");
Search();
if(final>0)
{
getmouse();
Change();
if(sum1+sum2==64)
{
Over();
break;
}
else
{
flag1=flag2=0;
step=2;
}
}
else
{
if(flag2==1)
{
Over();
break;
}
else
{
flag1=1;
step=2;
}
}
}
setcolor(RED);
memset(play,'\0',sizeof(play));
sprintf(play,"%d",sum1);
outtextxy(820,212,play);
memset(play,'\0',sizeof(play));
sprintf(play,"%d",sum2);
outtextxy(820,300,play);
if(step==2)
{
setcolor(RED);
outtextxy(700,170,"黑棋走");
Search();
if(final>0)
{
if(CHOOSE==3) Getmax();//根据难度系数调用不同的函数来下子
else if(CHOOSE==1) Getmin();
Change();
if(sum1+sum2==64)
{
Over();
break;
}
else
{
flag1=flag2=0;
step=1;
}
}
else
{
if(flag1==1)
{
Over();
break;
}
else
{
flag2=1;
step=1;
}
}
}
setcolor(RED);
memset(play,'\0',sizeof(play));
sprintf(play,"%d",sum1);
outtextxy(820,212,play);
memset(play,'\0',sizeof(play));
sprintf(play,"%d",sum2);
outtextxy(820,300,play);
if(sum1+sum2==64)
{
Over();
break;
}
}
}
/*
**函数名:Guide
**函数功能:进入游戏规则界面
**入口参数:无
**出口参数:无
*/
void Guide()
{
initgraph(900,600);
loadimage(NULL,"规则.jpg");
while(1)
{
m = GetMouseMsg();
switch(m.uMsg)
{
case WM_LBUTTONDOWN:
X=m.x;
Y=m.y;
if(X>=0&&Y>=0&&X<=45&&Y<=20)
{
closegraph();
Show();
}
}
}
}
/*
**函数名:Show
**函数功能:进入主界面
**入口参数:无
**出口参数:无
*/
void Show()
{
initgraph(900,600);
loadimage(NULL,"界面.jpg");
int flag=-1;
while(1)
{
m = GetMouseMsg();
switch(m.uMsg)
{
case WM_LBUTTONDOWN:
X=m.x;
Y=m.y;//将坐标附给X,Y
for(int i=0;i<3;i++)
{
if(X>=300&&X<=550&&Y>=410&&Y<=475)
{
flag=1;
break;
}
if(X>=300&&X<=550&&Y>=330&&Y<=395)
{
flag=0;
break;
}
if(X>=300&&X<=550&&Y>=520&&Y<=585)
{
flag=2;
break;
}
}
if(flag!=(-1)) break;
}
if(flag!=(-1)) break;
}
if(flag==0)//根据变量不同调用不同函数
{
pk=2;
closegraph();
PtoP();
}
else if(flag==1)
{
pk=1;
closegraph();
choose();
closegraph();
PtoC();
}
else if(flag==2)
{
closegraph();
Guide();
}
}
/*
**函数名:main
**函数功能:主函数
**入口参数:无
**出口参数:无
*/
int main()
{
Show();//进入主界面
return 0;
}