C++隨機(jī)生成迷宮算法
本文實(shí)例為大家分享了C++隨機(jī)生成迷宮的具體代碼,供大家參考,具體內(nèi)容如下
我們今天來(lái)做一個(gè)迷宮游戲。在其中有幾個(gè)要領(lǐng):
1.方向的控制
我們建立的迷宮是以坐標(biāo)的形式出現(xiàn)的,越往上x(chóng)坐標(biāo)越小,越往左y坐標(biāo)越小,這雨平面直角坐標(biāo)系不同,要注意!
2.隨機(jī)生成算法:
void init_maze(void); //初始化迷宮 void gotoxy(int x, int y); //移動(dòng)光標(biāo) void path_up(int *x, int *y); //上構(gòu)路徑 void path_down(int *x, int *y); //下構(gòu)路徑 void path_left(int *x, int *y); //左構(gòu)路徑 void path_right(int *x, int *y); //右構(gòu)路徑 void setxy(int x, int y); //指定位打通路徑 void path_local(int x, int y); //本置路徑
這是我們需要的函數(shù),主要功能呢在代碼中有講到。如果大家自己在編程時(shí)需要自己生成迷宮,可以借鑒一下。
3.代碼
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<conio.h> #include<iostream> #include<ctime> #include <windows.h> using namespace std; #define UP 72 #define DOWN 80 #define LEFT 75 #define RIGHT 77 #define M 40 //迷宮長(zhǎng)度 #define N 82 //迷宮寬度 char maze[M/2][N/2]; //定義迷宮數(shù)組 char path[M-1][N-1]; //定義路徑數(shù)組 void setview(void); //設(shè)置控制臺(tái)窗口信息 int menu_maze(void); //主目錄 void startgame(void); //開(kāi)始游戲 void init_maze(void); //初始化迷宮 void gotoxy(int x, int y); //移動(dòng)光標(biāo) void path_up(int *x, int *y); //上構(gòu)路徑 void path_down(int *x, int *y); //下構(gòu)路徑 void path_left(int *x, int *y); //左構(gòu)路徑 void path_right(int *x, int *y); //右構(gòu)路徑 void setxy(int x, int y); //指定位打通路徑 void path_local(int x, int y); //本置路徑 void go_up(int *x,int *y); //向上移動(dòng) void go_down(int *x,int *y); //向下移動(dòng) void go_left(int *x,int *y); //向左移動(dòng) void go_right(int *x,int *y); //向右移動(dòng) void HideCursor(void); //隱藏光標(biāo) void win(void); int T; int F; int m; int n; int x; int target; int flag; int local_x; int local_y; int main() { setview(); while(1) { switch(menu_maze()) { case 49: system("cls"); startgame(); continue; case 50:exit(0); } } } void setview() { HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 獲取標(biāo)準(zhǔn)輸出設(shè)備句柄 COORD size = {N*2+167, M*2+43}; SetConsoleScreenBufferSize(hOut,size); //設(shè)置控制臺(tái)窗口緩沖區(qū)大小 SMALL_RECT rc = {0,0,167,43}; SetConsoleWindowInfo(hOut,true ,&rc); //設(shè)置窗口位置和大小 SetConsoleTitle("迷宮"); //設(shè)置窗口標(biāo)題 HideCursor(); //隱藏光標(biāo) } int menu_maze(void) { char c; while(!(c>48&&c<51)) { system("cls"); printf("\n\n\n\n\n\n\n\n"); printf(" ………………^歡迎使用DOS迷宮游戲^……………\n"); printf(" *******************************************\n"); printf(" **************** 1.開(kāi)始游戲****************\n"); printf(" **************** 2.退出游戲****************\n"); printf(" *******************************************\n"); c=getch(); } return c; } void startgame() { char key; local_x=0; local_y=0; system("cls"); init_maze(); gotoxy(2,2); printf(""); while(path[M-2][N-2]!='o') { key=getch(); if(key==-32) { key=getch(); switch(key) { case UP: if(path[local_x-1][local_y]!='t'&&path[local_x-1][local_y]!='o'||local_x-1<0) break; //路徑不通或越界 go_up(&local_x,&local_y); break; case DOWN: if(path[local_x+1][local_y]!='t'&&path[local_x+1][local_y]!='o'||local_x+1>M-2) break; go_down(&local_x,&local_y); break; case LEFT: if(path[local_x][local_y-1]!='t'&&path[local_x][local_y-1]!='o'||local_y-1<0) break; go_left(&local_x,&local_y); break; case RIGHT: if(path[local_x][local_y+1]!='t'&&path[local_x][local_y+1]!='o'||local_y+1>N-2) break; go_right(&local_x,&local_y); break; } } } system("cls"); win(); } void init_maze() { int i,j; T=1; F=1; m=0; n=0; x=0; flag=0; srand((unsigned)time(NULL)); for(i=0;i<M/2;i++) //初始化迷宮數(shù)組 { for(j=0;j<N/2;j++) maze[i][j]='f'; } for(i=0;i<M-1;i++) //初始化路徑數(shù)組 { for(j=0;j<N-1;j++) path[i][j]='f'; } path[0][0]='t'; for(i=0;i<N+1;i++) //邊框 cout<<"**"; cout<<endl; for(i=0;i<M+1;i++) { for(j=0;j<N+1;j++) { cout<<"■"; } cout<<endl; } for(i=0;i<N+1;i++) cout<<"**"; cout<<endl; while(F)//構(gòu)建迷宮 { if(T==0) { for(j=0;j<N/2;j++) { for(i=0;i<M/2;i++) { if(maze[i][j]=='f') { m=i; n=j; maze[m][n]='t'; path_local(m,n); if(maze[m-1][n]==maze[0][0]) //向上有未打通路徑 { path_up(&m,&n); m=i; n=j; flag--; break; } if(maze[m+1][n]==maze[0][0]) //向下有未打通路徑 { path_down(&m,&n); m=i; n=j; flag--; break; } if(maze[m][n-1]==maze[0][0]) //向左有未打通路徑 { path_left(&m,&n); m=i; n=j; flag--; break; } if(maze[m][n+1]==maze[0][0]) //向右有未打通路徑 { path_right(&m,&n); m=i; n=j; flag--; break; } } } if(m==i&&n==j) break; } } T=1; while(T) { x++; if(m==0&&n==0)//光標(biāo)在起始位置 { maze[m][n]='t'; path_local(m,n); switch(rand()%2) { case 0://向下 path_down(&m,&n); break; case 1://向右 path_right(&m,&n); } } if(m==M/2-1&&n==0)//光標(biāo)在左下角 { switch(rand()%2) { case 0://向上 if(maze[m-1][n]==maze[0][0]) break; //已打通路徑 path_up(&m,&n); break; case 1://向右 if(maze[m][n+1]==maze[0][0]) break; path_right(&m,&n); } } if(m==0&&n==N/2-1)//光標(biāo)在右上角 { switch(rand()%2) { case 0://向下 if(maze[m+1][n]==maze[0][0]) break; path_down(&m,&n); break; case 1://向左 if(maze[m][n-1]==maze[0][0]) break; path_left(&m,&n); break; } } if(m==M/2-1&&n==N/2-1)//光標(biāo)在右下角 { switch(rand()%2) { case 0://向上 if(maze[m-1][n]==maze[0][0]) break; path_up(&m,&n); break; case 1://向左 if(maze[m][n-1]==maze[0][0]) break; path_left(&m,&n); break; } } if(m==0&&n!=0&&n!=N/2-1)//光標(biāo)在第一行 { switch(rand()%3) { case 0://向下 if(maze[m+1][n]==maze[0][0]) break; path_down(&m,&n); break; case 1://向左 if(maze[m][n-1]==maze[0][0]) break; path_left(&m,&n); break; case 2://向右 if(maze[m][n+1]==maze[0][0]) break; path_right(&m,&n); } } if(m!=0&&m!=M/2-1&&n==0)//光標(biāo)在第一列 { switch(rand()%3) { case 0://向上 if(maze[m-1][n]==maze[0][0]) break; path_up(&m,&n); break; case 1://向下 if(maze[m+1][n]==maze[0][0]) break; path_down(&m,&n); break; case 2://向右 if(maze[m][n+1]==maze[0][0]) break; path_right(&m,&n); } } if(m==M/2-1&&n!=0&&n!=N/2-1)//光標(biāo)在最后一行 { switch(rand()%3) { case 0://向上 if(maze[m-1][n]==maze[0][0]) break; path_up(&m,&n); break; case 1://向左 if(maze[m][n-1]==maze[0][0]) break; path_left(&m,&n); break; case 2://向右 if(maze[m][n+1]==maze[0][0]) break; path_right(&m,&n); } } if(m!=0&&m!=M/2-1&&n==N/2-1)//光標(biāo)在最后一列 { switch(rand()%3) { case 0://向上 if(maze[m-1][n]==maze[0][0]) break; path_up(&m,&n); break; case 1://向下 if(maze[m+1][n]==maze[0][0]) break; path_down(&m,&n); break; case 2://向左 if(maze[m][n-1]==maze[0][0]) break; path_left(&m,&n); } } if(m!=0&&m!=M/2-1&&n!=0&&n!=N/2-1)//光標(biāo)在中間部分 { switch(rand()%4) { case 0://向上 if(maze[m-1][n]==maze[0][0]) break; path_up(&m,&n); break; case 1://向下 if(maze[m+1][n]==maze[0][0]) break; path_down(&m,&n); break; case 2://向左 if(maze[m][n-1]==maze[0][0]) break; path_left(&m,&n); break; case 3://向右 if(maze[m][n+1]==maze[0][0]) break; path_right(&m,&n); } } if(x>M*N/4) { x=0; if(m==0&&n==0&&maze[m][n+1]==maze[0][0]&&maze[m+1][n]==maze[0][0]) T=0;//初始位置死路 if(m==0&&n==N/2-1&&maze[m][n-1]==maze[0][0]&&maze[m+1][n]==maze[0][0]) T=0;//右上角死路 if(m==M/2-1&&n==0&&maze[m][n+1]==maze[0][0]&&maze[m-1][n]==maze[0][0]) T=0;//左下角死路 if(m==M/2-1&&n==N/2-1&&maze[m][n-1]==maze[0][0]&&maze[m-1][n]==maze[0][0]) T=0;//終點(diǎn)死路 if(m==0&&n!=0&&n!=N/2-1&&maze[m][n-1]==maze[0][0]&&maze[m][n+1]==maze[0][0]&&maze[m+1][n]==maze[0][0]) T=0;//第一行死路 if(m!=0&&m!=M/2-1&&n==0&&maze[m-1][n]==maze[0][0]&&maze[m][n+1]==maze[0][0]&&maze[m+1][n]==maze[0][0]) T=0;//第一列死路 if(m!=0&&m!=M/2-1&&n==N/2-1&&maze[m-1][n]==maze[0][0]&&maze[m][n-1]==maze[0][0]&&maze[m+1][n]==maze[0][0]) T=0;//最后一列死路 if(m==M/2-1&&n!=0&&n!=N/2-1&&maze[m-1][n]==maze[0][0]&&maze[m][n+1]==maze[0][0]&&maze[m][n-1]==maze[0][0]) T=0;//最后一行死路 if(m>0&&m<M/2-1&&n>0&&n<N/2-1&&maze[m+1][n]==maze[0][0]&&maze[m-1][n]==maze[0][0]&&maze[m][n+1]==maze[0][0]&&maze[m][n-1]==maze[0][0]) T=0;//中間部分死路 } } if(flag==M*N/4) F=0; } /* i=M+3; gotoxy(0,i); for(i=0;i<M-1;i++) { for(j=0;j<N-1;j++) { if(path[i][j]=='f') printf("1"); if(path[i][j]=='t') printf("0"); } printf("\n"); } getch();*/ } void gotoxy(int x, int y) { COORD pos = {x,y}; HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hOut, pos); } void path_up(int *x, int *y) { int i,j; maze[--(*x)][*y]=maze[0][0]; path[2*(*x+1)-1][2*(*y)]=path[0][0]; path_local(*x,*y); i=4*(*y)+2; j=2*(*x)+3; gotoxy(i,j); printf(" "); } void path_down(int *x, int *y) { int i,j; maze[++(*x)][*y]=maze[0][0]; path[2*(*x-1)+1][2*(*y)]=path[0][0]; path_local(*x,*y); i=4*(*y)+2; j=2*(*x)+1; gotoxy(i,j); printf(" "); } void path_left(int *x, int *y) { int i,j; maze[*x][--(*y)]=maze[0][0]; path[2*(*x)][2*(*y+1)-1]=path[0][0]; path_local(*x,*y); i=4*(*y)+4; j=2*(*x)+2; gotoxy(i,j); printf(" "); } void path_right(int *x, int *y) { int i,j; maze[*x][++(*y)]=maze[0][0]; path[2*(*x)][2*(*y-1)+1]=path[0][0]; path_local(*x,*y); i=4*(*y); j=2*(*x)+2; gotoxy(i,j); printf(" "); } void setxy(int x, int y) { gotoxy(x,y); printf(" "); } void path_local(int x, int y) { int i,j; i=4*y+2; j=2*x+2; gotoxy(i,j); printf(" "); path[2*x][2*y]=path[0][0]; flag++; } void go_up(int *x,int *y) { int i,j; i=2*(*y)+2; j=(*x)+2; gotoxy(i,j); printf(" "); j-=1; gotoxy(i,j); printf(""); (*x)--; path[*x][*y]='o'; } void go_down(int *x,int *y) { int i,j; i=2*(*y)+2; j=(*x)+2; gotoxy(i,j); printf(" "); j+=1; gotoxy(i,j); printf(""); (*x)++; path[*x][*y]='o'; } void go_left(int *x,int *y) { int i,j; i=2*(*y)+2; j=(*x)+2; gotoxy(i,j); printf(" "); i-=2; gotoxy(i,j); printf(""); (*y)--; path[*x][*y]='o'; } void go_right(int *x,int *y) { int i,j; i=2*(*y)+2; j=(*x)+2; gotoxy(i,j); printf(" "); i+=2; gotoxy(i,j); printf(""); (*y)++; path[*x][*y]='o'; } void HideCursor() { CONSOLE_CURSOR_INFO cursor_info = {1, 0}; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); } void win() { printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" " 恭喜你,成功了!"); getch(); }
怎么樣,還是蠻簡(jiǎn)單的吧?
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(12.整數(shù)轉(zhuǎn)化成羅馬數(shù)字)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(12.整數(shù)轉(zhuǎn)化成羅馬數(shù)字),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C++實(shí)現(xiàn)CreatThread函數(shù)主線程與工作線程交互的方法
這篇文章主要介紹了C++實(shí)現(xiàn)CreatThread函數(shù)主線程與工作線程交互的方法,是Windows應(yīng)用程序設(shè)計(jì)中非常實(shí)用的方法,需要的朋友可以參考下2014-10-10C++ 中const對(duì)象與const成員函數(shù)的實(shí)例詳解
這篇文章主要介紹了C++ 中const對(duì)象與const成員函數(shù)的實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能讓大家徹底掌握該如何使用,需要的朋友可以參考下2017-08-08一起來(lái)學(xué)習(xí)C語(yǔ)言的輸入和輸出
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言的輸入和輸出,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03詳解C++編程中的重載流插入運(yùn)算符和流提取運(yùn)算符
這篇文章主要介紹了詳解C++編程中的重載流插入運(yùn)算符和流提取運(yùn)算符,是C語(yǔ)言入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09C++使用cjson操作Json格式文件(創(chuàng)建、插入、解析、修改、刪除)
本文主要介紹了C++使用cjson操作Json格式文件(創(chuàng)建、插入、解析、修改、刪除),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02