关键字:数据结构,迷宫求解,栈
代码清单:
- main.cpp
- typedef.h
- Stack.h
- Stack.cpp
- Maze.h
- Maze.cpp
Windows7 64位下 Code::Blocks12.11 GCC 编译运行通过。
原文地址:http://www.cnblogs.com/fengzy/archive/2013/06/01/3113089.html
欢迎交流学习,转载请注明出处。如有问题,请留言。
下面是源代码。
- main.cpp
1 /*-- main.cpp ---------------------------------*/ 2 3 #include <iostream> 4 #include <cassert> 5 6 #include "Maze.h" 7 8 using namespace std; 9 10 int main() 11 { 12 Maze maze; 13 14 maze.init(); 15 maze.display(); 16 maze.getPath(); 17 maze.display(); 18 19 return 0; 20 }
- typedef.h
1 /*-- typedef.h -------------------------------------------------------------- 2 这个头文件定义了程序所用的一些数据类型 3 4 数据类型: 5 PosType: 迷宫中的位置 6 Direction: 走步的方向 7 ElemType: 栈元素类型 8 --------------------------------------------------------------------------*/ 9 10 #ifndef TYPEDEF_H_INCLUDED 11 #define TYPEDEF_H_INCLUDED 12 13 typedef struct 14 { 15 int r; 16 int c; 17 } PosType; // loctation in the maze 18 19 enum Direction 20 { 21 NORTH = 2, 22 WEST = 4, 23 EAST = 6, 24 SOUTH = 8 25 }; 26 27 struct ElemType 28 { 29 int step; 30 PosType seat; 31 int direction; 32 33 ElemType(int s=1, int r=1, int c=1, int d=2) 34 { 35 step = s; 36 seat.r = r; 37 seat.c = c; 38 direction = d; 39 } 40 }; 41 42 #endif // TYPEDEF_H_INCLUDED
- Stack.h
1 /*-- Stack.h -------------------------------------------------------------- 2 3 这个头文件定义了一个 Stack 类 4 基本操作: 5 构造函数: 创建一个空栈 6 empty: 检查栈是否为空 7 push: 通过在栈顶添加一个元素来修改栈 8 top: 取出栈顶元素,并且保持栈不被修改 9 pop: 通过删除栈顶的元素来修改栈 10 display: 显示栈中所有元素 11 clear: 清空栈 12 Note: Execution terminates if memory isn't available for a stack element. 13 --------------------------------------------------------------------------*/ 14 15 #include <iostream> 16 using namespace std; 17 18 #ifndef STACK_H 19 #define STACK_H 20 21 #include "typedef.h" 22 23 class Stack 24 { 25 public: 26 /***** Function Members *****/ 27 /***** Constructors *****/ 28 Stack(); 29 Stack(const Stack &original); 30 //-- 赋值构造函数 31 32 /***** Destructor *****/ 33 ~Stack(); 34 35 /***** Assignment *****/ 36 const Stack &operator= (const Stack &rightHandSide); 37 bool empty() const; 38 void push(const ElemType &value); 39 //void display(ostream &out) const; 40 ElemType top() const; 41 void pop(); 42 void clear(); 43 44 private: 45 /*** Node class ***/ 46 class Node 47 { 48 public: 49 ElemType data; 50 Node *next; 51 //--- Node constructor 52 Node(ElemType value, Node *link = 0) 53 : data(value), next(link) 54 {} 55 }; 56 57 typedef Node *NodePointer; 58 59 /***** Data Members *****/ 60 NodePointer myTop; // pointer to top of stack 61 62 }; // end of class declaration 63 64 #endif // STACK_H
- Stack.cpp
1 /*-- Stack.cpp ---------------------------------------*/ 2 3 #include "Stack.h" 4 5 //--- Definition of Stack constructor 6 Stack::Stack() 7 : myTop(0) 8 {} 9 10 //--- Definition of Stack copy constructor 11 Stack::Stack(const Stack &original) 12 { 13 myTop = 0; 14 15 if (!original.empty()) 16 { 17 // Copy first node 18 myTop = new Stack::Node(original.top()); 19 20 // Set pointers to run through the stacks?linked lists 21 Stack::NodePointer lastPtr = myTop, 22 origPtr = original.myTop->next; 23 24 while (origPtr != 0) 25 { 26 lastPtr->next = new Stack::Node(origPtr->data); 27 lastPtr = lastPtr->next; 28 origPtr = origPtr->next; 29 } 30 } 31 } 32 33 //--- Definition of Stack destructor 34 Stack::~Stack() 35 { 36 // Set pointers to run through the stack 37 Stack::NodePointer currPtr = myTop, // node to be deallocated 38 nextPtr; // its successor 39 40 while (currPtr != 0) 41 { 42 nextPtr = currPtr->next; 43 delete currPtr; 44 currPtr = nextPtr; 45 } 46 } 47 48 //--- Definition of assignment operator 49 const Stack &Stack::operator=(const Stack &rightHandSide) 50 { 51 if (this != &rightHandSide) // check that not st = st 52 { 53 this->~Stack(); // destroy current linked list 54 55 if (rightHandSide.empty()) // empty stack 56 myTop = 0; 57 else 58 { // copy rightHandSide's list 59 // Copy first node 60 myTop = new Stack::Node(rightHandSide.top()); 61 62 // Set pointers to run through the stacks' linked lists 63 Stack::NodePointer lastPtr = myTop, 64 rhsPtr = rightHandSide.myTop->next; 65 66 while (rhsPtr != 0) 67 { 68 lastPtr->next = new Stack::Node(rhsPtr->data); 69 lastPtr = lastPtr->next; 70 rhsPtr = rhsPtr->next; 71 } 72 } 73 } 74 75 return *this; 76 } 77 78 //--- Definition of empty() 79 bool Stack::empty() const 80 { 81 return (myTop == 0); 82 } 83 84 //--- Definition of push() 85 void Stack::push(const ElemType &value) 86 { 87 myTop = new Stack::Node(value, myTop); 88 } 89 90 //--- Definition of display() 91 /*void Stack::display(ostream & out) const 92 { 93 Stack::NodePointer ptr; 94 for (ptr = myTop; ptr != 0; ptr = ptr->next) 95 out << ptr->data << endl; 96 }*/ 97 98 //--- Definition of top() 99 ElemType Stack::top() const 100 { 101 if (!empty()) 102 return (myTop->data); 103 else 104 { 105 cerr << "*** Stack is empty " 106 " -- returning garbage ***\n"; 107 ElemType *temp = new ElemType(); 108 ElemType garbage = *temp; // "Garbage" value 109 delete temp; 110 return garbage; 111 } 112 } 113 114 //--- Definition of pop() 115 void Stack::pop() 116 { 117 if (!empty()) 118 { 119 Stack::NodePointer ptr = myTop; 120 myTop = myTop->next; 121 delete ptr; 122 } 123 else 124 cerr << "*** Stack is empty -- can't remove a value ***\n"; 125 } 126 127 void Stack::clear() 128 { 129 while(!empty()) 130 pop(); 131 }
- Maze.h
1 /*-- Maze.h -------------------------------------------------------------- 2 这个头文件一个 Maze 类 3 4 成员函数: 5 init 初始化迷宫 6 getPath: 迷宫求解 7 display: 输出迷宫 8 pass: 判断该点是否可以通过 9 --------------------------------------------------------------------------*/ 10 #ifndef MAZE_H 11 #define MAZE_H 12 13 #include <iostream> 14 #include <string> 15 #include "Stack.h" 16 17 using namespace std; 18 19 20 class Maze 21 { 22 public: 23 /** Default constructor */ 24 Maze(); 25 26 void init(); 27 void display() const; 28 void getPath(); // 迷宫求解 29 30 /** Default destructor */ 31 virtual ~Maze(); 32 33 private: 34 bool pass(PosType); 35 ElemType getNext(const PosType curPos); // 根据当前坐标寻找下一位置。 36 37 protected: 38 39 private: 40 int r; 41 int c; 42 int **m; 43 PosType entra; 44 PosType exi; 45 Stack s; 46 47 }; 48 49 #endif // MAZE_H
- Maze.cpp
1 /*-- Maze.cpp -------------------------------------------------------*/ 2 #include <cassert> 3 #include <stdlib.h> 4 #include <ctime> 5 #include "Maze.h" 6 7 #define random(x) (rand()%(x)) 8 9 using namespace std; 10 11 string p[] = 12 { 13 " ", // 0,通路 14 "■", // 1,障碍或围墙 15 "↑", // 2,北 16 "○", // 3,入口 17 "←", // 4,西 18 "★", // 5,出口 19 "→", // 6,东 20 "※", // 7,死胡同 21 "↓" // 8,南 22 }; // 用于打印迷宫 23 24 25 Maze::Maze() 26 { 27 //ctor 28 } 29 30 void Maze::init() 31 { 32 cout << "Size of maze: "; 33 cin >> r >> c; 34 35 assert(r > 0 && c > 0); 36 37 /*---------- 分配数组------------*/ 38 m = new int*[r + 2]; 39 40 for (int i = 0; i < r + 2 ; i++ ) 41 m[i] = new int[c + 2]; 42 43 /*---------- “画” 围墙 -------------------------------- 44 障碍或围墙用 1 表示,通路用 0 表示 45 ----------------------------------------------------*/ 46 for (int i = 0; i < r + 2 ; i++) 47 { 48 m[i][0] = 1; 49 m[i][c + 1] = 1; 50 } 51 52 for (int i = 0; i < c + 2 ; i++) 53 { 54 m[0][i] = 1; 55 m[r + 1][i] = 1; 56 } 57 58 /*---------- 输入迷宫数据------------*/ 59 bool autoMaze = false; // 自动生成迷宫 60 cout << "Auto maze?(0/1) "; 61 cin >> autoMaze; 62 63 if (autoMaze) 64 { 65 for (int i = 1; i < r + 1 ; i++ ) 66 { 67 for (int j = 1; j < c + 1 ; j++ ) 68 { 69 srand((int)time(0) + i * j * 2); 70 71 if (random(20) > 4) m[i][j] = 0; 72 else m[i][j] = 1; 73 } 74 } 75 76 display(); 77 } 78 else 79 { 80 for (int i = 1; i < r + 1 ; i++ ) 81 { 82 cout << "row " << i << ": "; 83 84 for (int j = 1; j < c + 1 ; j++ ) 85 cin >> m[i][j]; 86 } 87 } 88 89 /*---------- 设置迷宫入口和出口 ------------*/ 90 int tempR, tempC; 91 cout << "ENTRANCE: "; 92 cin >> tempR >> tempC; 93 assert((tempR == 1 || tempR == r || tempC == 1 || tempC == c) && 94 (tempR > 0 && tempR <= r && tempC > 0 && tempC <= c)); 95 m[tempR][tempC] = 3; // 入口用 3 表示 96 entra.r = tempR; 97 entra.c = tempC; 98 99 cout << "EXIT: "; 100 cin >> tempR >> tempC; 101 assert((tempR == 1 || tempR == r || tempC == 1 || tempC == c) && 102 (tempR > 0 && tempR <= r && tempC > 0 && tempC <= c)); 103 m[tempR][tempC] = 5; // 出口用 5 表示 104 exi.r = tempR; 105 exi.c = tempC; 106 107 assert(entra.r != exi.r || entra.c != exi.c); // 限定入口与出口不可相同 108 } 109 110 void Maze::display() const 111 { 112 for (int i = 0; i < r + 2 ; i++ ) 113 { 114 for (int j = 0; j < c + 2 ; j++ ) 115 cout << p[m[i][j]]; 116 117 cout << "\n"; 118 } 119 120 cout << "\n"; 121 } 122 123 void Maze::getPath() 124 { 125 if (!s.empty()) 126 s.clear(); 127 128 PosType curPos = entra; 129 int step = 0; 130 bool found = false; 131 s.push(ElemType(step, curPos.r, curPos.c, 3)); // 首先将入口压栈 132 133 ElemType tempElem; 134 135 bool viewEachStep = false; 136 cout << "View each step?(0/1) "; 137 cin >> viewEachStep; 138 139 do { 140 if (viewEachStep) 141 { 142 system("pause"); 143 cout << "---------- step " << step 144 << " ----------\n"; 145 display(); 146 } 147 148 tempElem = getNext(s.top().seat); // 根据栈顶位置找下一个步 149 150 if (m[tempElem.seat.r][tempElem.seat.c] == 5) 151 found = true; // 找到的下一位置是出口 152 else 153 { // 不是出口 154 if (tempElem.direction) 155 { // 有下一步可走 156 tempElem.step = ++step; 157 s.push(tempElem); // 将下一步位置压栈 158 } 159 else 160 { // 找不到下一位置 161 step--; 162 163 if (s.top().direction != 3) 164 m[s.top().seat.r][s.top().seat.c] = 7; // 当前栈顶是死胡同 165 166 s.pop(); // 在路径中删除当前位置 167 } 168 } 169 } while (!s.empty() && !found); 170 171 /** ---------- 输出结果 ----------- **/ 172 if (found) 173 { 174 cout << "\n--------------- got path ----------------" << endl; 175 176 for (; !s.empty() ; s.pop()) 177 cout << "step " << s.top().step << ": " << p[s.top().direction] << endl; 178 } 179 else 180 cout << "\n--------------- no path ----------------" << endl; 181 182 } 183 184 ElemType Maze::getNext(const PosType curPos) 185 { 186 ElemType tempElem = ElemType(1, 0, 0, 0); 187 188 if (!m[curPos.r][curPos.c + 1] || m[curPos.r][curPos.c + 1] == 5) 189 { 190 if (m[curPos.r][curPos.c + 1] != 5) 191 { 192 m[curPos.r][curPos.c + 1] = 6; 193 } 194 195 tempElem.seat.r = curPos.r; 196 tempElem.seat.c = curPos.c + 1; 197 tempElem.direction = m[curPos.r][curPos.c + 1]; 198 return tempElem; 199 } 200 201 if (!m[curPos.r + 1][curPos.c] || m[curPos.r + 1][curPos.c] == 5) 202 { 203 if (m[curPos.r + 1][curPos.c] != 5) 204 { 205 m[curPos.r + 1][curPos.c] = 8; 206 } 207 208 tempElem.seat.r = curPos.r + 1; 209 tempElem.seat.c = curPos.c; 210 tempElem.direction = m[curPos.r + 1][curPos.c]; 211 return tempElem; 212 } 213 214 if (!m[curPos.r][curPos.c - 1] || m[curPos.r][curPos.c - 1] == 5) 215 { 216 if (m[curPos.r][curPos.c - 1] != 5) 217 { 218 m[curPos.r][curPos.c - 1] = 4; 219 } 220 221 tempElem.seat.r = curPos.r; 222 tempElem.seat.c = curPos.c - 1; 223 tempElem.direction = m[curPos.r][curPos.c - 1]; 224 return tempElem; 225 } 226 227 if (!m[curPos.r - 1][curPos.c] || m[curPos.r - 1][curPos.c] == 5) 228 { 229 if (m[curPos.r - 1][curPos.c] != 5) 230 { 231 m[curPos.r - 1][curPos.c] = 2; 232 } 233 234 tempElem.seat.r = curPos.r - 1; 235 tempElem.seat.c = curPos.c; 236 tempElem.direction = m[curPos.r - 1][curPos.c]; 237 return tempElem; 238 } 239 240 return tempElem; 241 } 242 243 bool Maze::pass(PosType p) 244 { 245 assert(p.r >= 0 && p.c >= 0 && p.r < r + 2 && p.c < c + 2); 246 return m[p.r][p.c] == 0; 247 } 248 249 Maze::~Maze() 250 { 251 for (int i = 0; i < r + 2 ; i++) 252 delete [] m[i]; 253 254 delete m; 255 }
更新:改进 getNext(const PosType curPos) 函数:可在 8 八个方向寻找路径(2013-06-03 08:06)
// 用于打印的字符串数组添加了四个方向 string p[] = { " ", // 0,通路 "■", // 1,障碍或围墙 "↑", // 2,北 "○", // 3,入口 "←", // 4,西 "★", // 5,出口 "→", // 6,东 "※", // 7,死胡同 "↓", // 8,南 "↘", // 9,东南 "↙", // 10,西南 "↖", // 11,西北 "↗" // 12,东北 }; // 用于打印迷宫 ElemType Maze::getNext(const PosType curPos) { // 改进,可以在 8 个方向寻找路径 int tempR = curPos.r; int tempC = curPos.c; ElemType tempElem = ElemType(1, 0, 0, 0); if ((m[tempR][tempC + 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC + 1]) == 0 || m[tempR + 1][tempC + 1] == 5) { // 东南 // 逻辑计算 ((!a || !b) && !c) || d == !(a * b + c) || d if (m[tempR + 1][tempC + 1] != 5) { m[tempR + 1][tempC + 1] = 9; } tempElem.seat.r = tempR + 1; tempElem.seat.c = tempC + 1; tempElem.direction = m[tempR + 1][tempC + 1]; return tempElem; } if (m[tempR][tempC + 1] == 0 || m[tempR][tempC + 1] == 5) { // 东 if (m[tempR][tempC + 1] != 5) { m[tempR][tempC + 1] = 6; } tempElem.seat.r = tempR; tempElem.seat.c = tempC + 1; tempElem.direction = m[tempR][tempC + 1]; return tempElem; } if (m[tempR + 1][tempC] == 0 || m[tempR + 1][tempC] == 5) { // 南 if (m[tempR + 1][tempC] != 5) { m[tempR + 1][tempC] = 8; } tempElem.seat.r = tempR + 1; tempElem.seat.c = tempC; tempElem.direction = m[tempR + 1][tempC]; return tempElem; } if ((m[tempR][tempC - 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC - 1]) == 0 || m[tempR + 1][tempC - 1] == 5) { // 西南 if (m[tempR + 1][tempC - 1] != 5) { m[tempR + 1][tempC - 1] = 10; } tempElem.seat.r = tempR + 1; tempElem.seat.c = tempC - 1; tempElem.direction = m[tempR + 1][tempC - 1]; return tempElem; } if ((m[tempR][tempC + 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC + 1]) == 0 || m[tempR - 1][tempC + 1] == 5) { // 东北 if (m[tempR - 1][tempC + 1] != 5) { m[tempR - 1][tempC + 1] = 12; } tempElem.seat.r = tempR - 1; tempElem.seat.c = tempC + 1; tempElem.direction = m[tempR - 1][tempC + 1]; return tempElem; } if (m[tempR - 1][tempC] == 0 || m[tempR - 1][tempC] == 5) { // 北 if (m[tempR - 1][tempC] != 5) { m[tempR - 1][tempC] = 2; } tempElem.seat.r = tempR - 1; tempElem.seat.c = tempC; tempElem.direction = m[tempR - 1][tempC]; return tempElem; } if (m[tempR][tempC - 1] == 0 || m[tempR][tempC - 1] == 5) { // 西 if (m[tempR][tempC - 1] != 5) { m[tempR][tempC - 1] = 4; } tempElem.seat.r = tempR; tempElem.seat.c = tempC - 1; tempElem.direction = m[tempR][tempC - 1]; return tempElem; } if ((m[tempR][tempC - 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC - 1]) == 0 || m[tempR - 1][tempC - 1] == 5) { // 西北 if (m[tempR - 1][tempC - 1] != 5) { m[tempR - 1][tempC - 1] = 11; } tempElem.seat.r = tempR - 1; tempElem.seat.c = tempC - 1; tempElem.direction = m[tempR - 1][tempC - 1]; return tempElem; } return tempElem; }
更新:改进 getNext(const PosType curPos) 函数:可以根据出口位置所在的方位自动调整行走方向,使得所走步数在一定意义上最少。(2013-06-03 12:39)
1 /*-- Maze.cpp -------------------------------------------------------*/ 2 #include <cassert> 3 #include <stdlib.h> 4 #include <ctime> 5 #include "Maze.h" 6 7 #define random(x) (rand()%(x)) 8 9 using namespace std; 10 11 string p[] = 12 { 13 " ", // 0,通路 14 "■", // 1,障碍或围墙 15 "↑", // 2,北 16 "○", // 3,入口 17 "←", // 4,西 18 "★", // 5,出口 19 "→", // 6,东 20 "※", // 7,死胡同 21 "↓", // 8,南 22 "↘", // 9,东南 23 "↙", // 10,西南 24 "↖", // 11,西北 25 "↗" // 12,东北 26 }; // 用于打印迷宫 27 28 29 Maze::Maze() 30 { 31 //ctor 32 } 33 34 void Maze::init() 35 { 36 cout << "Size of maze: "; 37 cin >> r >> c; 38 39 assert(r > 0 && c > 0); 40 41 /*---------- 分配数组------------*/ 42 m = new int*[r + 2]; 43 44 for (int i = 0; i < r + 2 ; i++ ) 45 m[i] = new int[c + 2]; 46 47 /*---------- “画” 围墙 -------------------------------- 48 障碍或围墙用 1 表示,通路用 0 表示 49 ----------------------------------------------------*/ 50 for (int i = 0; i < r + 2 ; i++) 51 { 52 m[i][0] = 1; 53 m[i][c + 1] = 1; 54 } 55 56 for (int i = 0; i < c + 2 ; i++) 57 { 58 m[0][i] = 1; 59 m[r + 1][i] = 1; 60 } 61 62 /*---------- 输入迷宫数据------------*/ 63 bool autoMaze = false; // 自动生成迷宫 64 cout << "Auto maze?(0/1) "; 65 cin >> autoMaze; 66 67 if (autoMaze) 68 { 69 for (int i = 1; i < r + 1 ; i++ ) 70 { 71 for (int j = 1; j < c + 1 ; j++ ) 72 { 73 srand((int)time(0) + i * j * 2); 74 75 if (random(20) > 4) m[i][j] = 0; 76 else m[i][j] = 1; 77 } 78 } 79 80 display(); 81 } 82 else 83 { 84 for (int i = 1; i < r + 1 ; i++ ) 85 { 86 cout << "row " << i << ": "; 87 88 for (int j = 1; j < c + 1 ; j++ ) 89 cin >> m[i][j]; 90 } 91 } 92 93 /*---------- 设置迷宫入口和出口 ------------*/ 94 int tempR, tempC; 95 cout << "ENTRANCE: "; 96 cin >> tempR >> tempC; 97 assert((tempR == 1 || tempR == r || tempC == 1 || tempC == c) && 98 (tempR > 0 && tempR <= r && tempC > 0 && tempC <= c)); 99 m[tempR][tempC] = 3; // 入口用 3 表示 100 entra.r = tempR; 101 entra.c = tempC; 102 103 cout << "EXIT: "; 104 cin >> tempR >> tempC; 105 assert((tempR == 1 || tempR == r || tempC == 1 || tempC == c) && 106 (tempR > 0 && tempR <= r && tempC > 0 && tempC <= c)); 107 m[tempR][tempC] = 5; // 出口用 5 表示 108 exi.r = tempR; 109 exi.c = tempC; 110 111 assert(entra.r != exi.r || entra.c != exi.c); // 限定入口与出口不可相同 112 } 113 114 void Maze::display() const 115 { 116 for (int i = 0; i < r + 2 ; i++ ) 117 { 118 for (int j = 0; j < c + 2 ; j++ ) 119 cout << p[m[i][j]]; 120 121 cout << "\n"; 122 } 123 124 cout << "\n"; 125 } 126 127 void Maze::getPath() 128 { 129 if (!s.empty()) 130 s.clear(); 131 132 PosType curPos = entra; 133 int step = 0; 134 bool found = false; 135 s.push(ElemType(step, curPos.r, curPos.c, 3)); // 首先将入口压栈 136 137 ElemType tempElem; 138 139 bool viewEachStep = false; 140 cout << "View each step?(0/1) "; 141 cin >> viewEachStep; 142 143 do 144 { 145 if (viewEachStep) 146 { 147 system("pause"); 148 cout << "---------- step " << step 149 << " ----------\n"; 150 display(); 151 } 152 153 tempElem = getNext(s.top().seat); // 根据栈顶位置找下一个步 154 155 if (m[tempElem.seat.r][tempElem.seat.c] == 5) 156 found = true; // 找到的下一位置是出口 157 else 158 { 159 // 不是出口 160 if (tempElem.direction) 161 { 162 // 有下一步可走 163 tempElem.step = ++step; 164 s.push(tempElem); // 将下一步位置压栈 165 } 166 else 167 { 168 // 找不到下一位置 169 step--; 170 171 if (s.top().direction != 3) 172 m[s.top().seat.r][s.top().seat.c] = 7; // 当前栈顶是死胡同 173 174 s.pop(); // 在路径中删除当前位置 175 } 176 } 177 } 178 while (!s.empty() && !found); 179 180 /** ---------- 输出结果 ----------- **/ 181 if (found) 182 { 183 cout << "\n--------------- got path ----------------" << endl; 184 185 for (; !s.empty() ; s.pop()) 186 cout << "step " << s.top().step << ": " << p[s.top().direction] << endl; 187 } 188 else 189 cout << "\n--------------- no path ----------------" << endl; 190 191 } 192 193 ElemType Maze::getNext(const PosType curPos) 194 { 195 int tempR = curPos.r; 196 int tempC = curPos.c; 197 int exitR = exi.r; 198 int exitC = exi.c; 199 ElemType tempElem = ElemType(1, 0, 0, 0); 200 201 if (tempR<= exitR && tempC<=exitC) 202 { 203 // 在出口左上角 204 getNextNW(tempElem, tempR, tempC); 205 return tempElem; 206 } 207 208 if (tempR<= exitR && tempC>=exitC) 209 { 210 // 在出口右上角 211 getNextNE(tempElem, tempR, tempC); 212 return tempElem; 213 } 214 215 if (tempR>= exitR && tempC<=exitC) 216 { 217 // 在出口左下角 218 getNextSW(tempElem, tempR, tempC); 219 return tempElem; 220 } 221 222 if (tempR>= exitR && tempC>=exitC) 223 { 224 // 在出口右下角 225 getNextSE(tempElem, tempR, tempC); 226 return tempElem; 227 } 228 229 return tempElem; 230 } 231 232 void Maze::getNextNW(ElemType &tempElem, int tempR, int tempC) 233 { 234 // 西北 11 235 if ((m[tempR][tempC + 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC + 1]) == 0 || m[tempR + 1][tempC + 1] == 5) 236 { 237 // 东南 // 逻辑计算 ((!a || !b) && !c) || d == !(a * b + c) || d 238 if (m[tempR + 1][tempC + 1] != 5) 239 { 240 m[tempR + 1][tempC + 1] = 9; 241 } 242 243 tempElem.seat.r = tempR + 1; 244 tempElem.seat.c = tempC + 1; 245 tempElem.direction = m[tempR + 1][tempC + 1]; 246 247 return; 248 } 249 250 if (m[tempR + 1][tempC] == 0 || m[tempR + 1][tempC] == 5) 251 { 252 // 南 253 if (m[tempR + 1][tempC] != 5) 254 { 255 m[tempR + 1][tempC] = 8; 256 } 257 258 tempElem.seat.r = tempR + 1; 259 tempElem.seat.c = tempC; 260 tempElem.direction = m[tempR + 1][tempC]; 261 262 return; 263 } 264 265 if (m[tempR][tempC + 1] == 0 || m[tempR][tempC + 1] == 5) 266 { 267 // 东 268 if (m[tempR][tempC + 1] != 5) 269 { 270 m[tempR][tempC + 1] = 6; 271 } 272 273 tempElem.seat.r = tempR; 274 tempElem.seat.c = tempC + 1; 275 tempElem.direction = m[tempR][tempC + 1]; 276 277 return; 278 } 279 280 if ((m[tempR][tempC - 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC - 1]) == 0 || m[tempR + 1][tempC - 1] == 5) 281 { 282 // 西南 283 if (m[tempR + 1][tempC - 1] != 5) 284 { 285 m[tempR + 1][tempC - 1] = 10; 286 } 287 288 tempElem.seat.r = tempR + 1; 289 tempElem.seat.c = tempC - 1; 290 tempElem.direction = m[tempR + 1][tempC - 1]; 291 292 return; 293 } 294 295 if ((m[tempR][tempC + 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC + 1]) == 0 || m[tempR - 1][tempC + 1] == 5) 296 { 297 // 东北 298 if (m[tempR - 1][tempC + 1] != 5) 299 { 300 m[tempR - 1][tempC + 1] = 12; 301 } 302 303 tempElem.seat.r = tempR - 1; 304 tempElem.seat.c = tempC + 1; 305 tempElem.direction = m[tempR - 1][tempC + 1]; 306 307 return; 308 } 309 310 if (m[tempR][tempC - 1] == 0 || m[tempR][tempC - 1] == 5) 311 { 312 // 西 313 if (m[tempR][tempC - 1] != 5) 314 { 315 m[tempR][tempC - 1] = 4; 316 } 317 318 tempElem.seat.r = tempR; 319 tempElem.seat.c = tempC - 1; 320 tempElem.direction = m[tempR][tempC - 1]; 321 322 return; 323 } 324 325 if (m[tempR - 1][tempC] == 0 || m[tempR - 1][tempC] == 5) 326 { 327 // 北 328 if (m[tempR - 1][tempC] != 5) 329 { 330 m[tempR - 1][tempC] = 2; 331 } 332 333 tempElem.seat.r = tempR - 1; 334 tempElem.seat.c = tempC; 335 tempElem.direction = m[tempR - 1][tempC]; 336 337 return; 338 } 339 340 if ((m[tempR][tempC - 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC - 1]) == 0 || m[tempR - 1][tempC - 1] == 5) 341 { 342 // 西北 343 if (m[tempR - 1][tempC - 1] != 5) 344 { 345 m[tempR - 1][tempC - 1] = 11; 346 } 347 348 tempElem.seat.r = tempR - 1; 349 tempElem.seat.c = tempC - 1; 350 tempElem.direction = m[tempR - 1][tempC - 1]; 351 352 return; 353 } 354 } 355 356 void Maze::getNextNE(ElemType &tempElem, int tempR, int tempC) 357 { 358 // 东北 12 359 if ((m[tempR][tempC - 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC - 1]) == 0 || m[tempR + 1][tempC - 1] == 5) 360 { 361 // 西南 362 if (m[tempR + 1][tempC - 1] != 5) 363 { 364 m[tempR + 1][tempC - 1] = 10; 365 } 366 367 tempElem.seat.r = tempR + 1; 368 tempElem.seat.c = tempC - 1; 369 tempElem.direction = m[tempR + 1][tempC - 1]; 370 371 return; 372 } 373 374 if (m[tempR][tempC - 1] == 0 || m[tempR][tempC - 1] == 5) 375 { 376 // 西 377 if (m[tempR][tempC - 1] != 5) 378 { 379 m[tempR][tempC - 1] = 4; 380 } 381 382 tempElem.seat.r = tempR; 383 tempElem.seat.c = tempC - 1; 384 tempElem.direction = m[tempR][tempC - 1]; 385 386 return; 387 } 388 389 if (m[tempR + 1][tempC] == 0 || m[tempR + 1][tempC] == 5) 390 { 391 // 南 392 if (m[tempR + 1][tempC] != 5) 393 { 394 m[tempR + 1][tempC] = 8; 395 } 396 397 tempElem.seat.r = tempR + 1; 398 tempElem.seat.c = tempC; 399 tempElem.direction = m[tempR + 1][tempC]; 400 401 return; 402 } 403 404 if ((m[tempR][tempC + 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC + 1]) == 0 || m[tempR + 1][tempC + 1] == 5) 405 { 406 // 东南 // 逻辑计算 ((!a || !b) && !c) || d == !(a * b + c) || d 407 if (m[tempR + 1][tempC + 1] != 5) 408 { 409 m[tempR + 1][tempC + 1] = 9; 410 } 411 412 tempElem.seat.r = tempR + 1; 413 tempElem.seat.c = tempC + 1; 414 tempElem.direction = m[tempR + 1][tempC + 1]; 415 416 return; 417 } 418 419 if ((m[tempR][tempC - 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC - 1]) == 0 || m[tempR - 1][tempC - 1] == 5) 420 { 421 // 西北 422 if (m[tempR - 1][tempC - 1] != 5) 423 { 424 m[tempR - 1][tempC - 1] = 11; 425 } 426 427 tempElem.seat.r = tempR - 1; 428 tempElem.seat.c = tempC - 1; 429 tempElem.direction = m[tempR - 1][tempC - 1]; 430 431 return; 432 } 433 434 if (m[tempR - 1][tempC] == 0 || m[tempR - 1][tempC] == 5) 435 { 436 // 北 437 if (m[tempR - 1][tempC] != 5) 438 { 439 m[tempR - 1][tempC] = 2; 440 } 441 442 tempElem.seat.r = tempR - 1; 443 tempElem.seat.c = tempC; 444 tempElem.direction = m[tempR - 1][tempC]; 445 446 return; 447 } 448 449 if (m[tempR][tempC + 1] == 0 || m[tempR][tempC + 1] == 5) 450 { 451 // 东 452 if (m[tempR][tempC + 1] != 5) 453 { 454 m[tempR][tempC + 1] = 6; 455 } 456 457 tempElem.seat.r = tempR; 458 tempElem.seat.c = tempC + 1; 459 tempElem.direction = m[tempR][tempC + 1]; 460 461 return; 462 } 463 464 if ((m[tempR][tempC + 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC + 1]) == 0 || m[tempR - 1][tempC + 1] == 5) 465 { 466 // 东北 467 if (m[tempR - 1][tempC + 1] != 5) 468 { 469 m[tempR - 1][tempC + 1] = 12; 470 } 471 472 tempElem.seat.r = tempR - 1; 473 tempElem.seat.c = tempC + 1; 474 tempElem.direction = m[tempR - 1][tempC + 1]; 475 476 return; 477 } 478 } 479 480 void Maze::getNextSW(ElemType &tempElem, int tempR, int tempC) 481 { 482 // 西南 10 483 484 if ((m[tempR][tempC + 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC + 1]) == 0 || m[tempR - 1][tempC + 1] == 5) 485 { 486 // 东北 487 if (m[tempR - 1][tempC + 1] != 5) 488 { 489 m[tempR - 1][tempC + 1] = 12; 490 } 491 492 tempElem.seat.r = tempR - 1; 493 tempElem.seat.c = tempC + 1; 494 tempElem.direction = m[tempR - 1][tempC + 1]; 495 496 return; 497 } 498 499 if (m[tempR - 1][tempC] == 0 || m[tempR - 1][tempC] == 5) 500 { 501 // 北 502 if (m[tempR - 1][tempC] != 5) 503 { 504 m[tempR - 1][tempC] = 2; 505 } 506 507 tempElem.seat.r = tempR - 1; 508 tempElem.seat.c = tempC; 509 tempElem.direction = m[tempR - 1][tempC]; 510 511 return; 512 } 513 514 if (m[tempR][tempC + 1] == 0 || m[tempR][tempC + 1] == 5) 515 { 516 // 东 517 if (m[tempR][tempC + 1] != 5) 518 { 519 m[tempR][tempC + 1] = 6; 520 } 521 522 tempElem.seat.r = tempR; 523 tempElem.seat.c = tempC + 1; 524 tempElem.direction = m[tempR][tempC + 1]; 525 526 return; 527 } 528 529 if ((m[tempR][tempC - 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC - 1]) == 0 || m[tempR - 1][tempC - 1] == 5) 530 { 531 // 西北 532 if (m[tempR - 1][tempC - 1] != 5) 533 { 534 m[tempR - 1][tempC - 1] = 11; 535 } 536 537 tempElem.seat.r = tempR - 1; 538 tempElem.seat.c = tempC - 1; 539 tempElem.direction = m[tempR - 1][tempC - 1]; 540 541 return; 542 } 543 544 if ((m[tempR][tempC + 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC + 1]) == 0 || m[tempR + 1][tempC + 1] == 5) 545 { 546 // 东南 // 逻辑计算 ((!a || !b) && !c) || d == !(a * b + c) || d 547 if (m[tempR + 1][tempC + 1] != 5) 548 { 549 m[tempR + 1][tempC + 1] = 9; 550 } 551 552 tempElem.seat.r = tempR + 1; 553 tempElem.seat.c = tempC + 1; 554 tempElem.direction = m[tempR + 1][tempC + 1]; 555 556 return; 557 } 558 559 if (m[tempR + 1][tempC] == 0 || m[tempR + 1][tempC] == 5) 560 { 561 // 南 562 if (m[tempR + 1][tempC] != 5) 563 { 564 m[tempR + 1][tempC] = 8; 565 } 566 567 tempElem.seat.r = tempR + 1; 568 tempElem.seat.c = tempC; 569 tempElem.direction = m[tempR + 1][tempC]; 570 571 return; 572 } 573 574 if (m[tempR][tempC - 1] == 0 || m[tempR][tempC - 1] == 5) 575 { 576 // 西 577 if (m[tempR][tempC - 1] != 5) 578 { 579 m[tempR][tempC - 1] = 4; 580 } 581 582 tempElem.seat.r = tempR; 583 tempElem.seat.c = tempC - 1; 584 tempElem.direction = m[tempR][tempC - 1]; 585 586 return; 587 } 588 589 if ((m[tempR][tempC - 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC - 1]) == 0 || m[tempR + 1][tempC - 1] == 5) 590 { 591 // 西南 592 if (m[tempR + 1][tempC - 1] != 5) 593 { 594 m[tempR + 1][tempC - 1] = 10; 595 } 596 597 tempElem.seat.r = tempR + 1; 598 tempElem.seat.c = tempC - 1; 599 tempElem.direction = m[tempR + 1][tempC - 1]; 600 601 return; 602 } 603 } 604 605 void Maze::getNextSE(ElemType &tempElem, int tempR, int tempC) 606 { 607 // 东南 9 608 609 if ((m[tempR][tempC - 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC - 1]) == 0 || m[tempR - 1][tempC - 1] == 5) 610 { 611 // 西北 612 if (m[tempR - 1][tempC - 1] != 5) 613 { 614 m[tempR - 1][tempC - 1] = 11; 615 } 616 617 tempElem.seat.r = tempR - 1; 618 tempElem.seat.c = tempC - 1; 619 tempElem.direction = m[tempR - 1][tempC - 1]; 620 621 return; 622 } 623 624 if (m[tempR - 1][tempC] == 0 || m[tempR - 1][tempC] == 5) 625 { 626 // 北 627 if (m[tempR - 1][tempC] != 5) 628 { 629 m[tempR - 1][tempC] = 2; 630 } 631 632 tempElem.seat.r = tempR - 1; 633 tempElem.seat.c = tempC; 634 tempElem.direction = m[tempR - 1][tempC]; 635 636 return; 637 } 638 639 if (m[tempR][tempC - 1] == 0 || m[tempR][tempC - 1] == 5) 640 { 641 // 西 642 if (m[tempR][tempC - 1] != 5) 643 { 644 m[tempR][tempC - 1] = 4; 645 } 646 647 tempElem.seat.r = tempR; 648 tempElem.seat.c = tempC - 1; 649 tempElem.direction = m[tempR][tempC - 1]; 650 651 return; 652 } 653 654 if ((m[tempR][tempC + 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC + 1]) == 0 || m[tempR - 1][tempC + 1] == 5) 655 { 656 // 东北 657 if (m[tempR - 1][tempC + 1] != 5) 658 { 659 m[tempR - 1][tempC + 1] = 12; 660 } 661 662 tempElem.seat.r = tempR - 1; 663 tempElem.seat.c = tempC + 1; 664 tempElem.direction = m[tempR - 1][tempC + 1]; 665 666 return; 667 } 668 669 if ((m[tempR][tempC - 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC - 1]) == 0 || m[tempR + 1][tempC - 1] == 5) 670 { 671 // 西南 672 if (m[tempR + 1][tempC - 1] != 5) 673 { 674 m[tempR + 1][tempC - 1] = 10; 675 } 676 677 tempElem.seat.r = tempR + 1; 678 tempElem.seat.c = tempC - 1; 679 tempElem.direction = m[tempR + 1][tempC - 1]; 680 681 return; 682 } 683 684 if (m[tempR + 1][tempC] == 0 || m[tempR + 1][tempC] == 5) 685 { 686 // 南 687 if (m[tempR + 1][tempC] != 5) 688 { 689 m[tempR + 1][tempC] = 8; 690 } 691 692 tempElem.seat.r = tempR + 1; 693 tempElem.seat.c = tempC; 694 tempElem.direction = m[tempR + 1][tempC]; 695 696 return; 697 } 698 699 if (m[tempR][tempC + 1] == 0 || m[tempR][tempC + 1] == 5) 700 { 701 // 东 702 if (m[tempR][tempC + 1] != 5) 703 { 704 m[tempR][tempC + 1] = 6; 705 } 706 707 tempElem.seat.r = tempR; 708 tempElem.seat.c = tempC + 1; 709 tempElem.direction = m[tempR][tempC + 1]; 710 711 return; 712 } 713 714 if ((m[tempR][tempC + 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC + 1]) == 0 || m[tempR + 1][tempC + 1] == 5) 715 { 716 // 东南 // 逻辑计算 ((!a || !b) && !c) || d == !(a * b + c) || d 717 if (m[tempR + 1][tempC + 1] != 5) 718 { 719 m[tempR + 1][tempC + 1] = 9; 720 } 721 722 tempElem.seat.r = tempR + 1; 723 tempElem.seat.c = tempC + 1; 724 tempElem.direction = m[tempR + 1][tempC + 1]; 725 726 return; 727 } 728 729 if ((m[tempR][tempC + 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC + 1]) == 0 || m[tempR + 1][tempC + 1] == 5) 730 { 731 // 东南 // 逻辑计算 ((!a || !b) && !c) || d == !(a * b + c) || d 732 if (m[tempR + 1][tempC + 1] != 5) 733 { 734 m[tempR + 1][tempC + 1] = 9; 735 } 736 737 tempElem.seat.r = tempR + 1; 738 tempElem.seat.c = tempC + 1; 739 tempElem.direction = m[tempR + 1][tempC + 1]; 740 741 return; 742 } 743 } 744 745 bool Maze::pass(PosType p) 746 { 747 assert(p.r >= 0 && p.c >= 0 && p.r < r + 2 && p.c < c + 2); 748 return m[p.r][p.c] == 0; 749 } 750 751 Maze::~Maze() 752 { 753 for (int i = 0; i < r + 2 ; i++) 754 delete [] m[i]; 755 756 delete m; 757 }
更新:为了增强代码可读性,并且减少编码时不必要的错误,将表示方向和各个坐标状态的数字进行了宏定义。(2013-06-04 22:06)
1 /*-- Maze.cpp -------------------------------------------------------*/ 2 #include <cassert> 3 #include <stdlib.h> 4 #include <ctime> 5 #include "Maze.h" 6 7 #define random(x) (rand()%(x)) 8 9 using namespace std; 10 11 #define SPACE 0 // 0,通路或空格 12 #define BLOCK 1 // 1,障碍或围墙 13 #define NORTH 2 // 2,北 14 #define ENTRANCE 3 // 3,入口 15 #define WEST 4 // 4,西 16 #define EXITPORT 5 // 5,出口 17 #define EAST 6 // 6,东 18 #define DEADEND 7 // 7,死胡同 19 #define SOUTH 8 // 8,南 20 #define SOUTHEAST 9 // 9,东南 21 #define SOUTHWEST 10 // 10,西南 22 #define NORTHWEST 11 // 11,西北 23 #define NORTHEAST 12 // 12,东北 24 25 string p[] = 26 { 27 " ", // 0,通路 28 "■", // 1,障碍或围墙 29 "↑", // 2,北 30 "○", // 3,入口 31 "←", // 4,西 32 "★", // 5,出口 33 "→", // 6,东 34 "", // 7,死胡同 35 "↓", // 8,南 36 "↘", // 9,东南 37 "↙", // 10,西南 38 "↖", // 11,西北 39 "↗" // 12,东北 40 }; // 用于打印迷宫 41 42 43 Maze::Maze() 44 { 45 //ctor 46 } 47 48 void Maze::init() 49 { 50 cout << "Size of maze: "; 51 cin >> r >> c; 52 53 assert(r > 0 && c > 0); 54 55 /*---------- 分配数组------------*/ 56 m = new int*[r + 2]; 57 58 for (int i = 0; i < r + 2 ; i++ ) 59 m[i] = new int[c + 2]; 60 61 /*---------- “画” 围墙 -------------------------------- 62 障碍或围墙用 1 表示,通路用 0 表示 63 ----------------------------------------------------*/ 64 for (int i = 0; i < r + 2 ; i++) 65 { 66 m[i][0] = BLOCK; 67 m[i][c + 1] = BLOCK; 68 } 69 70 for (int i = 0; i < c + 2 ; i++) 71 { 72 m[0][i] = BLOCK; 73 m[r + 1][i] = BLOCK; 74 } 75 76 /*---------- 输入迷宫数据------------*/ 77 bool autoMaze = false; // 自动生成迷宫 78 cout << "Auto maze?(0/1) "; 79 cin >> autoMaze; 80 81 if (autoMaze) 82 { 83 for (int i = 1; i < r + 1 ; i++ ) 84 { 85 for (int j = 1; j < c + 1 ; j++ ) 86 { 87 srand((int)time(0) + i * j * 2); 88 89 if (random(20) > 4) m[i][j] = SPACE; 90 else m[i][j] = BLOCK; 91 } 92 } 93 94 display(); 95 } 96 else 97 { 98 for (int i = 1; i < r + 1 ; i++ ) 99 { 100 cout << "row " << i << ": "; 101 102 for (int j = 1; j < c + 1 ; j++ ) 103 cin >> m[i][j]; 104 } 105 } 106 107 /*---------- 设置迷宫入口和出口 ------------*/ 108 int tempR, tempC; 109 cout << "ENTRANCE: "; 110 cin >> tempR >> tempC; 111 assert((tempR == 1 || tempR == r || tempC == 1 || tempC == c) && 112 (tempR > 0 && tempR <= r && tempC > 0 && tempC <= c)); 113 m[tempR][tempC] = ENTRANCE; // 入口用 3 表示 114 entra.r = tempR; 115 entra.c = tempC; 116 117 cout << "EXIT: "; 118 cin >> tempR >> tempC; 119 assert((tempR == 1 || tempR == r || tempC == 1 || tempC == c) && 120 (tempR > 0 && tempR <= r && tempC > 0 && tempC <= c)); 121 m[tempR][tempC] = EXITPORT; // 出口用 5 表示 122 exi.r = tempR; 123 exi.c = tempC; 124 125 assert(entra.r != exi.r || entra.c != exi.c); // 限定入口与出口不可相同 126 } 127 128 void Maze::display() const 129 { 130 for (int i = 0; i < r + 2 ; i++ ) 131 { 132 for (int j = 0; j < c + 2 ; j++ ) 133 cout << p[m[i][j]]; 134 135 cout << "\n"; 136 } 137 138 cout << "\n"; 139 } 140 141 void Maze::getPath() 142 { 143 if (!s.empty()) 144 s.clear(); 145 146 PosType curPos = entra; 147 int step = 0; 148 bool found = false; 149 s.push(ElemType(step, curPos.r, curPos.c, ENTRANCE)); // 首先将入口压栈 150 151 ElemType tempElem; 152 153 bool viewEachStep = false; 154 cout << "View each step?(0/1) "; 155 cin >> viewEachStep; 156 157 do 158 { 159 if (viewEachStep) 160 { 161 system("pause"); 162 cout << "---------- step " << step 163 << " ----------\n"; 164 display(); 165 } 166 167 tempElem = getNext(s.top().seat); // 根据栈顶位置找下一个步 168 169 if (m[tempElem.seat.r][tempElem.seat.c] == EXITPORT) 170 found = true; // 找到的下一位置是出口 171 else 172 { 173 // 不是出口 174 if (tempElem.direction) 175 { 176 // 有下一步可走 177 tempElem.step = ++step; 178 s.push(tempElem); // 将下一步位置压栈 179 } 180 else 181 { 182 // 找不到下一位置 183 step--; 184 185 if (s.top().direction != ENTRANCE) 186 m[s.top().seat.r][s.top().seat.c] = DEADEND; // 当前栈顶是死胡同 187 188 s.pop(); // 在路径中删除当前位置 189 } 190 } 191 } 192 while (!s.empty() && !found); 193 194 /** ---------- 输出结果 ----------- **/ 195 if (found) 196 { 197 cout << "\n--------------- got path ----------------" << endl; 198 199 for (; !s.empty() ; s.pop()) 200 cout << "step " << s.top().step << ": " << p[s.top().direction] << endl; 201 } 202 else 203 cout << "\n--------------- no path ----------------" << endl; 204 205 } 206 207 ElemType Maze::getNext(const PosType curPos) 208 { 209 int tempR = curPos.r; 210 int tempC = curPos.c; 211 int exitR = exi.r; 212 int exitC = exi.c; 213 ElemType tempElem = ElemType(1, 0, 0, SPACE); 214 215 if (tempR<= exitR && tempC<=exitC) 216 { 217 // 在出口左上角 218 getNextNW(tempElem, tempR, tempC); 219 return tempElem; 220 } 221 222 if (tempR<= exitR && tempC>=exitC) 223 { 224 // 在出口右上角 225 getNextNE(tempElem, tempR, tempC); 226 return tempElem; 227 } 228 229 if (tempR>= exitR && tempC<=exitC) 230 { 231 // 在出口左下角 232 getNextSW(tempElem, tempR, tempC); 233 return tempElem; 234 } 235 236 if (tempR>= exitR && tempC>=exitC) 237 { 238 // 在出口右下角 239 getNextSE(tempElem, tempR, tempC); 240 return tempElem; 241 } 242 243 return tempElem; 244 } 245 246 void Maze::getNextNW(ElemType &tempElem, int tempR, int tempC) 247 { 248 // 西北 11 249 if (!(m[tempR][tempC + 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC + 1]) || m[tempR + 1][tempC + 1] == EXITPORT) 250 { 251 // 东南 // 逻辑计算 ((!a || !b) && !c) || d == !(a * b + c) || d 252 if (m[tempR + 1][tempC + 1] != EXITPORT) 253 { 254 m[tempR + 1][tempC + 1] = SOUTHEAST; 255 } 256 257 tempElem.seat.r = tempR + 1; 258 tempElem.seat.c = tempC + 1; 259 tempElem.direction = m[tempR + 1][tempC + 1]; 260 261 return; 262 } 263 264 if (m[tempR + 1][tempC] == SPACE || m[tempR + 1][tempC] == EXITPORT) 265 { 266 // 南 267 if (m[tempR + 1][tempC] != EXITPORT) 268 { 269 m[tempR + 1][tempC] = SOUTH; 270 } 271 272 tempElem.seat.r = tempR + 1; 273 tempElem.seat.c = tempC; 274 tempElem.direction = m[tempR + 1][tempC]; 275 276 return; 277 } 278 279 if (m[tempR][tempC + 1] == SPACE || m[tempR][tempC + 1] == EXITPORT) 280 { 281 // 东 282 if (m[tempR][tempC + 1] != EXITPORT) 283 { 284 m[tempR][tempC + 1] = EAST; 285 } 286 287 tempElem.seat.r = tempR; 288 tempElem.seat.c = tempC + 1; 289 tempElem.direction = m[tempR][tempC + 1]; 290 291 return; 292 } 293 294 if (!(m[tempR][tempC - 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC - 1]) || m[tempR + 1][tempC - 1] == EXITPORT) 295 { 296 // 西南 297 if (m[tempR + 1][tempC - 1] != EXITPORT) 298 { 299 m[tempR + 1][tempC - 1] = SOUTHWEST; 300 } 301 302 tempElem.seat.r = tempR + 1; 303 tempElem.seat.c = tempC - 1; 304 tempElem.direction = m[tempR + 1][tempC - 1]; 305 306 return; 307 } 308 309 if (!(m[tempR][tempC + 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC + 1]) || m[tempR - 1][tempC + 1] == EXITPORT) 310 { 311 // 东北 312 if (m[tempR - 1][tempC + 1] != EXITPORT) 313 { 314 m[tempR - 1][tempC + 1] = NORTHEAST; 315 } 316 317 tempElem.seat.r = tempR - 1; 318 tempElem.seat.c = tempC + 1; 319 tempElem.direction = m[tempR - 1][tempC + 1]; 320 321 return; 322 } 323 324 if (m[tempR][tempC - 1] == SPACE || m[tempR][tempC - 1] == EXITPORT) 325 { 326 // 西 327 if (m[tempR][tempC - 1] != EXITPORT) 328 { 329 m[tempR][tempC - 1] = WEST; 330 } 331 332 tempElem.seat.r = tempR; 333 tempElem.seat.c = tempC - 1; 334 tempElem.direction = m[tempR][tempC - 1]; 335 336 return; 337 } 338 339 if (m[tempR - 1][tempC] == SPACE || m[tempR - 1][tempC] == EXITPORT) 340 { 341 // 北 342 if (m[tempR - 1][tempC] != EXITPORT) 343 { 344 m[tempR - 1][tempC] = NORTH; 345 } 346 347 tempElem.seat.r = tempR - 1; 348 tempElem.seat.c = tempC; 349 tempElem.direction = m[tempR - 1][tempC]; 350 351 return; 352 } 353 354 if (!(m[tempR][tempC - 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC - 1]) || m[tempR - 1][tempC - 1] == EXITPORT) 355 { 356 // 西北 357 if (m[tempR - 1][tempC - 1] != EXITPORT) 358 { 359 m[tempR - 1][tempC - 1] = NORTHWEST; 360 } 361 362 tempElem.seat.r = tempR - 1; 363 tempElem.seat.c = tempC - 1; 364 tempElem.direction = m[tempR - 1][tempC - 1]; 365 366 return; 367 } 368 } 369 370 void Maze::getNextNE(ElemType &tempElem, int tempR, int tempC) 371 { 372 // 东北 12 373 if (!(m[tempR][tempC - 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC - 1]) || m[tempR + 1][tempC - 1] == EXITPORT) 374 { 375 // 西南 376 if (m[tempR + 1][tempC - 1] != EXITPORT) 377 { 378 m[tempR + 1][tempC - 1] = SOUTHWEST; 379 } 380 381 tempElem.seat.r = tempR + 1; 382 tempElem.seat.c = tempC - 1; 383 tempElem.direction = m[tempR + 1][tempC - 1]; 384 385 return; 386 } 387 388 if (m[tempR][tempC - 1] == SPACE || m[tempR][tempC - 1] == EXITPORT) 389 { 390 // 西 391 if (m[tempR][tempC - 1] != EXITPORT) 392 { 393 m[tempR][tempC - 1] = WEST; 394 } 395 396 tempElem.seat.r = tempR; 397 tempElem.seat.c = tempC - 1; 398 tempElem.direction = m[tempR][tempC - 1]; 399 400 return; 401 } 402 403 if (m[tempR + 1][tempC] == SPACE || m[tempR + 1][tempC] == EXITPORT) 404 { 405 // 南 406 if (m[tempR + 1][tempC] != EXITPORT) 407 { 408 m[tempR + 1][tempC] = SOUTH; 409 } 410 411 tempElem.seat.r = tempR + 1; 412 tempElem.seat.c = tempC; 413 tempElem.direction = m[tempR + 1][tempC]; 414 415 return; 416 } 417 418 if (!(m[tempR][tempC + 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC + 1]) || m[tempR + 1][tempC + 1] == EXITPORT) 419 { 420 // 东南 // 逻辑计算 ((!a || !b) && !c) || d == !(a * b + c) || d 421 if (m[tempR + 1][tempC + 1] != EXITPORT) 422 { 423 m[tempR + 1][tempC + 1] = SOUTHEAST; 424 } 425 426 tempElem.seat.r = tempR + 1; 427 tempElem.seat.c = tempC + 1; 428 tempElem.direction = m[tempR + 1][tempC + 1]; 429 430 return; 431 } 432 433 if (!(m[tempR][tempC - 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC - 1]) || m[tempR - 1][tempC - 1] == EXITPORT) 434 { 435 // 西北 436 if (m[tempR - 1][tempC - 1] != EXITPORT) 437 { 438 m[tempR - 1][tempC - 1] = NORTHWEST; 439 } 440 441 tempElem.seat.r = tempR - 1; 442 tempElem.seat.c = tempC - 1; 443 tempElem.direction = m[tempR - 1][tempC - 1]; 444 445 return; 446 } 447 448 if (m[tempR - 1][tempC] == SPACE || m[tempR - 1][tempC] == EXITPORT) 449 { 450 // 北 451 if (m[tempR - 1][tempC] != EXITPORT) 452 { 453 m[tempR - 1][tempC] = NORTH; 454 } 455 456 tempElem.seat.r = tempR - 1; 457 tempElem.seat.c = tempC; 458 tempElem.direction = m[tempR - 1][tempC]; 459 460 return; 461 } 462 463 if (m[tempR][tempC + 1] == SPACE || m[tempR][tempC + 1] == EXITPORT) 464 { 465 // 东 466 if (m[tempR][tempC + 1] != EXITPORT) 467 { 468 m[tempR][tempC + 1] = EAST; 469 } 470 471 tempElem.seat.r = tempR; 472 tempElem.seat.c = tempC + 1; 473 tempElem.direction = m[tempR][tempC + 1]; 474 475 return; 476 } 477 478 if (!(m[tempR][tempC + 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC + 1]) || m[tempR - 1][tempC + 1] == EXITPORT) 479 { 480 // 东北 481 if (m[tempR - 1][tempC + 1] != EXITPORT) 482 { 483 m[tempR - 1][tempC + 1] = NORTHEAST; 484 } 485 486 tempElem.seat.r = tempR - 1; 487 tempElem.seat.c = tempC + 1; 488 tempElem.direction = m[tempR - 1][tempC + 1]; 489 490 return; 491 } 492 } 493 494 void Maze::getNextSW(ElemType &tempElem, int tempR, int tempC) 495 { 496 // 西南 10 497 498 if (!(m[tempR][tempC + 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC + 1]) || m[tempR - 1][tempC + 1] == EXITPORT) 499 { 500 // 东北 501 if (m[tempR - 1][tempC + 1] != EXITPORT) 502 { 503 m[tempR - 1][tempC + 1] = NORTHEAST; 504 } 505 506 tempElem.seat.r = tempR - 1; 507 tempElem.seat.c = tempC + 1; 508 tempElem.direction = m[tempR - 1][tempC + 1]; 509 510 return; 511 } 512 513 if (m[tempR - 1][tempC] == SPACE || m[tempR - 1][tempC] == EXITPORT) 514 { 515 // 北 516 if (m[tempR - 1][tempC] != EXITPORT) 517 { 518 m[tempR - 1][tempC] = NORTH; 519 } 520 521 tempElem.seat.r = tempR - 1; 522 tempElem.seat.c = tempC; 523 tempElem.direction = m[tempR - 1][tempC]; 524 525 return; 526 } 527 528 if (m[tempR][tempC + 1] == SPACE || m[tempR][tempC + 1] == EXITPORT) 529 { 530 // 东 531 if (m[tempR][tempC + 1] != EXITPORT) 532 { 533 m[tempR][tempC + 1] = EAST; 534 } 535 536 tempElem.seat.r = tempR; 537 tempElem.seat.c = tempC + 1; 538 tempElem.direction = m[tempR][tempC + 1]; 539 540 return; 541 } 542 543 if (!(m[tempR][tempC - 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC - 1]) || m[tempR - 1][tempC - 1] == EXITPORT) 544 { 545 // 西北 546 if (m[tempR - 1][tempC - 1] != EXITPORT) 547 { 548 m[tempR - 1][tempC - 1] = NORTHWEST; 549 } 550 551 tempElem.seat.r = tempR - 1; 552 tempElem.seat.c = tempC - 1; 553 tempElem.direction = m[tempR - 1][tempC - 1]; 554 555 return; 556 } 557 558 if (!(m[tempR][tempC + 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC + 1]) || m[tempR + 1][tempC + 1] == EXITPORT) 559 { 560 // 东南 // 逻辑计算 ((!a || !b) && !c) || d == !(a * b + c) || d 561 if (m[tempR + 1][tempC + 1] != EXITPORT) 562 { 563 m[tempR + 1][tempC + 1] = SOUTHEAST; 564 } 565 566 tempElem.seat.r = tempR + 1; 567 tempElem.seat.c = tempC + 1; 568 tempElem.direction = m[tempR + 1][tempC + 1]; 569 570 return; 571 } 572 573 if (m[tempR + 1][tempC] == SPACE || m[tempR + 1][tempC] == EXITPORT) 574 { 575 // 南 576 if (m[tempR + 1][tempC] != EXITPORT) 577 { 578 m[tempR + 1][tempC] = SOUTH; 579 } 580 581 tempElem.seat.r = tempR + 1; 582 tempElem.seat.c = tempC; 583 tempElem.direction = m[tempR + 1][tempC]; 584 585 return; 586 } 587 588 if (m[tempR][tempC - 1] == SPACE || m[tempR][tempC - 1] == EXITPORT) 589 { 590 // 西 591 if (m[tempR][tempC - 1] != EXITPORT) 592 { 593 m[tempR][tempC - 1] = WEST; 594 } 595 596 tempElem.seat.r = tempR; 597 tempElem.seat.c = tempC - 1; 598 tempElem.direction = m[tempR][tempC - 1]; 599 600 return; 601 } 602 603 if (!(m[tempR][tempC - 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC - 1]) || m[tempR + 1][tempC - 1] == EXITPORT) 604 { 605 // 西南 606 if (m[tempR + 1][tempC - 1] != EXITPORT) 607 { 608 m[tempR + 1][tempC - 1] = SOUTHWEST; 609 } 610 611 tempElem.seat.r = tempR + 1; 612 tempElem.seat.c = tempC - 1; 613 tempElem.direction = m[tempR + 1][tempC - 1]; 614 615 return; 616 } 617 } 618 619 void Maze::getNextSE(ElemType &tempElem, int tempR, int tempC) 620 { 621 // 东南 9 622 623 if (!(m[tempR][tempC - 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC - 1]) || m[tempR - 1][tempC - 1] == EXITPORT) 624 { 625 // 西北 626 if (m[tempR - 1][tempC - 1] != EXITPORT) 627 { 628 m[tempR - 1][tempC - 1] = NORTHWEST; 629 } 630 631 tempElem.seat.r = tempR - 1; 632 tempElem.seat.c = tempC - 1; 633 tempElem.direction = m[tempR - 1][tempC - 1]; 634 635 return; 636 } 637 638 if (m[tempR - 1][tempC] == SPACE || m[tempR - 1][tempC] == EXITPORT) 639 { 640 // 北 641 if (m[tempR - 1][tempC] != EXITPORT) 642 { 643 m[tempR - 1][tempC] = NORTH; 644 } 645 646 tempElem.seat.r = tempR - 1; 647 tempElem.seat.c = tempC; 648 tempElem.direction = m[tempR - 1][tempC]; 649 650 return; 651 } 652 653 if (m[tempR][tempC - 1] == SPACE || m[tempR][tempC - 1] == EXITPORT) 654 { 655 // 西 656 if (m[tempR][tempC - 1] != EXITPORT) 657 { 658 m[tempR][tempC - 1] = WEST; 659 } 660 661 tempElem.seat.r = tempR; 662 tempElem.seat.c = tempC - 1; 663 tempElem.direction = m[tempR][tempC - 1]; 664 665 return; 666 } 667 668 if (!(m[tempR][tempC + 1] * m[tempR - 1][tempC] + m[tempR - 1][tempC + 1]) || m[tempR - 1][tempC + 1] == EXITPORT) 669 { 670 // 东北 671 if (m[tempR - 1][tempC + 1] != EXITPORT) 672 { 673 m[tempR - 1][tempC + 1] = NORTHEAST; 674 } 675 676 tempElem.seat.r = tempR - 1; 677 tempElem.seat.c = tempC + 1; 678 tempElem.direction = m[tempR - 1][tempC + 1]; 679 680 return; 681 } 682 683 if (!(m[tempR][tempC - 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC - 1]) || m[tempR + 1][tempC - 1] == EXITPORT) 684 { 685 // 西南 686 if (m[tempR + 1][tempC - 1] != EXITPORT) 687 { 688 m[tempR + 1][tempC - 1] = SOUTHWEST; 689 } 690 691 tempElem.seat.r = tempR + 1; 692 tempElem.seat.c = tempC - 1; 693 tempElem.direction = m[tempR + 1][tempC - 1]; 694 695 return; 696 } 697 698 if (m[tempR + 1][tempC] == SPACE || m[tempR + 1][tempC] == EXITPORT) 699 { 700 // 南 701 if (m[tempR + 1][tempC] != EXITPORT) 702 { 703 m[tempR + 1][tempC] = SOUTH; 704 } 705 706 tempElem.seat.r = tempR + 1; 707 tempElem.seat.c = tempC; 708 tempElem.direction = m[tempR + 1][tempC]; 709 710 return; 711 } 712 713 if (m[tempR][tempC + 1] == SPACE || m[tempR][tempC + 1] == EXITPORT) 714 { 715 // 东 716 if (m[tempR][tempC + 1] != EXITPORT) 717 { 718 m[tempR][tempC + 1] = EAST; 719 } 720 721 tempElem.seat.r = tempR; 722 tempElem.seat.c = tempC + 1; 723 tempElem.direction = m[tempR][tempC + 1]; 724 725 return; 726 } 727 728 if (!(m[tempR][tempC + 1] * m[tempR + 1][tempC] + m[tempR + 1][tempC + 1]) || m[tempR + 1][tempC + 1] == EXITPORT) 729 { 730 // 东南 // 逻辑计算 ((!a || !b) && !c) || d == !(a * b + c) || d 731 if (m[tempR + 1][tempC + 1] != EXITPORT) 732 { 733 m[tempR + 1][tempC + 1] = SOUTHEAST; 734 } 735 736 tempElem.seat.r = tempR + 1; 737 tempElem.seat.c = tempC + 1; 738 tempElem.direction = m[tempR + 1][tempC + 1]; 739 740 return; 741 } 742 } 743 744 bool Maze::pass(PosType p) 745 { 746 assert(p.r >= 0 && p.c >= 0 && p.r < r + 2 && p.c < c + 2); 747 return m[p.r][p.c] == 0; 748 } 749 750 Maze::~Maze() 751 { 752 for (int i = 0; i < r + 2 ; i++) 753 delete [] m[i]; 754 755 delete m; 756 }
测试用例:
迷宫 1
3 2
0
0 0
0 0
0 0
1 1
3 2
迷宫 2
3 4
0
0 0 0 0
0 0 1 1
0 0 0 0
1 1
3 4
迷宫 3
9 8
0
0 0 1 0 0 0 1 0
0 0 1 0 0 0 1 0
0 0 0 0 1 1 0 1
0 1 1 1 0 0 1 0
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 1
0 1 1 1 1 0 0 1
1 1 0 0 0 1 0 1
1 1 0 0 0 0 0 0
1 1
9 8
迷宫 4
4 9
0
0 0 0 0 0 0 1 0 0
0 1 0 0 0 1 0 0 0
0 0 1 1 1 0 0 1 1
0 0 1 1 1 0 1 0 0
1 1
4 9
自动生成迷宫:
30 30
1
1 1