/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at
golgotha_source@usa.net (Subject should have "GOLG" in it)
***********************************************************************/
#include "solvemap_breadth.hh"
#include "path_api.hh"
#include "memory/malloc.hh"
#include "error/error.hh"
void g1_breadth_first_map_solver_class::set_block_map(g1_block_map_class *_block)
//{{{
{
block = _block;
if (!solve_map || block->width()!=wx || block->height()!=wy)
{
if (solve_map)
i4_free(solve_map);
wx = block->width();
wy = block->height();
solve_map = (w8*)i4_malloc(wx*wy,"solve_map");
}
}
//}}}
g1_breadth_first_map_solver_class::~g1_breadth_first_map_solver_class()
//{{{
{
if (solve_map)
i4_free(solve_map);
}
//}}}
i4_bool g1_breadth_first_map_solver_class::add_cell(w32 x,w32 y,w8 d, w32 length)
//{{{
{
if (d>0 &&
(x<0 || x>=wx || y<0 || y>=wy || is_visited(x,y) || block->is_blocked(x,y,d)))
return i4_F;
set_solve_dir(x,y,d);
visit(x,y);
cnx[head] = x;
cny[head] = y;
cnl[head] = length;
if (++head>=queue_length) head=0;
if (head==tail)
i4_warning("queue overrun.");
return i4_T;
}
//}}}
i4_bool g1_breadth_first_map_solver_class::get_next_cell(w32 &x,w32 &y, w32 &length)
//{{{
{
if (tail==head)
return i4_F;
x = cnx[tail];
y = cny[tail];
length = cnl[tail];
if (++tail>=queue_length) tail=0;
return i4_T;
}
//}}}
i4_bool g1_breadth_first_map_solver_class::path_solve(w32 startx, w32 starty,
w32 destx, w32 desty,
w8 sizex, w8 sizey, w8 grade,
i4_float *point, w16 &points)
//{{{
{
w32 x,y,l;
clear_queue();
clear_solve();
add_cell(startx,
starty,
0,0);
int found=0;
while (get_next_cell(x,y,l) && (x!=destx || y!=desty))
{
add_cell(x,y-1,G1_NORTH,l+1);
add_cell(x,y+1,G1_SOUTH,l+1);
add_cell(x+1,y,G1_WEST,l+1);
add_cell(x-1,y,G1_EAST,l+1);
}
x = destx;
y = desty;
w32 last_dir=0;
points = 0;
if (solve_dir(x,y)==0)
return i4_F;
while (x!=startx || y!=starty)
{
ok(x,y);
if (solve_dir(x,y)!=last_dir)
{
last_dir = solve_dir(x,y);
point[points*2]= i4_float(x)+0.5;
point[points*2+1]= i4_float(y)+0.5;
points++;
}
switch (solve_dir(x,y))
{
case G1_NORTH: y++; break;
case G1_SOUTH: y--; break;
case G1_WEST: x--; break;
case G1_EAST: x++; break;
default:
I4_ASSERT(0,"busted path solving!\n");
break;
}
}
ok(x,y);
point[points*2]= i4_float(x)+0.5;
point[points*2+1]=i4_float(y)+0.5;
points++;
return i4_T;
}
//}}}
//{{{ Emacs Locals
// Local Variables:
// folded-file: t
// End:
//}}}