馬踏棋盤代碼分析


馬踏棋盤代碼分析

                         (因為最近數據結構講到圖和網,聽是能聽懂,可是一到代碼上,就發現問題很多,因此將馬踏棋盤的代碼拿出來分析下,貌似有些不對頭,其實呢是因為不想寫其余的作業,所以找個借口)

說到馬踏棋盤,這樣說,就是一個8*8的棋盤,指定一個位置,讓馬走日字,將棋盤上的點全部走完。

   先說說思路:首先指定位置,在這個位置的基礎上走一個位置,然后再在這個基礎上走日字,現在面臨一個問題,要是走着走着,突然有一次,就那么的卡住在那里了,怎么走都不行,可是全局看下,會發現,還有空點沒有踏到,那么怎么辦?看來這條路不通了,那就得重新的找一條路,怎么從一條路到另一條路呢?那就是退回,要退回,必須有退回的路,因此呢,要有標記,不然,就找不到退回的路了,退回到另一條路,然后繼續探索,走日字,卡住了就退,哦,這里要記得將原來路也記一下,不然,你有可能重走這條不歸路。就這樣不停的走,不停地退,最終就會找到一條你想找的路。大體思路就是這樣的,思路簡單,用代碼寫起來,一定要邏輯清楚,我就是經常混在這種情況下,出不來進不去。

   恩,來看代碼:

   聲明:是MAXSIZE是100

  先定義一個8*8的棋盤:

   int board[8][8];          

  棋盤要進行初始化:N是8

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

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

         board[i][j]=0;

那么現在要輸入馬踏的位置,這就需要用戶自己輸入:記得要進行完善,要是用戶輸入的坐標不正確,要提示重新輸入:

while(1)

printf("Please enter the location of the first step of the horse(1<=x<=8 and 1<=y<=8)\n");

printf("Input x = "); 

scanf("%d",&x);         //輸入起始位置的橫坐標

printf("Input y = "); 

scanf("%d",&y);         //輸入起始位置的縱坐標

if(x>=1&&x<=8&&y>=1&&y<=8)

break;  //若輸入的坐標超出所給棋盤的允許范圍則跳出循環

printf("Your input is worng!!!\n");

}

當輸入正確后,就應該將值傳進去:調用起始坐標函數

 InitLocation(x-1,y-1)

這里就要用到棧:利用棧的特點,來記錄走過的路

棧的定義:

struct Stack

{                  

int i;                  //行坐標

int j;                  //列坐標

         int director;           //存儲方向

}stack[MAXSIZE]; 

同時定義了一個棧指針:用來記錄棧的元素進入和刪除,相當於計數器

int top=-1;              

然后是InitLocation函數

void InitLocation(int xi,int yi)

                          top++;                  //棧指針指向第一個棧的底層

                            stack[top].i=xi;           //將起始位置的橫坐標進棧

                            stack[top].j=yi;           //將起始位置的縱坐標進棧

                            stack[top].director=-1;     //將起始位置的嘗試方向賦初值

                            board[xi][yi]=top+1;       //標記棋盤

                            if(TryPath(xi,yi))            //調用馬兒探尋函數,如果馬兒探尋整個棋盤返回1否則返回0

                            Display();         //輸出馬兒的行走路徑

                            else                    

                             printf("sorry ,There is no solution");     

}

上面有兩個函數:TryPath(x,y)和Display();

 嘗試路徑:

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

//存儲馬各個出口位置相對當前位置行下標的增量數組

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

//存儲馬各個出口位置相對當前位置列下標的增量數組

int TryPath(int i,int j)

int find,director,number,min;        

int i1,j1,h,k,s;              //定義幾個臨時變量

int a[8],b1[8],b2[8],d[8];     //定義幾個臨時數組

while(top>-1)                 //棧不空時循環

for(h=0;h<8;h++)    //用數組a[8]記錄當前位置的下一個位置的可行路徑的條數

number=0; 

i=stack[top].i+Htry1[h];

j=stack[top].j+Htry2[h];

b1[h]=i;

b2[h]=j; 

if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8)    //如果找到下一位置

{

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

i1=b1[h]+Htry1[k];

               j1=b2[h]+Htry2[k]; 

           if(board[i1][j1]==0&&i1>=0&&i1<8&&j1>=0&&j1<8) //如果找到下一位置   

number++;              //記錄條數

    a[h]=number;                   //將條數存入數組a[8]中

}

for(h=0;h<8;h++)     //根據可行路徑條數小到大按下表排序放入數組d[8]中

{  

min=9; 

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

if(min>a[k]) 

min=a[k]; 

d[h]=k;    //將下表存入數組d[8]中

         s=k;

    a[s]=9;

      director=stack[top].director;     

if(top>=63)                 //如果走完整個棋盤返回

return (1); 

find=0;                     //表示沒有找到下一個位置

for(h=director+1;h<8;h++)   //向八個方向進行探尋

i=stack[top].i+Htry1[d[h]];

    j=stack[top].j+Htry2[d[h]]; 

if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8) //如果找到下一位置

find=1;       //表示找到下一個位置

break;

}

if(find==1)          //如果找到下一個位置進棧

stack[top].director=director; //存儲棧結點的方向

top++;                      //棧指針前移進棧

stack[top].i=i;

stack[top].j=j; 

stack[top].director=-1;    //重新初始化下一棧結點的嘗試方向

board[i][j]=top+1;         //標記棋盤

else                           //否則退棧

{  

board[stack[top].i][stack[top].j]=0;  //清除棋盤的標記

top--;                     //棧指針前移退棧

}

return (0);   

}

打印棋盤:board[i][j]里已經記錄了走的次序,只需輸出即可

void Display()

 

    int i,j; 

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

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

printf("\t%d  ",board[i][j]);  //輸出馬兒在棋盤上走過的路徑

printf("\n\n");

printf("\n");

}

恩恩 結束了,哦在來個運行結果截圖:

 

 

 

 

 

 

 

 

 

 

 

            by:暖暖

           20141124


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM