C++實(shí)現(xiàn)迷宮小游戲
介紹
本程序是根據(jù)廣度優(yōu)先遍歷算法的思想設(shè)計(jì)的一款迷宮游戲,游戲設(shè)計(jì)了兩種模式一種自動(dòng)游戲模式,一種手動(dòng)模式。因?yàn)轫?xiàng)目在 Linux 開發(fā),需要在 Windows 開發(fā)的,請(qǐng)查看源代碼中需要修改地方的備注。
截圖



代碼
#include <iostream>
#include <cstdlib> //標(biāo)準(zhǔn)庫
#include <unistd.h> //延時(shí)函數(shù)
#include <stdio.h> //getchar
#include <ctime>
#include <termios.h> //終端設(shè)置
#define MAX_X 20
#define MAX_Y 30
bool flag = false;
bool slow = false;
bool autogame = true;
using namespace std;
int maze[MAX_X][MAX_Y]; //迷宮
//路線棧
class stack_of_maze{
private:
//記錄迷宮坐標(biāo)
struct node
{
int x;
int y;
char direction; //上一步路徑(如何來的)
node* next;
};
node* head;
public:
stack_of_maze(){
head = NULL;
}
~stack_of_maze(){
node* p = head;
while(head!=NULL){
head = head->next;
delete p;
p = head;
}
}
//壓棧
void push(int xx,int yy,char ddirection){
node* new_node = new node;
if(new_node!=NULL){
new_node->x = xx;
new_node->y = yy;
new_node->direction = ddirection;
new_node->next = NULL;
if(head==NULL)
head = new_node;
else{
new_node->next = head;
head = new_node;
}
}
else
cout<<"內(nèi)存分配失敗"<<endl;
}
//出棧
node* pop(int& xx,int& yy){
if(head!=NULL){
node* p = head;
head = head->next;
xx = p->x;
yy = p->y;
delete p;
}
return head;
}
void print(){
if(head!=NULL){
node* p = head;
while(p!=NULL){
cout<<" "<<p->x<<" "<<p->y<<" "<<p->direction<<endl;
p = p->next;
}
}
else
cout<<"棧為空,打印失敗"<<endl;
}
};
//創(chuàng)建迷宮
void createMaze(){
int maxway = MAX_X * MAX_Y; //最大通路
int x,y;
for(x=0;x<MAX_X;x++)
for(y=0;y<MAX_Y;y++)
maze[x][y] = 1; //先填充迷宮
srand((unsigned)time(NULL)); //隨機(jī)函數(shù)種子,以時(shí)間為參數(shù)
for(int i=0;i<maxway;i++) //隨機(jī)構(gòu)建迷宮通路
{
x = rand() % (MAX_X-2) + 1;
y = rand() % (MAX_Y-2) + 1;
maze[x][y] = 0;
}
maze[1][1] = 0; //入口
maze[MAX_X-2][MAX_Y-2] = 0; //出口
maze[0][1] = 3;
maze[MAX_X-1][MAX_Y-2] = 0;
}
//輸出迷宮
void printMaze(){
int x,y;
system("clear"); //windows下使用system("cls")
//cout<<endl;
for(x=0;x<MAX_X;x++)
{
for(y=0;y<MAX_Y;y++)
{
if(maze[x][y]==0){cout<<" ";continue;} //通路
if(maze[x][y]==1){cout<<"■";continue;} //墻
if(maze[x][y]==2){cout<<"×";continue;} //死胡同
if(maze[x][y]==3){cout<<"↓";continue;} //向下走
if(maze[x][y]==4){cout<<"→";continue;}
if(maze[x][y]==5){cout<<"←";continue;}
if(maze[x][y]==6){cout<<"↑";continue;}
if(maze[x][y]==7){cout<<"※";continue;} //當(dāng)前站立位置
}
cout<<endl;
}
if(slow){
sleep(1); //延時(shí)函數(shù)
}
}
void check(stack_of_maze &s){
int temp[MAX_X][MAX_Y];
for(int x=0;x<MAX_X;x++)
for(int y=0;y<MAX_Y;y++)
temp[x][y] = maze[x][y];
int x=1,y=1; //出發(fā)點(diǎn)
while(1){
temp[x][y] = 2;
//向下
if(temp[x+1][y]==0){
s.push(x,y,'D');
temp[x][y] = 3; //在當(dāng)前位置做一個(gè)向下的標(biāo)志
x = x + 1;
temp[x][y] = 7; //當(dāng)前位置
if((x==MAX_X-1)&&(y==MAX_Y-2)){
flag = true;
return;
}
else
continue;
}
//向右
if(temp[x][y+1]==0){
s.push(x,y,'R');
temp[x][y] = 4; //在當(dāng)前位置做一個(gè)向右的標(biāo)志
y = y + 1;
temp[x][y] = 7;
if((x==MAX_X-1)&&(y==MAX_Y-2)){
flag = true;
return;
}
else
continue;
}
//向上
if(temp[x-1][y]==0){
s.push(x,y,'U');
temp[x][y] = 6; //在當(dāng)前位置做一個(gè)向上的標(biāo)志
x = x - 1;
temp[x][y] = 7;
if((x==MAX_X-1)&&(y==MAX_Y-2)){
flag = true;
return;
}
else
continue;
}
//向左
if(temp[x][y-1]==0){
s.push(x,y,'L');
temp[x][y] = 5; //在當(dāng)前位置做一個(gè)向右的標(biāo)志
y = y - 1;
temp[x][y] = 7;
if((x==MAX_X-1)&&(y==MAX_Y-2)){
flag = true;
return;
}
else
continue;
}
//上下左右不通,則回退
if(s.pop(x,y)==NULL && temp[x-1][y]!=0 && temp[x][y-1]!=0 && temp[x][y+1]!=0 && temp[x+1][y]!=0){
temp[0][1] = 7;
if(temp[1][1]!=1)
temp[1][1] = 2;
return;
}
}
}
//輸入,windows下可以使用#incldue<conio.h>替代此函數(shù)
char getch(){
char ch;
static struct termios oldt, newt; //保存原有終端屬性和新設(shè)置的終端屬性
tcgetattr( STDIN_FILENO, &oldt); //獲得終端原有屬性并保存在結(jié)構(gòu)體oldflag
//設(shè)置新的終端屬性
newt = oldt;
newt.c_lflag &= ~(ICANON);
tcsetattr( STDIN_FILENO, TCSANOW, &newt);
//取消回顯
system("stty -echo");
ch = getchar();
system("stty echo");
tcsetattr( STDIN_FILENO, TCSANOW, &oldt); //讓終端恢復(fù)為原有的屬性
return ch;
}
void move(){
int x=1,y=1; //出發(fā)點(diǎn)
while(1){
switch(getch()){
case 's':
if(maze[x+1][y]==0){
maze[x][y] = 0;
x = x + 1;
maze[x][y] = 7; //當(dāng)前位置
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
cout<<"\n\n 成功走出"<<endl;
return;
}
}
break;
case 'd':
if(maze[x][y+1]==0){
if(maze[x][y+1]==0){
maze[x][y] = 0;
y = y + 1;
maze[x][y] = 7;
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
cout<<"\n\n 成功走出"<<endl;
return;
}
}
}
break;
case 'w':
if(maze[x-1][y]==0){
maze[x][y] = 0;
x = x - 1;
maze[x][y] = 7;
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
cout<<"\n\n 成功走出"<<endl;
return;
}
}
break;
case 'a':
if(maze[x][y-1]==0){
maze[x][y] = 0;
y = y - 1;
maze[x][y] = 7;
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
cout<<"\n\n 成功走出"<<endl;
return;
}
}
break;
}
}
}
void autoMove(stack_of_maze &s){
int x=1,y=1; //出發(fā)點(diǎn)
while(1){
maze[x][y] = 2;
//向下
if(maze[x+1][y]==0){
s.push(x,y,'D');
maze[x][y] = 3; //在當(dāng)前位置做一個(gè)向下的標(biāo)志
x = x + 1;
maze[x][y] = 7; //當(dāng)前位置
if(slow)
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
s.push(x,y,'*');
cout<<"\n\n 成功走出"<<endl;
return;
}
else
continue;
}
//向右
if(maze[x][y+1]==0){
s.push(x,y,'R');
maze[x][y] = 4; //在當(dāng)前位置做一個(gè)向右的標(biāo)志
y = y + 1;
maze[x][y] = 7;
if(slow)
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
s.push(x,y,'*');
cout<<"\n\n 成功走出"<<endl;
return;
}
else
continue;
}
//向上
if(maze[x-1][y]==0){
s.push(x,y,'U');
maze[x][y] = 6; //在當(dāng)前位置做一個(gè)向上的標(biāo)志
x = x - 1;
maze[x][y] = 7;
if(slow)
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
s.push(x,y,'*');
cout<<"\n\n 成功走出"<<endl;
return;
}
else
continue;
}
//向左
if(maze[x][y-1]==0){
s.push(x,y,'L');
maze[x][y] = 5; //在當(dāng)前位置做一個(gè)向右的標(biāo)志
y = y - 1;
maze[x][y] = 7;
if(slow)
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
s.push(x,y,'*');
cout<<"\n\n 成功走出"<<endl;
return;
}
else
continue;
}
//上下左右不通,則回退
if(s.pop(x,y)==NULL && maze[x-1][y]!=0 && maze[x][y-1]!=0 && maze[x][y+1]!=0 && maze[x+1][y]!=0){
cout<<"\n\n 沒有找到合適的路徑"<<endl;
maze[0][1] = 7;
if(maze[1][1]!=1)
maze[1][1] = 2;
return;
}
}
}
void menu();
void gamestart(){
flag = false;
while(!flag){
stack_of_maze stack; //定義一個(gè)棧的對(duì)象,用來記錄行走路線
createMaze();
check(stack);
system("clear");
cout<<"\t* loading. *"<<endl;
system("clear");
cout<<"\t* loading.. *"<<endl;
system("clear");
cout<<"\t* loading... *"<<endl;
}
printMaze(); //輸出當(dāng)前迷宮的初始狀態(tài)
cout<<"\n\n 輸入enter鍵繼續(xù)"<<endl;
getchar();
if(!autogame){
move();
cout<<"\n\n 輸入enter鍵繼續(xù)"<<endl;
getchar();
menu();
}
else{
stack_of_maze stack1;
autoMove(stack1); //行走中……
}
printMaze(); //輸出迷宮的最終狀態(tài)
cout<<"\n\n 輸入enter鍵繼續(xù)"<<endl;
getchar();
menu();
}
void menu(){
system("clear");
int num;
cout<<"\t****************************************"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t* 1.查看路徑 *"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t* 2.自動(dòng)進(jìn)行 *"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t* 3.自行游戲 *"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t* 4.退出游戲 *"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t****************************************"<<endl;
slow = false;
switch(getch()){
case '1':
autogame = true;
gamestart();break;
case '2':
autogame = true;
slow = true;
gamestart();
break;
case '3':
autogame = false;
gamestart();
break;
case '4':
exit(1);break;
default:
cout<<"\n\n 錯(cuò)誤操作,輸入enter返回!"<<endl;
getchar();
menu();
}
getchar();
}
int main(int argc,char** argv){
menu();
return 0;
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用C++實(shí)現(xiàn)MySQL數(shù)據(jù)庫連接池
這篇文章主要為大家詳細(xì)介紹了如何使用C++實(shí)現(xiàn)MySQL數(shù)據(jù)庫連接池,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以了解下2024-03-03
C++?opencv學(xué)習(xí)之圖像像素的邏輯操作
圖像的像素操作包括讀寫操作、算數(shù)操作、邏輯運(yùn)算操作等,下面這篇文章主要給大家介紹了關(guān)于C++?opencv學(xué)習(xí)之圖像像素的邏輯操作的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11
如何將編譯過的C++庫迅速部署在Visual?Studio新項(xiàng)目中
本文介紹在Visual?Studio中,通過屬性表,使得一個(gè)新建解決方案中的項(xiàng)目可以快速配置已有解決方案的項(xiàng)目中各類已編譯好的C++第三方庫的方法,感興趣的朋友跟隨小編一起看看吧2024-05-05
詳解vs2022創(chuàng)建及調(diào)用.lib的方法
這篇文章主要介紹了vs2022創(chuàng)建及調(diào)用.lib的方法,調(diào)用Lib的原則就是可以讓編譯器找到頭文件和庫文件的目錄,并正確引入,本文給大家詳細(xì)講解需要的朋友可以參考下2022-11-11
C語言運(yùn)用回調(diào)函數(shù)實(shí)現(xiàn)計(jì)算器
這篇文章主要為大家詳細(xì)介紹了C語言運(yùn)用回調(diào)函數(shù)實(shí)現(xiàn)計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
C語言中隨機(jī)數(shù)rand()函數(shù)詳解
大家好,本篇文章主要講的是C語言中隨機(jī)數(shù)rand()函數(shù)詳解,感興趣的同學(xué)感快來看一看吧,對(duì)你有幫助的話記得收藏一下2022-02-02
VScode配置cuda開發(fā)環(huán)境的實(shí)現(xiàn)步驟
本文主要介紹了VScode配置cuda開發(fā)環(huán)境的實(shí)現(xiàn)步驟,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07
C++課程設(shè)計(jì)之圖書館管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++課程設(shè)計(jì)之圖書館管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03

