Browse Source

first commit

zhuyijun 1 năm trước cách đây
commit
4d59ad4bbb
1 tập tin đã thay đổi với 476 bổ sung0 xóa
  1. 476 0
      maze.cpp

+ 476 - 0
maze.cpp

@@ -0,0 +1,476 @@
+#include <stdio.h>    //getchar()
+#include <termios.h>  //终端设置
+#include <unistd.h>   //延时函数
+
+#include <cstdlib>   //标准库
+#include <ctime>     //时间函数
+#include <iostream>  //输入输出流
+
+using namespace std;  //命名空间
+
+#define MAX_X 20
+#define MAX_Y 30
+bool flag = false;
+bool slow = false;
+bool autogame = true;
+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;
+  //清屏,如果是windows环境使用system("cls")
+  system("clear");
+  //打印地图
+  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;  //当前位置
+      //判断是否到达出口,如果到达出口则flag标记为true,下同
+      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;
+      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;
+      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;
+      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;
+    }
+  }
+}
+char getch() {
+  char ch;
+  //保存原有终端属性和新设置的终端属性
+  static struct termios oldt, newt;
+
+  //获得终端原有属性并保存在结构体oldt
+  tcgetattr(STDIN_FILENO, &oldt);
+
+  //设置新的终端属性
+  newt = oldt;
+  newt.c_lflag &= ~(ICANON);
+  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
+
+  //取消回显
+  system("stty -echo");
+  ch = getchar();
+  system("stty echo");
+
+  //让终端恢复为原有的属性
+  tcsetattr(STDIN_FILENO, TCSANOW, &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, y, '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, y, '*');
+        cout << "\n\n              成功走出" << endl;
+        return;
+      } else
+        continue;
+    }
+
+    //向右
+    if (maze[x][y + 1] == 0) {
+      s.push(x, y, '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, y, '*');
+        cout << "\n\n              成功走出" << endl;
+        return;
+      } else
+        continue;
+    }
+
+    //向上
+    if (maze[x - 1][y] == 0) {
+      s.push(x, y, '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, y, '*');
+        cout << "\n\n              成功走出" << endl;
+        return;
+      } else
+        continue;
+    }
+
+    //向左
+    if (maze[x][y - 1] == 0) {
+      s.push(x, y, '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, 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;
+    //创建地图
+    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;
+}