基於轉角數為基準的廣度優先搜尋(樣例:連連看)
阿新 • • 發佈:2018-12-30
c++作業,設計一個簡單的連連看程式,建立一個 圖 ,然後每次輸入兩個座標,判斷是否可以消除,初次寫覺得廣搜可以完成(事實證明的確可以),但是略有些麻煩,本來想看老師的程式碼的,結果一下整個600來行的簡單模擬(八種情況,分別嘗試),太麻煩了,就查詢這方面的資料,《程式設計之美》中就對這個方面有所涉及:下面;
首先找到一個起點,起點到終點的路徑問題,中間轉角數小於3,記錄轉角;
程式碼如下,親自測試消除5-6對方塊,還沒發現什麼bug,有大佬發現歡迎指出:
#include<stdio.h> #include<string.h> #include<math.h> #include<stdlib.h> #include<time.h> //#include<map> #include<set> #include<deque> #include<queue> #include<stack> #include<string> #include<fstream> #include<iostream> #include<algorithm> using namespace std; #define ll long long #define INF 0x3f3f3f3f #define clean(a,b) memset(a,b,sizeof(a))// 水印 struct node{ int x,y; int direction,turn_num; }; void swap(int *a,int *b) { int can=*a; *a=*b; *b=can; } void build_map(int map[10][10]) { //定義一個8*8的nmap //地圖邊界0-|1-8|-9 // for(int i=0;i<10;++i) // { // for(int j=0;j<10;++j) // cout<<map[i][j]<<" "; // cout<<endl; // } for(int i=1;i<9;++i) { for(int j=1;j<9;++j) map[i][j]=i;//八組不同的圖案 對應八個不同的數字 } for(int i=0;i<100;++i)//打亂100次,從新排列 swap(map[rand()%8+1][rand()%8+1],map[rand()%8+1][rand()%8+1]); } void show_map(int map[10][10],char *img) { cout<<" "; for(int i=1;i<9;++i) cout<<i<<" "; cout<<endl<<"---------------------------"<<endl; for(int i=1;i<9;++i) { cout<<i<<"|"; for(int j=1;j<9;++j) { if(map[i][j]) cout<<" "<<img[map[i][j]]; else cout<<" "; } cout<<endl; } cout<<"---------------------------"<<endl; } input_dot(int *dot) { for(int i=0;i<4;++i) cin>>dot[i]; } int judge(int map[10][10],int dot[4]) { bool biaoji[15][15]; int fx[4]={1,-1,0,0}; int fy[4]={0,0,1,-1}; clean(biaoji,0); node str; str.x=dot[0]; str.y=dot[1]; str.direction=INF; str.turn_num=-1; queue<node> s; s.push(str); biaoji[str.x][str.y]=1;//防止自身找自身 while(s.size()) { node now=s.front(); for(int i=0;i<4;++i)//四個方向 0,1,2,3; { node can; can.x=now.x+fx[i]; can.y=now.y+fy[i]; can.direction=i; if(now.direction==INF||(now.direction+i)%2)//起點|| 轉角 can.turn_num=now.turn_num+1; else can.turn_num=now.turn_num; if(can.x<0||can.x>10||can.y<0||can.y>10)//超出地圖 continue; if(can.turn_num>2)//轉交大於2 continue; if(can.x==dot[2]&&can.y==dot[3])//符合要求的路線 return 1; if(map[can.x][can.y])//該位置有東西 continue; if(biaoji[can.x][can.y])//該位置已經走過了 continue; s.push(can); biaoji[can.x][can.y]=1; } s.pop(); } return 0; } int emtry(int map[10][10]) { for(int i=1;i<9;++i) { for(int j=1;j<9;++j) { if(map[i][j]) return 0; } } return 1; } int main() { int map[10][10];//建立一個地圖 int dot[4];//起點0,1;終點2,3; char img[9]={' ','!','@','#','$','%','&','+','~'}; clean(map,0); build_map(map); show_map(map,img); while(1) { cout<<"輸入座標x1 y1 x2 y2"<<endl; input_dot(dot); if(judge(map,dot)) { system("cls"); cout<<"clean seccess"<<endl; map[dot[0]][dot[1]]=0; map[dot[2]][dot[3]]=0; show_map(map,img); if(emtry(map)) { cout<<"winner"<<endl; exit(0); } } else { system("cls"); cout<<"clean failure"<<endl; show_map(map,img); } } }