diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 9876f945e..f8dd974c3 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -395,7 +395,7 @@ bool BattleInfo::isAccessible(int hex, bool * accessibility, bool twoHex, bool a } } -void BattleInfo::makeBFS(int start, bool *accessibility, int *predecessor, int *dists, bool twoHex, bool attackerOwned, bool flying) const //both pointers must point to the at least 187-elements int arrays +void BattleInfo::makeBFS(int start, bool *accessibility, int *predecessor, int *dists, bool twoHex, bool attackerOwned, bool flying, bool fillPredecessors) const //both pointers must point to the at least 187-elements int arrays { //inits for(int b=0; b hexq; //bfs queue - hexq.push(start); - dists[hexq.front()] = 0; + std::queue< std::pair > hexq; //bfs queue (second filed used only if fillPredecessors is true) + hexq.push(std::make_pair(start, true)); + dists[hexq.front().first] = 0; int curNext = -1; //for bfs loop only (helper var) while(!hexq.empty()) //bfs loop { - int curHex = hexq.front(); - std::vector neighbours = neighbouringTiles(curHex); + std::pair curHex = hexq.front(); + std::vector neighbours = neighbouringTiles(curHex.first); hexq.pop(); for(unsigned int nr=0; nr=dists[curNext]) - bool accessible = isAccessible(curNext, accessibility, twoHex, attackerOwned, flying, dists[curHex]+1 == dists[curNext]); - if( dists[curHex]+1 >= dists[curNext] ) + bool accessible = isAccessible(curNext, accessibility, twoHex, attackerOwned, flying, dists[curHex.first]+1 == dists[curNext]); + if( dists[curHex.first]+1 >= dists[curNext] ) continue; - if(accessible) + if(accessible && curHex.second) { - hexq.push(curNext); - dists[curNext] = dists[curHex] + 1; + hexq.push(std::make_pair(curNext, true)); + dists[curNext] = dists[curHex.first] + 1; } - predecessor[curNext] = curHex; + else if(fillPredecessors && !(accessible && !curHex.second)) + { + hexq.push(std::make_pair(curNext, false)); + dists[curNext] = dists[curHex.first] + 1; + } + predecessor[curNext] = curHex.first; } } }; @@ -442,7 +447,7 @@ std::vector BattleInfo::getAccessibility(int stackID, bool addOccupiable) c getAccessibilityMap(ac, s->hasFeatureOfType(StackFeature::DOUBLE_WIDE), s->attackerOwned, addOccupiable, occupyable, s->hasFeatureOfType(StackFeature::FLYING), stackID); int pr[BFIELD_SIZE], dist[BFIELD_SIZE]; - makeBFS(s->position, ac, pr, dist, s->hasFeatureOfType(StackFeature::DOUBLE_WIDE), s->attackerOwned, s->hasFeatureOfType(StackFeature::FLYING)); + makeBFS(s->position, ac, pr, dist, s->hasFeatureOfType(StackFeature::DOUBLE_WIDE), s->attackerOwned, s->hasFeatureOfType(StackFeature::FLYING), false); if(s->hasFeatureOfType(StackFeature::DOUBLE_WIDE)) { @@ -548,7 +553,7 @@ std::pair< std::vector, int > BattleInfo::getPath(int start, int dest, bool int predecessor[BFIELD_SIZE]; //for getting the Path int dist[BFIELD_SIZE]; //calculated distances - makeBFS(start, accessibility, predecessor, dist, twoHex, attackerOwned, flyingCreature); + makeBFS(start, accessibility, predecessor, dist, twoHex, attackerOwned, flyingCreature, false); if(predecessor[dest] == -1) //cannot reach destination { @@ -2568,7 +2573,7 @@ std::pair BattleInfo::getNearestStack(const CStack * closes getAccessibilityMap(ac, closest->hasFeatureOfType(StackFeature::DOUBLE_WIDE), closest->attackerOwned, false, occupyable, closest->hasFeatureOfType(StackFeature::FLYING), closest->ID); int predecessor[BFIELD_SIZE], dist[BFIELD_SIZE]; - makeBFS(closest->position, ac, predecessor, dist, closest->hasFeatureOfType(StackFeature::DOUBLE_WIDE), closest->attackerOwned, closest->hasFeatureOfType(StackFeature::FLYING)); + makeBFS(closest->position, ac, predecessor, dist, closest->hasFeatureOfType(StackFeature::DOUBLE_WIDE), closest->attackerOwned, closest->hasFeatureOfType(StackFeature::FLYING), true); std::vector< std::pair< std::pair, const CStack *> > stackPairs; //pairs <, stack> for(int g=0; g BattleInfo::getNearestStack(const CStack * closes if(stackPairs.size() > 0) { - std::pair< std::pair, const CStack *> minimalPair = stackPairs[0]; + std::vector< std::pair< std::pair, const CStack *> > minimalPairs; + minimalPairs.push_back(stackPairs[0]); for(int b=1; b, const CStack *> minPair = minimalPairs[minimalPairs.size()/2]; + + return std::make_pair(minPair.second, predecessor[minPair.first.second]); } return std::make_pair(NULL, -1); diff --git a/lib/CGameState.h b/lib/CGameState.h index 30dcb5f07..7f7a2fad5 100644 --- a/lib/CGameState.h +++ b/lib/CGameState.h @@ -143,7 +143,7 @@ struct DLL_EXPORT BattleInfo const CStack * getStackT(int tileID, bool onlyAlive = true) const; void getAccessibilityMap(bool *accessibility, bool twoHex, bool attackerOwned, bool addOccupiable, std::set & occupyable, bool flying, int stackToOmmit=-1) const; //send pointer to at least 187 allocated bytes static bool isAccessible(int hex, bool * accessibility, bool twoHex, bool attackerOwned, bool flying, bool lastPos); //helper for makeBFS - void makeBFS(int start, bool*accessibility, int *predecessor, int *dists, bool twoHex, bool attackerOwned, bool flying) const; //*accessibility must be prepared bool[187] array; last two pointers must point to the at least 187-elements int arrays - there is written result + void makeBFS(int start, bool*accessibility, int *predecessor, int *dists, bool twoHex, bool attackerOwned, bool flying, bool fillPredecessors) const; //*accessibility must be prepared bool[187] array; last two pointers must point to the at least 187-elements int arrays - there is written result std::pair< std::vector, int > getPath(int start, int dest, bool*accessibility, bool flyingCreature, bool twoHex, bool attackerOwned); //returned value: pair; length may be different than number of elements in path since flying vreatures jump between distant hexes std::vector getAccessibility(int stackID, bool addOccupiable) const; //returns vector of accessible tiles (taking into account the creature range)