0

I am currently programming a little game for the console with an 2D map. 2 Elements of my game are: destroying fields and an enemy, which spreads in a random direction (its getting bigger). These two "entities" are saved in a structure which contains two vectors (X and Y). I am now trying to erase an element of "_Enemy"(<-private instance of the structure in a class, same as "_DestroyedFields") if you destroy the field where the enemy is.

I tried a lot of different variations to do so and whats giving me the error least is this method (I already searched the internet for a while now an couldn't find a answer to my question):

for (std::vector<int>::iterator itEX = _Enemys.X.begin(), itEY = _Enemys.Y.begin(); itEX != _Enemys.X.end() && itEY != _Enemys.Y.end(); ++itEX, ++itEY) { for (std::vector<int>::iterator itX = _DestroyedFields.X.begin(), itY = _DestroyedFields.Y.begin(); itX != _DestroyedFields.X.end() && itY != _DestroyedFields.Y.end(); ++itX, ++itY) { if (*itY == *itEY && *itX == *itEX){ itEY = _Enemys.Y.erase(itEY); itEX = _Enemys.X.erase(itEX); } } } 

PS: sorry if my english isn't the best, im german ^^

PSS: if you wanna watch over my whole code, you can find it on Github: https://github.com/Aemmel/ConsoleGame1

11
  • Currently, you increase your iterator when you do the erase... Commented Apr 18, 2014 at 15:10
  • I suggest to use a simple struct for position. Commented Apr 18, 2014 at 15:14
  • @Jarod42 whar do you mean with simple struct? Commented Apr 18, 2014 at 15:22
  • Which double for loop implementation is being used? The version on git assumes that X and Y are always the same size. The one above should be a better way to search for the correct elements. Commented Apr 18, 2014 at 15:44
  • @CPlusPlusOOAandD Whoops, didn't notice it wasn't the same ^^. The example above is used. Commented Apr 18, 2014 at 15:49

3 Answers 3

2

After erasing using iterator it, you cannot use it further as it is invalidated. You should use a result of a call to erase which is new, valid iterator.

for( it = v.begin(); it != v.end();) { //... if(...) { it = v.erase( it); } else { ++it; } ... } 
Sign up to request clarification or add additional context in comments.

2 Comments

Doesn't work, it gives out the error: "vector iterator not dereferencable"
using your method instead of mine with _Enemys(so itEX and itEY). And I think it always crashes in the if statement (I'm printing out when it erases and in the else statement and it stops printing after the if-statement, when the condition is true)
0

I fixed the bug with first: making a "simple structure"(struct Entity{int X; intY} and then std::vector [insert name here]) and then with adding an break; if the condition is true.

for (Uint itE = 0; itE < _Enemys.size(); ++itE){ for (Uint it = 0; it<_DestroyedFields.size(); ++it){ if (_Enemys.at(itE).Y == _DestroyedFields.at(it).Y && _Enemys.at(itE).X == _DestroyedFields.at(it).X){ _Enemys.erase(_Enemys.begin()+itE); break; } } } 

2 Comments

If you add bool operator == (const Position& lhs, const Position& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; }, then you may write the condition : _Enemys.at(itE) == _DestroyedFields.at(it) (or with [] : _Enemys[itE] == _DestroyedFields[it])
BTW, you still increase itE when you erase, so you may miss the removal of successive elements.
0

With struct Position {int x; int y;}; and some utility operators,
you may do one of the following: (https://ideone.com/0aiih0)

void filter(std::vector<Position>& positions, const std::vector<Position>& destroyedFields) { for (std::vector<Position>::iterator it = positions.begin(); it != positions.end(); ) { if (std::find(destroyedFields.begin(), destroyedFields.end(), *it) != destroyedFields.end()) { it = positions.erase(it); } else { ++it; } } } 

Or, if input are sorted, you may use a 'difference':

std::vector<Position> filter2(const std::vector<Position>& positions, const std::vector<Position>& destroyedFields) { std::vector<Position> res; std::set_difference(positions.begin(), positions.end(), destroyedFields.begin(), destroyedFields.end(), std::back_inserter(res)); return res; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.