mirror of
https://github.com/glest/glest-source.git
synced 2025-02-25 04:02:30 +01:00
* 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
133 lines
3.8 KiB
C++
133 lines
3.8 KiB
C++
// ==============================================================
|
|
// This file is part of Glest (www.glest.org)
|
|
//
|
|
// Copyright (C) 2009 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
|
|
// ==============================================================
|
|
//
|
|
// File: node_pool.cpp
|
|
//
|
|
#include "node_pool.h"
|
|
#include "world.h"
|
|
#include "map.h"
|
|
|
|
namespace Glest { namespace Game {
|
|
|
|
// =====================================================
|
|
// class NodePool
|
|
// =====================================================
|
|
|
|
NodePool::NodePool(int w, int h)
|
|
: counter(0)
|
|
, leastH(NULL)
|
|
, numNodes(0)
|
|
, tmpMaxNodes(size)
|
|
, markerArray(w, h) {
|
|
stock = new AStarNode[size];
|
|
}
|
|
|
|
NodePool::~NodePool() {
|
|
delete [] stock;
|
|
}
|
|
|
|
/** reset the node pool for a new search (resets tmpMaxNodes too) */
|
|
void NodePool::reset() {
|
|
numNodes = 0;
|
|
counter = 0;
|
|
tmpMaxNodes = size;
|
|
leastH = NULL;
|
|
markerArray.newSearch();
|
|
openHeap.clear();
|
|
//IF_DEBUG_EDITION( listedNodes.clear(); )
|
|
}
|
|
/** set a maximum number of nodes to expand */
|
|
void NodePool::setMaxNodes(const int max) {
|
|
assert(max >= 32 && max <= size); // reasonable number ?
|
|
assert(!numNodes); // can't do this after we've started using it.
|
|
tmpMaxNodes = max;
|
|
}
|
|
|
|
/** marks an unvisited position as open
|
|
* @param pos the position to open
|
|
* @param prev the best known path to pos is from
|
|
* @param h the heuristic for pos
|
|
* @param d the costSoFar for pos
|
|
* @return true if added, false if node limit reached */
|
|
bool NodePool::setOpen(const Vec2i &pos, const Vec2i &prev, float h, float d) {
|
|
assert(!isOpen(pos));
|
|
AStarNode *node = newNode();
|
|
if (!node) { // NodePool exhausted
|
|
return false;
|
|
}
|
|
//IF_DEBUG_EDITION( listedNodes.push_back(pos); )
|
|
node->posOff = pos;
|
|
if (prev.x >= 0) {
|
|
node->posOff.ox = prev.x - pos.x;
|
|
node->posOff.oy = prev.y - pos.y;
|
|
} else {
|
|
node->posOff.ox = 0;
|
|
node->posOff.oy = 0;
|
|
}
|
|
node->distToHere = d;
|
|
node->heuristic = h;
|
|
addOpenNode(node);
|
|
if (!numNodes || h < leastH->heuristic) {
|
|
leastH = node;
|
|
}
|
|
numNodes++;
|
|
return true;
|
|
}
|
|
|
|
/** add a new node to the open list @param node pointer to the node to add */
|
|
void NodePool::addOpenNode(AStarNode *node) {
|
|
assert(!isOpen(node->pos()));
|
|
markerArray.setOpen(node->pos());
|
|
markerArray.set(node->pos(), node);
|
|
openHeap.insert(node);
|
|
}
|
|
|
|
/** conditionally update a node on the open list. Tests if a path through a new nieghbour
|
|
* is better than the existing known best path to pos, updates if so.
|
|
* @param pos the open postion to test
|
|
* @param prev the new path from
|
|
* @param d the distance to here through prev */
|
|
void NodePool::updateOpen(const Vec2i &pos, const Vec2i &prev, const float cost) {
|
|
//assert(isClosed(prev));
|
|
AStarNode *posNode, *prevNode;
|
|
posNode = markerArray.get(pos);
|
|
prevNode = markerArray.get(prev);
|
|
if (prevNode->distToHere + cost < posNode->distToHere) {
|
|
posNode->posOff.ox = prev.x - pos.x;
|
|
posNode->posOff.oy = prev.y - pos.y;
|
|
posNode->distToHere = prevNode->distToHere + cost;
|
|
openHeap.promote(posNode);
|
|
}
|
|
}
|
|
|
|
#if _GAE_DEBUG_EDITION_
|
|
|
|
list<Vec2i>* NodePool::getOpenNodes() {
|
|
list<Vec2i> *ret = new list<Vec2i>();
|
|
list<Vec2i>::iterator it = listedNodes.begin();
|
|
for ( ; it != listedNodes.end (); ++it) {
|
|
if (isOpen(*it)) ret->push_back(*it);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
list<Vec2i>* NodePool::getClosedNodes() {
|
|
list<Vec2i> *ret = new list<Vec2i>();
|
|
list<Vec2i>::iterator it = listedNodes.begin();
|
|
for ( ; it != listedNodes.end(); ++it) {
|
|
if (isClosed(*it)) ret->push_back(*it);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#endif // _GAE_DEBUG_EDITION_
|
|
|
|
}} |