1马的遍历


#include<string>
#include<conio.h>
#include<stdio.h>
#include <graphics.h>    // 引用 EasyX 图形库
#define MAXSIZE 100//用于马所遍历的点最大值
using namespace std;
int X,Y,mx,my,x,y,hx,hy,zcx,zcy,zxx,zyy;
wchar_t ix[10];    
wchar_t iy[10];
int flag=0;
int count=1;
char zx[1];
char zy[1];
char s[] = "马的遍历";
char t[]="马:";
char T[]="遍历结束";
int getmouse(int c);
int nn,mm;
int dir[8][2]={{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1}};  //八个方向
int nexti[8],nextj[8];
int board[10][10];
int exists[8];  //记录当前点的下一个点的出路数 
int getpoint(int hx,int hy);


typedef struct
{
    int x,y;
    
}biaoji;//马的坐标 用于自动遍历

  typedef struct
{
biaoji di[8];
   
}biao;//存储马八个方向

void initial(biao &L ){
      for(int i=0;i<8;i++){
    L.di[i].x=0;
    L.di[i].y=0;
      }
  }//初始化八个坐标坐标的方向为0
int tag(biao &L,int mx, int my){
      flag++;
     
      
      board[mx][my] =flag;
      int j,i;
      i=0;
      for(j=0;j<8;j++){
        
          if(board[mx+dir[j][0]][my+dir[j][1]]==0&&0<mx+dir[j][0]&&mx+dir[j][0]<x+1&&0<my+dir[j][1]&&my+dir[j][1]<y+1){
               i++;
                L.di[j].x=mx+dir[j][0];
                L.di[j].y=my+dir[j][1];
          }
          
        
          }
     
 if(i==0){ getpoint(0,0);return 1;}//无位置走则带入0 0结束

 return 0;

  }//标记八个反向的坐标(走过则不予标记board[x][y]数组中存走的第几次数,x,y表示其中马的坐标)

int judge(biao &L,int x,int y){
      
      for(int j=0;j<8;j++){
         
          if(L.di[j].x==x&&L.di[j].y==y)
              return 1;
             
          
  }
 
return 0;
}
      
void paint(){
       char qx[1];
       char qy[1];
       X=(x)*100+40;
       Y=(y-1)*100+40;

    
       initgraph(X,Y+50);
       setbkcolor(YELLOW);
       cleardevice();
       settextstyle(25, 0, "黑体");
       setlinestyle(PS_SOLID,2); //设置线的样式
       setlinecolor(BLACK);//设置线的颜色
       settextcolor(BLACK);//设置字体的颜色
       outtextxy((X-140)/2,0,s);//设置字体的位置
       outtextxy(X-110,10,"遍历顺序");
        
      
      
       for(int i=0;i<=((Y-40)/100);i++){
       line(20,100*i+70,X-120,100*i+70); 
       sprintf(qx,"%d",i+1);
       outtextxy(2,100*i+65,qx);
       }//滑动y轴划线

       for(int j=0;j<=((X-140)/100);j++){
       line(100*j+20,70,100*j+20,Y+30);
       sprintf(qy,"%d",j+1);
       outtextxy(100*j+15,40,qy);
       }//滑动x轴划线 
      

}//画棋盘


int getpoint(int hx,int hy){
    if(hx==0&&hy==0)    {
        outtextxy(X-110,Y,"未遍历完全");
    _getch();
    return 1;
    }    settextstyle(15, 0, "黑体");
         if(flag||count)  clearcircle(20+(zcx-1)*100,70+(zcy-1)*100,10);
         if(flag+1) outtextxy(0,0,"返回");
        count++;
          
           setfillcolor(BLACK);
           fillcircle(20+(hx-1)*100,70+(hy-1)*100,10);
           
          sprintf(zx,"%d",hx);
          sprintf(zy,"%d",hy);
          settextcolor(BLACK);//设置字体的颜色
          
          if(15*(count)+50<Y){
          outtextxy(X-110,15*(count)+50,t);//设置字体的位置
          outtextxy(X-90,15*(count)+50,zy[0]);//设置字体的位置
          outtextxy(X-75,15*(count)+50,zx[0]);//设置字体的位置
          }
    if(15*(count)+50>=Y){
          outtextxy(X-60,15*(count)+115-Y,t);//设置字体的位置
          outtextxy(X-40,15*(count)+115-Y,zy[0]);//设置字体的位置
          outtextxy(X-25,15*(count)+115-Y,zx[0]);//设置字体的位置
          }
    settextstyle(22, 0, "黑体");
    if(count==x*y){ 
        outtextxy(X-110,Y,"已完全遍历");
        _getch();
    }
    else{    
        outtextxy(X-110,Y,"正在遍历中");
    }
    
    

        Sleep(1000);
       
        
        zcx=hx;
        zcy=hy;
    return 0;     

}    //获取棋盘点的位置
    


