Knight's Shortest Path on Chessboard

后端 未结 16 1288
情深已故
情深已故 2020-11-30 16:42

I\'ve been practicing for an upcoming programming competition and I have stumbled across a question that I am just completely bewildered at. However, I feel as though it\'s

16条回答
  •  失恋的感觉
    2020-11-30 17:01

    /*
    This program takes two sets of cordinates on a 8*8 chessboard, representing the
    starting and ending points of a knight's path.
    The problem is to print the cordinates that the knight traverses in between, following
    the shortest path it can take.
    Normally this program is to be implemented using the Djikstra's algorithm(using graphs)
    but can also be implemented using the array method.
    NOTE:Between 2 points there may be more than one shortest path. This program prints
    only one of them.
    */
    
    #include
    
    #include
    
    #include
    
    int m1=0,m2=0;
    
    /*
    This array contains three columns and 37 rows:
    The rows signify the possible coordinate differences.
    The columns 1 and 2 contains the possible permutations of the row and column difference 
    between two positions on a chess board;
    The column 3 contains the minimum number of steps involved in traversing the knight's 
    path with the given permutation*/
    
    int arr[37][3]={{0,0,0},{0,1,3},{0,2,2},{0,3,3},{0,4,2},{0,5,3},{0,6,4},{0,7,5},    {1,1,2},{1,2,1},{1,3,2},{1,4,3},{1,5,4},{1,6,3},{1,7,4},{2,2,4},{2,3,3},{2,4,2},
                {2,5,3},{2,6,3},{2,7,5},{3,3,2},{3,4,3},{3,5,4},{3,6,3},{3,7,4},{4,4,4},{4,5,3},{4,6,4},{4,7,5},{5,5,4},{5,6,5},{5,7,4},{6,6,5},{6,7,5},{7,7,6}};
    
    void printMoves(int,int,int,int,int,int);
    void futrLegalMove(int,int,int,int);
    main()
    {
      printf("KNIGHT'S SHORTEST PATH ON A 8*8 CHESSBOARD :\n");
      printf("------------------------------------------");
      printf("\nThe chessboard may be treated as a 8*8 array here i.e. the (1,1) ");
      printf("\non chessboard is to be referred as (0,0) here and same for (8,8) ");
      printf("\nwhich is to be referred as (7,7) and likewise.\n");
      int ix,iy,fx,fy;
      printf("\nEnter the initial position of the knight :\n");
      scanf("%d%d",&ix,&iy);
      printf("\nEnter the final position to be reached :\n");
      scanf("%d%d",&fx,&fy);
      int px=ix,py=iy;
      int temp;
      int tx,ty;
      printf("\nThe Knight's shortest path is given by :\n\n");
      printf("(%d, %d)",ix,iy);
      futrLegalMove(px,py,m1,m2);
      printMoves(px,py,fx,fy,m1,m2);
       getch();
    } 
    
    /*
      This method checkSteps() checks the minimum number of steps involved from current
      position(a & b) to final position(c & d) by looking up in the array arr[][].
    */
    
    int checkSteps(int a,int b,int c,int d)
    {  
        int xdiff, ydiff;
        int i, j;
        if(c>a)
            xdiff=c-a;
        else
            xdiff=a-c;
        if(d>b)
            ydiff=d-b;
        else
            ydiff=b-d;
        for(i=0;i<37;i++)
            {
                if(((xdiff==arr[i][0])&&(ydiff==arr[i][1])) || ((xdiff==arr[i][1])&& (ydiff==arr[i] [0])))
                {
                    j=arr[i][2];break;
                }
            }
    
            return j;
    }   
    
    /*
    This method printMoves() prints all the moves involved.
    */
    
    void printMoves(int px,int py, int fx, int fy,int a,int b)
    {    
     int temp;
     int tx,ty;
     int t1,t2;
      while(!((px==fx) && (py==fy)))
      {   
          printf(" --> ");
          temp=checkSteps(px+a,py+b,fx,fy);
          tx=px+a;
          ty=py+b;
          if(!(a==2 && b==1))
          {if((checkSteps(px+2,py+1,fx,fy)7 || b>7 || a<0 || b<0)
            return 0;
        else
            return 1;
    }
    
    /*Out of the 8 possible moves, this function futrLegalMove() sets the valid move by
      applying the following constraints
          1. The next move should not be beyond the scope of the board.
          2. The next move should not be the exact opposite of the previous move.
      The 1st constraint is checked by sending all possible moves to the checkMove() 
      method;
      The 2nd constraint is checked by passing as parameters(i.e. a and b) the steps of the 
      previous move and checking whether or not it is the exact opposite of the current move.
    */
    
    void futrLegalMove(int px,int py,int a,int b)
    {
         if(checkMove(px+2,py+1) && (a!=-2 && b!=-1))
             m1=2,m2=1;
         else
         {
             if(checkMove(px+2,py-1)&& (a!=-2 && b!=1))
                 m1=2,m2=-1;
         else
         {
             if(checkMove(px-2,py+1)&& (a!=2 && b!=-1))
                  m1=-2,m2=1;
         else
         {
             if(checkMove(px-2,py-1)&& (a!=2 && b!=1))
                   m1=-2,m2=-1;
         else
         {
             if(checkMove(px+1,py+2)&& (b!=-2 && a!=-1))
                   m2=2,m1=1;
         else
         {
             if(checkMove(px+1,py-2)&& (a!=-1 && b!=2))
                   m2=-2,m1=1;
         else
         {
             if(checkMove(px-1,py+2)&& (a!=1 && b!=-2))
                   m2=2,m1=-1;
         else
         {
             if(checkMove(px-1,py-2)&& (a!=1 && b!=2))
                   m2=-2,m1=-1;
         }}}}}}}
    }
    
    //End of Program.
    

    I haven't studied graphs yet..as per the problem of implementing it through simply arrays, I could not derive any solution other than this. I treated the positions not as ranks and files(The usual chess notation), but as array indices. FYI, this is for a 8*8 chessboard only. Any improvement advice is always welcomed.

    *The comments should suffice for your understanding of the logic. However, you may always ask.

    *Checked on DEV-C++ 4.9.9.2 compiler(Bloodshed Software).

提交回复
热议问题