|
|
|
/*
|
|
|
|
* ksokoban - a Sokoban game for TDE
|
|
|
|
* Copyright (C) 1998 Anders Widell <d95-awi@nada.kth.se>
|
|
|
|
*
|
|
|
|
* 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 <stdio.h>
|
|
|
|
#include "PathFinder.h"
|
|
|
|
#include "LevelMap.h"
|
|
|
|
#include "Queue.h"
|
|
|
|
#include "Move.h"
|
|
|
|
|
|
|
|
void
|
|
|
|
PathFinder::BFS (int _x, int _y) {
|
|
|
|
Queue<int, 10> xq;
|
|
|
|
Queue<int, 10> yq;
|
|
|
|
Queue<int, 10> 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 */) {
|
|
|
|
}
|
|
|
|
|