int input1(){
    int v=0;
    initgraph(480, 480);
    setbkcolor(YELLOW);
    cleardevice();
    
    //设置字体颜色 还有测试显示字体
    settextcolor(BLACK);
    settextstyle(25, 0, "黑体");
    outtextxy(200, 50, "自动遍历");
    outtextxy(100,100, "棋盘大小");
    outtextxy(100, 180, "起始坐标");
   
    outtextxy(0, 0, "-------------------------------------");
    outtextxy(0, 300, "-------------------------------------") ;
       
    string str1,str2,str3,str4;   //头文件 string 
    //str1用来放c的总内容 str2每次存放“显示内容:”+str1,方便输出
    

    char c;  //定义字符c接收键盘输入
    while(v!=5){
        c=_getch();
       
        if (c== '\b') 
        {   v--;
          if(v<2)
               str1 = str1.substr(0, str1.size()-1);
               
           else
              str3 = str3.substr(0, str3.size() - 1);       
        }//如果c是退格符,str1删掉一个
 
        else{
        if(c!=' ')//是否是空格
              v++;

            if(v<=2){ 
                    
            str1 += (int)c; 
            
             if(v==1)
                  hx=(int)c; 
             else if(v==2)
                     hy=(int)c;
        }//判断在第几行输入 

           else{
             
            str3+=(int)c; 
            
            if(v==3)
               my=(int)c; 
             else if(v==4)
               mx=(int)c;}
       } 

    
    
    
         str2 = "棋盘大小:" + str1;
        str4 = "起始坐标:" + str3;
        cleardevice();
        outtextxy(0, 0, "------------------------------------");
       
        outtextxy(0, 300, "------------------------------------");
        outtextxy(200, 50, "自动遍历");
        
        outtextxy(100, 100, str2.c_str()); 
        outtextxy(100, 180, str4.c_str()); 
        if(v==4){
            outtextxy(0, 400, "------------按任意键进入----------");
            v++;
           _getch();
         }
        
    }closegraph();

return 0;


}

int input2(){
    int v=0;
    initgraph(480, 480);
    setbkcolor(YELLOW);
    cleardevice();
    
    //设置字体颜色 还有测试显示字体
    settextcolor(BLACK);
    settextstyle(25, 0, "黑体");
    outtextxy(200, 50, "手动遍历");
    outtextxy(100,100, "棋盘大小");
    
   
    outtextxy(0, 0, "-------------------------------------");
    outtextxy(0, 300, "-------------------------------------") ;
       
    string str1,str2;  //头文件 string 
    //str1用来放c的总内容 str2每次存放“显示内容:”+str1,方便输出
    

    char c;  //定义字符c接收键盘输入
    while(v!=3){
        c=_getch();
       
        if (c== '\b') 
        {   v--;
            str1 = str1.substr(0, str1.size()-1);
               
        }//如果c是退格符,str1删掉一个
 
        else{
          if(c!=' ')//是否是空格
              v++;
                    
            str1 += (int)c; 
            
             if(v==1)
                  hx=(int)c; 
             else
                     hy=(int)c;
        }//判断在第几行输入 

         
    
         str2 = "棋盘大小:" + str1;
       
        cleardevice();
        outtextxy(0, 0, "------------------------------------");
       
        outtextxy(0, 300, "------------------------------------");
        outtextxy(200, 50, "手动遍历");
        
        outtextxy(100, 100, str2.c_str()); 
        
        if(v==2){
            outtextxy(0, 400, "------------按任意键进入----------");
            v++;
           _getch();
         }
        
    }closegraph();

return 0;


}

int slove(int x,int y)
{
    getpoint(y,x);
    memset(board,0,sizeof(board));
    memset(exists,0,sizeof(exists));
    memset(nexti,0,sizeof(nexti));
    memset(nextj,0,sizeof(nextj));//初始化数组
    int cnt,t,minx,tmp;
    board[x][y] = 1;
    for(int i=2;i<=nn*mm;++i){

        for(int k=0;k<8;++k){
            exists[k] = 0;  //初始化出路的个数为0
        }
        t = 0;  
        for(int j=0;j<8;++j){
            int nx = x + dir[j][0];
            int ny = y + dir[j][1];
            if(nx<1||nx>nn||ny<1||ny>mm) continue;
            if(board[nx][ny] == 0){ //如果这个方向可走,则记录方向
                nexti[t] = nx;
                nextj[t] = ny;
                t++;
            }
        }
        cnt = t;  //cnt记录的是从当前点向8个方向走,可以落子的点的个数
        if(cnt == 0)  { getpoint(0,0) ;return 0    ;}  //从这一步无路可走
        
        else if(cnt == 1){  //只有一个可以走的方向,则这个方向就是最少出路的方向
             minx=0;
        }

        else{
            for(k=0;k<cnt;++k){
                for(int j=0;j<8;++j){
                    int nx = nexti[k]+dir[j][0];
                    int ny = nextj[k]+dir[j][1];
                    if(nx<1||nx>nn||ny<1||ny>mm) continue;
                    if(board[nx][ny]==0){
                        exists[k]++;  //记录下个位置的出路数据
                    }
                }
            }

            tmp = exists[0];
            minx = 0;

            for(k=1;k<cnt;++k){
                if(exists[k] < tmp){
                    tmp = exists[k];
                    minx = k;
                 }
            }
        }
        x = nexti[minx];
        y = nextj[minx];
        getpoint(y,x);    
        board[x][y] = i;
    }
    return 1;
}

