File indexing completed on 2025-03-09 03:49:43
0001 /* 0002 SPDX-FileCopyrightText: 1998 Anders Widell <d95-awi@nada.kth.se> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "PathFinder.h" 0008 0009 #include "LevelMap.h" 0010 #include "Move.h" 0011 #include "Queue.h" 0012 0013 //#include <cstdio> 0014 0015 static constexpr int PATH_WALL = 32767; 0016 0017 void PathFinder::BFS(int _x, int _y) 0018 { 0019 Queue<int, 10> xq; 0020 Queue<int, 10> yq; 0021 Queue<int, 10> dq; 0022 int x, y, d; 0023 0024 xq.enqueue(_x); 0025 yq.enqueue(_y); 0026 dq.enqueue(1); 0027 0028 while (!xq.empty()) { 0029 x = xq.dequeue(); 0030 y = yq.dequeue(); 0031 d = dq.dequeue(); 0032 0033 if (x < 0 || x > Map::MAX_X || y < 0 || y > Map::MAX_Y || dist[y][x]) 0034 continue; 0035 dist[y][x] = d; 0036 0037 xq.enqueue(x); 0038 xq.enqueue(x); 0039 xq.enqueue(x - 1); 0040 xq.enqueue(x + 1); 0041 0042 yq.enqueue(y - 1); 0043 yq.enqueue(y + 1); 0044 yq.enqueue(y); 0045 yq.enqueue(y); 0046 0047 dq.enqueue(d + 1); 0048 dq.enqueue(d + 1); 0049 dq.enqueue(d + 1); 0050 dq.enqueue(d + 1); 0051 } 0052 } 0053 0054 Move *PathFinder::search(const Map *_map, int _x, int _y) 0055 { 0056 int xpos = _map->xpos(); 0057 int ypos = _map->ypos(); 0058 if (xpos == _x && ypos == _y) 0059 return nullptr; 0060 0061 for (int y = 0; y <= Map::MAX_Y; y++) { 0062 for (int x = 0; x <= Map::MAX_X; x++) { 0063 if (_map->empty(x, y)) 0064 dist[y][x] = 0; 0065 else 0066 dist[y][x] = PATH_WALL; 0067 } 0068 } 0069 0070 BFS(_x, _y); 0071 0072 #if 0 0073 for (int y=0; y<=Map::MAX_Y; y++) { 0074 for (int x=0; x<=Map::MAX_X; x++) { 0075 //if (x==_x && y==_y) {printf ("++ "); continue;} 0076 //if (x==xpos && y==ypos) {printf ("@@ "); continue;} 0077 if (dist[y][x] == PATH_WALL) {printf ("## "); continue;} 0078 printf ("%02d ", dist[y][x]); 0079 } 0080 printf ("\n"); 0081 } 0082 #endif 0083 0084 int d; 0085 auto *move = new Move(xpos, ypos); 0086 int oldX, oldY; 0087 for (;;) { 0088 oldX = xpos; 0089 oldY = ypos; 0090 0091 if (xpos == _x && ypos == _y) { 0092 move->finish(); 0093 // printf ("move->finish ()\n"); 0094 return move; 0095 } 0096 0097 d = dist[ypos][xpos]; 0098 0099 while (ypos - 1 >= 0 && dist[ypos - 1][xpos] < d) { 0100 ypos--; 0101 d = dist[ypos][xpos]; 0102 } 0103 if (oldY != ypos) { 0104 move->step(xpos, ypos); 0105 // printf ("step (%d, %d)\n", xpos, ypos); 0106 continue; 0107 } 0108 0109 while (ypos + 1 <= Map::MAX_Y && dist[ypos + 1][xpos] < d) { 0110 ypos++; 0111 d = dist[ypos][xpos]; 0112 } 0113 if (oldY != ypos) { 0114 move->step(xpos, ypos); 0115 // printf ("step (%d, %d)\n", xpos, ypos); 0116 continue; 0117 } 0118 0119 while (xpos - 1 >= 0 && dist[ypos][xpos - 1] < d) { 0120 xpos--; 0121 d = dist[ypos][xpos]; 0122 } 0123 if (oldX != xpos) { 0124 move->step(xpos, ypos); 0125 // printf ("step (%d, %d)\n", xpos, ypos); 0126 continue; 0127 } 0128 0129 while (xpos + 1 <= Map::MAX_X && dist[ypos][xpos + 1] < d) { 0130 xpos++; 0131 d = dist[ypos][xpos]; 0132 } 0133 if (oldX != xpos) { 0134 move->step(xpos, ypos); 0135 // printf ("step (%d, %d)\n", xpos, ypos); 0136 continue; 0137 } 0138 0139 delete move; 0140 return nullptr; 0141 } 0142 } 0143 0144 Move *PathFinder::drag(int /* x1 */, int /* y1 */, int /* x2 */, int /* y2 */) 0145 { 0146 return nullptr; 0147 } 0148 0149 bool PathFinder::canDrag(int /* x */, int /* y */) const 0150 { 0151 return false; 0152 } 0153 0154 bool PathFinder::canWalkTo(int /* x */, int /* y */) const 0155 { 0156 return false; 0157 } 0158 0159 bool PathFinder::canDragTo(int /* x */, int /* y */) const 0160 { 0161 return false; 0162 } 0163 0164 void PathFinder::updatePossibleMoves() 0165 { 0166 } 0167 0168 void PathFinder::updatePossibleDestinations(int /* x */, int /* y */) 0169 { 0170 }