1. 程式人生 > 程式設計 >C++實現迷宮小遊戲

C++實現迷宮小遊戲

介紹

本程式是根據廣度優先遍歷演算法的思想設計的一款迷宮遊戲,遊戲設計了兩種模式一種自動遊戲模式,一種手動模式。因為專案在 Linux 開發,需要在 Windows 開發的,請檢視原始碼中需要修改地方的備註。

截圖

C++實現迷宮小遊戲

C++實現迷宮小遊戲

C++實現迷宮小遊戲

程式碼

#include <iostream>
#include <cstdlib>  //標準庫
#include <unistd.h>  //延時函式
#include <stdio.h>  //getchar 
#include <ctime>  
#include <termios.h> //終端設定

#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:
 //記錄迷宮座標
 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<<"記憶體分配失敗"<<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;
 }
};

//建立迷宮
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)); //隨機函式種子,以時間為引數
 for(int i=0;i<maxway;i++) //隨機構建迷宮通路
 {
 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;} //當前站立位置
 }
 cout<<endl;
 }
 if(slow){
 sleep(1);      //延時函式
 }
}

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;   //出發點 
 while(1){
 temp[x][y] = 2;

 //向下
 if(temp[x+1][y]==0){
  s.push(x,y,'D');
  temp[x][y] = 3;  //在當前位置做一個向下的標誌
  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,'R');
  temp[x][y] = 4;  //在當前位置做一個向右的標誌
  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,'U');
  temp[x][y] = 6;  //在當前位置做一個向上的標誌
  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,'L');
  temp[x][y] = 5;  //在當前位置做一個向右的標誌
  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>替代此函式
char getch(){
 char ch;  
  static struct termios oldt,newt;  //儲存原有終端屬性和新設定的終端屬性
  tcgetattr( STDIN_FILENO,&oldt);  //獲得終端原有屬性並儲存在結構體oldflag

  //設定新的終端屬性
  newt = oldt;
  newt.c_lflag &= ~(ICANON);     
  tcsetattr( STDIN_FILENO,TCSANOW,&newt);

  //取消回顯
  system("stty -echo");
  ch = getchar();
  system("stty echo");  

  tcsetattr( STDIN_FILENO,&oldt); //讓終端恢復為原有的屬性
 return ch;
}

void move(){
 int x=1,y=1;   //出發點 
 while(1){
 switch(getch()){
  case 's':
  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 '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;   //出發點 
 while(1){
 maze[x][y] = 2;

 //向下
 if(maze[x+1][y]==0){
  s.push(x,'D');
  maze[x][y] = 3;  //在當前位置做一個向下的標誌
  x = x + 1;
  maze[x][y] = 7;  //當前位置
  if(slow)
  printMaze();
  if((x==MAX_X-1)&&(y==MAX_Y-2)){
  s.push(x,'*');
  cout<<"\n\n       成功走出"<<endl;
  return;
  }
  else
  continue;
 }

 //向右
 if(maze[x][y+1]==0){
  s.push(x,'R');
  maze[x][y] = 4;  //在當前位置做一個向右的標誌
  y = y + 1;
  maze[x][y] = 7;
  if(slow)
  printMaze();
  if((x==MAX_X-1)&&(y==MAX_Y-2)){
  s.push(x,'*');
  cout<<"\n\n       成功走出"<<endl;
  return;
  }
  else
  continue;
 }

 //向上
 if(maze[x-1][y]==0){
  s.push(x,'U');
  maze[x][y] = 6;  //在當前位置做一個向上的標誌
  x = x - 1;
  maze[x][y] = 7;
  if(slow)
  printMaze();
  if((x==MAX_X-1)&&(y==MAX_Y-2)){
  s.push(x,'*');
  cout<<"\n\n       成功走出"<<endl;
  return;
  }
  else
  continue;
 }

 //向左
 if(maze[x][y-1]==0){
  s.push(x,'L');
  maze[x][y] = 5;  //在當前位置做一個向右的標誌
  y = y - 1;
  maze[x][y] = 7;
  if(slow)
  printMaze();
  if((x==MAX_X-1)&&(y==MAX_Y-2)){
  s.push(x,'*');
  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;  //定義一個棧的物件,用來記錄行走路線 
 createMaze();
 check(stack);
 system("clear");
 cout<<"\t*        loading.       *"<<endl;
 system("clear");
 cout<<"\t*        loading..       *"<<endl;
 system("clear");
 cout<<"\t*        loading...      *"<<endl;
 }
 printMaze();   //輸出當前迷宮的初始狀態
 cout<<"\n\n       輸入enter鍵繼續"<<endl;
 getchar();
 if(!autogame){
 move();
 cout<<"\n\n       輸入enter鍵繼續"<<endl;
 getchar();
 menu();
 }
 else{
 stack_of_maze stack1;  
 autoMove(stack1);   //行走中……
 } 
 printMaze();    //輸出迷宮的最終狀態
 cout<<"\n\n       輸入enter鍵繼續"<<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.自動進行       *"<<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       錯誤操作,輸入enter返回!"<<endl;
  getchar();
  menu();
 }
 getchar();
}

int main(int argc,char** argv){
 menu();
 return 0;
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。