int getmouse(int c){

    MOUSEMSG m; 

    switch(c){
    case 1:         
    
         while(1){
             m = GetMouseMsg();
            if(m.x>=190&&m.x<=240&&m.y>=300&&m.y<=340){
                setlinecolor(BLUE);
                  rectangle(190,300,240,340);
                   if (m.uMsg == WM_LBUTTONDOWN) {        //如果按下鼠标左键实现相应功能.
                   closegraph();
                   return 1;
            }
            }

            else if(m.x>=260&&m.x<=310&&m.y>=300&&m.y<=340){
                        setlinecolor(BLUE);
                        rectangle(260,300,310,340);
                if (m.uMsg == WM_LBUTTONDOWN) {        //如果按下鼠标左键实现相应功能.
                   exit(0);
            }
        } 
            else
             {
                setlinecolor(YELLOW);
                   rectangle(190,300,240,340);
                   rectangle(260,300,310,340);
    }
    }break;
    

    case 2:        biao L;
                initial(L);
    memset(board,0,sizeof(board));
    
        while(1){
a:              m = GetMouseMsg();
                if(m.x<40&&m.y<20&&m.uMsg == WM_LBUTTONDOWN){
                return 1;
                }
               if (m.uMsg == WM_LBUTTONDOWN&&m.x<=X-120){//如果按下鼠标左键实现相应功能.
            if(flag!=0){
                 if(!judge(L,m.x/100+1,m.y/100+1)||zxx==m.x/100+1&&zyy==m.y/100+1)goto a;
                 }
            
                 getpoint(m.x/100+1,m.y/100+1);
                 zxx=m.x/100+1;
                 zyy=m.y/100+1;
                  initial(L);
                 if(tag(L,m.x/100+1,m.y/100+1)) return 0;

                 }
             
     
        
           }break;

    case 3:
        while(1){
                m = GetMouseMsg();
             if(m.x>=110&&m.x<=360&&m.y>=150&&m.y<=220){
                         setlinecolor(BLUE);
                        rectangle(110,150,360,220);
             if (m.uMsg == WM_LBUTTONDOWN) {        //如果按下鼠标左键实现相应功能.
                    closegraph();
                    return 2;
             }
             }
             else if(m.x>=110&&m.x<=360&&m.y>=300&&m.y<=370){
                        setlinecolor(BLUE);
                        rectangle(110,300,360,370);
             if (m.uMsg == WM_LBUTTONDOWN) {        //如果按下鼠标左键实现相应功能.
                    closegraph();
                    return 1;
             }
             }
         else
        {
            setlinecolor(YELLOW);
               rectangle(110,150,360,220);
              rectangle(110,300,360,370);
        }
        }break;
    }
return 1;

}
void gameover(){

    initgraph(480, 480);
    setbkcolor(YELLOW);

    cleardevice();
    

    settextcolor(BLACK);
    settextstyle(60, 0, "黑体");
    
    outtextxy(130, 100, "游戏结束");
    settextstyle(40, 0, "黑体");
    outtextxy(160, 200, "是否继续?");
    outtextxy(190, 300, "是");
    outtextxy(260, 300, "否");
        getmouse(1);

}
int show(){
initgraph(480,480);
setbkcolor(YELLOW);
cleardevice();
settextcolor(BLACK);    
settextstyle(60, 0, "黑体");
outtextxy(110,0,"马的遍历");
settextstyle(40, 0, "黑体");
outtextxy(130,150,"手动遍历");
outtextxy(130,300,"自动遍历");
return getmouse(3);

}


int main(){  

A:   count=0;flag=0;
    switch(show()){
    case 1:input1(); x=hx-48;
        y=hy-48;
        mm=x;
        nn=y;
        mx=mx-48;
        my=my-48;
        paint();
        slove(mx,my);
        gameover();
        goto A;break;
    case 2:input2(); 
        x=hx-48;
        y=hy-48;
        paint();  
        if(getmouse(2)) goto A;
        else{gameover();
            goto A;}
 }

    
      return 1;
    
}
//需要下载easyx库

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值