/* * ksokoban - a Sokoban game for TDE * Copyright (C) 1998 Anders Widell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ //#include #include "PathFinder.h" #include "LevelMap.h" #include "Queue.h" #include "Move.h" void PathFinder::BFS (int _x, int _y) { Queue xq; Queue yq; Queue dq; int x, y, d; xq.enqueue (_x); yq.enqueue (_y); dq.enqueue (1); while (!xq.empty ()) { x = xq.dequeue (); y = yq.dequeue (); d = dq.dequeue (); if (x<0 || x>MAX_X || y<0 || y>MAX_Y || dist[y][x]) continue; dist[y][x] = d; xq.enqueue (x); xq.enqueue (x); xq.enqueue (x-1); xq.enqueue (x+1); yq.enqueue (y-1); yq.enqueue (y+1); yq.enqueue (y); yq.enqueue (y); dq.enqueue (d+1); dq.enqueue (d+1); dq.enqueue (d+1); dq.enqueue (d+1); } } Move * PathFinder::search (Map *_map, int _x, int _y) { int xpos=_map->xpos (); int ypos=_map->ypos (); if (xpos == _x && ypos == _y) return 0; for (int y=0; y<=MAX_Y; y++) { for (int x=0; x<=MAX_X; x++) { if (_map->empty (x, y)) dist[y][x] = 0; else dist[y][x] = PATH_WALL; } } BFS (_x, _y); #if 0 for (int y=0; y<=MAX_Y; y++) { for (int x=0; x<=MAX_X; x++) { //if (x==_x && y==_y) {printf ("++ "); continue;} //if (x==xpos && y==ypos) {printf ("@@ "); continue;} if (dist[y][x] == PATH_WALL) {printf ("## "); continue;} printf ("%02d ", dist[y][x]); } printf ("\n"); } #endif int d; Move *move=new Move (xpos, ypos); int oldX, oldY; for (;;) { oldX = xpos; oldY = ypos; if (xpos == _x && ypos == _y) { move->finish (); //printf ("move->finish ()\n"); return move; } d = dist[ypos][xpos]; while (ypos-1 >= 0 && dist[ypos-1][xpos] < d) { ypos--; d = dist[ypos][xpos]; } if (oldY != ypos) { move->step (xpos, ypos); //printf ("step (%d, %d)\n", xpos, ypos); continue; } while (ypos+1 <= MAX_Y && dist[ypos+1][xpos] < d) { ypos++; d = dist[ypos][xpos]; } if (oldY != ypos) { move->step (xpos, ypos); //printf ("step (%d, %d)\n", xpos, ypos); continue; } while (xpos-1 >= 0 && dist[ypos][xpos-1] < d) { xpos--; d = dist[ypos][xpos]; } if (oldX != xpos) { move->step (xpos, ypos); //printf ("step (%d, %d)\n", xpos, ypos); continue; } while (xpos+1 <= MAX_X && dist[ypos][xpos+1] < d) { xpos++; d = dist[ypos][xpos]; } if (oldX != xpos) { move->step (xpos, ypos); //printf ("step (%d, %d)\n", xpos, ypos); continue; } delete move; return 0; } } Move* PathFinder::drag(int /* x1 */, int /* y1 */, int /* x2 */, int /* y2 */) { return 0; } bool PathFinder::canDrag(int /* x */, int /* y */) const { return false; } bool PathFinder::canWalkTo(int /* x */, int /* y */) const { return false; } bool PathFinder::canDragTo(int /* x */, int /* y */) const { return false; } void PathFinder::updatePossibleMoves() { } void PathFinder::updatePossibleDestinations(int /* x */, int /* y */) { }