* added GAE path finder (SearchEngine and friends)

* some small changes to Unit, UnitType, Vec2<> & Map needed for the new path finder
 * compiles, but not hooked up yet, old PathFinder still in use
This commit is contained in:
James McCulloch
2010-07-11 18:31:02 +00:00
parent 277230657c
commit bdd4f306f4
35 changed files with 5547 additions and 76 deletions

View File

@@ -0,0 +1,119 @@
// ==============================================================
// This file is part of the Glest Advanced Engine
//
// Copyright (C) 2010 James McCulloch <silnarm at gmail>
//
// You can redistribute this code 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
// ==============================================================
#ifndef _MIN_HEAP_INCLUDED_
#define _MIN_HEAP_INCLUDED_
#include <cassert>
namespace Shared { namespace Util {
/** 'Nodes' nead to implement this implicit interface:
struct SomeNode {
void setHeapIndex(int ndx); // typically, { heap_ndx = ndx; }
int getHeapIndex() const; // typically, { return heap_ndx; }
bool operator<(const SomeNode &that) const;
};
*/
/** (Min) Heap, supporting node 'index awareness'.
* stores pointers to Nodes, user needs to supply the actual nodes, preferably in single block
* of memory, and preferably with as compact a node structure as is possible (to the point that the
* int 'heap_ndx' should be a bitfield using as few bits as you can get away with).
*/
template<typename Node> class MinHeap {
private:
Node** data;
int counter;
int capacity;
public:
/** Construct MinHeap with a given capacity */
MinHeap(int capacity = 1024) : counter(0), capacity(capacity) {
data = new Node*[capacity];
}
~MinHeap() {
delete [] data;
}
/** add a new node to the min heap */
bool insert(Node *node) {
if (counter == capacity) {
return false;
}
data[counter] = node;
data[counter]->setHeapIndex(counter);
promoteNode(counter++);
return true;
}
/** pop the best node off the min heap */
Node* extract() {
assert(counter);
Node *res = data[0];
if (--counter) {
data[0] = data[counter];
data[0]->setHeapIndex(0);
demoteNode();
}
return res;
}
/** indicate a node has had its key decreased */
void promote(Node *node) {
assert(data[node->getHeapIndex()] == node);
promoteNode(node->getHeapIndex());
}
int size() const { return counter; }
void clear() { counter = 0; }
bool empty() const { return !counter; }
private:
inline int parent(int ndx) const { return (ndx - 1) / 2; }
inline int left(int ndx) const { return (ndx * 2) + 1; }
void promoteNode(int ndx) {
assert(ndx >= 0 && ndx < counter);
while (ndx > 0 && *data[ndx] < *data[parent(ndx)]) {
Node *tmp = data[parent(ndx)];
data[parent(ndx)] = data[ndx];
data[ndx] = tmp;
data[ndx]->setHeapIndex(ndx);
ndx = parent(ndx);
data[ndx]->setHeapIndex(ndx);
}
}
void demoteNode(int ndx = 0) {
assert(counter);
while (true) {
int cndx = left(ndx); // child index
int sndx = ndx; // smallest (priority) of data[ndx] and any children
if (cndx < counter && *data[cndx] < *data[ndx]) sndx = cndx;
if (++cndx < counter && *data[cndx] < *data[sndx]) sndx = cndx;
if (sndx == ndx) return;
Node *tmp = data[sndx];
data[sndx] = data[ndx];
data[ndx] = tmp;
data[ndx]->setHeapIndex(ndx);
ndx = sndx;
data[ndx]->setHeapIndex(ndx);
}
}
};
}} // end namespace Shared::Util
#endif // _MIN_HEAP_INCLUDED_

View File

@@ -0,0 +1,83 @@
// ==============================================================
// This file is part of the Glest Advanced Engine
//
// Copyright (C) 2010 James McCulloch <silnarm at gmail>
//
// You can redistribute this code 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
// ==============================================================
#ifndef _LINE_ALGORITHM_INCLUDED_
#define _LINE_ALGORITHM_INCLUDED_
#include <cassert>
namespace Shared { namespace Util {
/** midpoint line algorithm, 'Visit' specifies the 'pixel visit' function, *
* and must take two int params (x & y co-ords) */
template<typename VisitFunc> void line(int x0, int y0, int x1, int y1, VisitFunc visitor) {
bool mirror_x, mirror_y;
int pivot_x, pivot_y;
if (x0 > x1) {
mirror_x = true;
pivot_x = x0;
x1 = (x0 << 1) - x1;
} else {
mirror_x = false;
}
if (y0 > y1) {
mirror_y = true;
pivot_y = y0;
y1 = (y0 << 1) - y1;
} else {
mirror_y = false;
}
// Visit(x,y) => Visit(mirror_x ? (pivot_x << 1) - x : x, mirror_y ? (pivot_y << 1) - y : y);
assert(y0 <= y1 && x0 <= x1);
int dx = x1 - x0,
dy = y1 - y0;
int x = x0,
y = y0;
if (dx == 0) {
while (y <= y1) {
visitor(mirror_x ? (pivot_x << 1) - x : x, mirror_y ? (pivot_y << 1) - y : y);
++y;
}
} else if (dy == 0) {
while (x <= x1) {
visitor(mirror_x ? (pivot_x << 1) - x : x, mirror_y ? (pivot_y << 1) - y : y);
++x;
}
} else if (dy > dx) {
int d = 2 * dx - dy;
int incrS = 2 * dx;
int incrSE = 2 * (dx - dy);
do {
visitor(mirror_x ? (pivot_x << 1) - x : x, mirror_y ? (pivot_y << 1) - y : y);
if (d <= 0) {
d += incrS; ++y;
} else {
d += incrSE; ++x; ++y;
}
} while (y <= y1);
} else {
int d = 2 * dy - dx;
int incrE = 2 * dy;
int incrSE = 2 * (dy - dx);
do {
visitor(mirror_x ? (pivot_x << 1) - x : x, mirror_y ? (pivot_y << 1) - y : y);
if (d <= 0) {
d += incrE; ++x;
} else {
d += incrSE; ++x; ++y;
}
} while (x <= x1);
}
}
}} // end namespace Shared::Util
#endif // !def _LINE_ALGORITHM_INCLUDED_