knight tour,C++, heuristic, 启示法骑士走棋盘

//this code is writen by c++

//this code is in cpp1.cpp

#include <algorithm>

using namespace std;

const int MaxN = 1000;  

 

int N = 0 ;   

int Knight_Square[MaxN][MaxN];  

 

 

//those two arries store the way to get the next step, for example, the next step could be (x+2,y-1)

int step_x[8] = { 2,  1, -1, -2, -2, -1, 1, 2} ;

int step_y[8] = {-1, -2, -2, -1,  1,  2,  2,  1} ;

 

typedef struct Elem{

    int hvl ;  

    int dir ;  

    bool operator < (const Elem &a) const {

        return hvl < a.hvl ;

    }

}Helem ;

 

//struck of position

typedef struct {

    int x, y ;

    int dex ;

    Helem hd[8];// store the possible next step

}Pos ;

 

//sort the reachable square according to the number of reachable square of the square

void Bubble_Sort(Helem data[]) {

    int i,j;

    Helem temp;

    for(j=0;j<7;j++) {

        for(i=0;i<7-j;i++) {

            if(data[i].hvl>=data[i+1].hvl) {

                temp = data[i];

                data[i] = data[i+1];

                data[i+1] = temp;

            }

        }

    }

}

 

// sample stack of Pos, store the tour

typedef struct STACK{   

    Pos *p_top;

    Pos base[MaxN*MaxN + 1];

    STACK() {

        p_top = base ;

    }

    void push(const Pos &a){

        (*p_top) = a ;

        ++p_top ;

    }

 

    Pos top() {

        return *(p_top - 1) ;

    }

    void pop() {

        --p_top;

    }

    bool empty(){

        return (p_top == base) ;

    }

}Stack ;

Stack S ;

 

 

//output the result

void output( int G[][MaxN], int N )

{

    int i, j;

    for (i = 0; i < N; ++i){

        for (j = 0; j < N; ++j)

        printf("%5d", G[i][j]);

        puts("\n");

    }

    puts("\n\n");

}

//check it if it on the Knight_Square

bool check(int x, int y)

{

    if (x < 0 || y < 0 || x >= N || y >= N) return false ;

    if (Knight_Square[x][y] != 0) return false ;

    return true ;

}

 

 

//caluate the number of squares that are reachable

int sum_square(int x, int y)

{

    int i;

    int tx, ty;

    int sum = 0;

    for (i = 0; i < 8; ++i){

        tx = x + step_x[i];

        ty = y + step_y[i];

        if (check( tx, ty)) ++sum ;

    }

 

    return sum ;

}

 

//set the heuristic, and sort heuristic through the number of  reachable square

void Set_Hval( Pos &k )

{

    int i ;

    int tx, ty ;

    int temp=0;

    int j=1;

   // printf("%d,%d\n",k.x,k.y);

    for(i = 0; i < 8; ++i)

    {

        k.hd[i].hvl =N*N+2;

    }

    for (i = 0; i < 8; ++i) {

        tx = k.x + step_x[i];

        ty = k.y + step_y[i];

        k.hd[i].dir = i ;

        if (check( tx, ty))// check if it on the Knight_Square

        {

//caluate the number of squares that are reachable using a single knights move, and consider it as a degree

            k.hd[i].hvl = sum_square(tx, ty);

            temp=k.hd[i].hvl;

        }

    }

 

    j=1;

//judge if it need to be sorted

    for(i = 0; i < 8; ++i)

    {

        j=j&&((k.hd[i].hvl==temp)||(k.hd[i].hvl==N*N+2));}

    

    if(j==0)

    Bubble_Sort(k.hd);//adding the next possible square with lowest degree

}

 

//judge the tour open or closed

bool open(int x, int y)

{

    int i;

    int tx, ty;

    for (i = 0; i < 8; i++)

{

        tx = x + step_x[i];

        ty = y + step_y[i];

if(Knight_Square[tx][ty]==1)

{

                return false;

}

    }

    return true;

}

 

 

//knight tour

int Knight( Pos &start )

{

    int step = 1 ;

    bool flag ;

    int flag2 = 1;

    Pos tmp, top ;

    

    while (!S.empty())  S.pop();

    

    Set_Hval(start);

    S.push(start);

    Knight_Square[start.x][start.y] = 1 ;

    

    while (!S.empty()) {

        

        top = S.top();

        flag = false;//if there is no reachable square, the flag will matain false, and return 3

        while (++top.dex < 8){

 

            tmp.x = top.x + step_x[ top.hd[top.dex].dir ];//get the nexy step

            tmp.y = top.y + step_y[ top.hd[top.dex].dir ];//get the next step

            

            if (!check(tmp.x, tmp.y)) continue; //if this step is not on the Knight_Square, go to another step.

            Knight_Square[tmp.x][tmp.y] = ++step ;

 

            flag = true ;

            tmp.dex = -1;

            Set_Hval(tmp);

            S.push(tmp);

            

            if (step == N*N)// knight tour is finished, then judge it if closed or open, if it is open return 1, else return 2

            {

                if(open(tmp.x,tmp.y))

                flag2=1;

                else

{

                flag2=2;

 

}

                return flag2;

            }

            break ;

        }

        //knight tour is failed, let all unreachable square become -1

        if (!flag) {

            for(int i=0;i<N;i++)

                for(int j=0;j<N;j++)

                     if(Knight_Square[i][j]==0)

                        Knight_Square[i][j]= -1 ;

            flag2=3;

            return  flag2;

        }

    }

    

   

    return flag2 ;

}

 

 

 

int main()

{

    Pos p ;

int judge;//use to judge open or close or no tour

    

    printf("input boards size 1 ~ %d : ", MaxN - 1);

    while (scanf("%d", &N) != EOF && N > 0 && N < MaxN)//if input the unlegal number, input again

    {

        p.dex = -1 ;

        memset(Knight_Square, 0, sizeof(Knight_Square));

        while (true) {

            printf("input X- intercept of position of start 1 ~ %d : ", N);

            scanf("%d", &p.x);

p.x--;

printf("input Y- intercept of position of start 1 ~ %d : ", N);

scanf("%d", &p.y);

p.y--;

            if (check(p.x, p.y)) break;

            puts("\n please input again ");

        }

        judge=Knight(p);

        if ( judge==1 ) {

            puts(" <<open tour>> \n");

            

        }

        

        else if ( judge==2 ) {

            puts(" <<closed tour>> \n");

            

        }

        else if(judge==3 )

            {

                puts("\n\ncannot find the tour!!\n");

 

            }

        output( Knight_Square, N );

        puts("----------------------------\n----------------------------") ;

        printf("input boards size 1 ~ %d : ", MaxN - 1);

    }

    

    

    return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值