黑白棋



#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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值