You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegames/ksokoban/PathFinder.cpp

177 lines
3.8 KiB

/*
* ksokoban - a Sokoban game for KDE
* 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 */) {
}