Find coordinates in a vector c++ - c++

I'm creating a game in Qt in c++, and I store every coordinate of specific size into a vector like :
std::vector<std::unique_ptr<Tile>> all_tiles = createWorld(bgTile);
for(auto & tile : all_tiles) {
tiles.push_back(std::move(tile));
}
Each level also has some healthpacks which are stored in a vector aswell.
std::vector<std::unique_ptr<Enemy>> all_enemies = getEnemies(nrOfEnemies);
for(auto &healthPackUniquePtr : all_healthpacks) {
std::shared_ptr<Tile> healthPackPtr{std::move(healthPackUniquePtr)};
int x = healthPackPtr->getXPos();
int y = healthPackPtr->getYPos();
int newYpos=checkOverlapPos(healthPackPtr->getXPos(),healthPackPtr->getYPos());
newYpos = checkOverlapEnemy(healthPackPtr->getXPos(),newYpos);
auto healthPack = std::make_shared<HealthPack>(healthPackPtr->getXPos(), newYpos, healthPackPtr->getValue());
healthPacks.push_back(healthPack);
}
But know I'm searching for the fastest way to check if my player position is at an healthpack position. So I have to search on 2 values in a vector : x and y position. Anyone a suggestion how to do this?

Your 'real' question:
I have to search on 2 values in a vector : x and y position. Anyone a
suggestion how to do this?"
Is a classic XY question, so I'm ignoring it!
I'm searching for the fastest way to check if my player position is at
an healthpack position.
Now we're talking. The approach you are using now won't scale well as the number of items increase, and you'll need to do something similar for every pair of objects you are interested in. Not good.
Thankfully this problem has been solved (and improved upon) for decades, you need to use a spacial partitioning scheme such as BSP, BVH, quadtree/octree, etc. The beauty of the these schemes is that a single data structure can hold the entire world in it, making arbitrary item intersection queries trivial (and fast).

You can implement a callback system. Then a player moves a tile, fire a callback to that tile which the player is on. Tiles should know its state and could add health to a player or do nothing if there is nothing on that tile. Using this technique, you don`t need searching at all.

If all_leathpacks has less than ~50 elements I wouldn't bother to improve. Simple loop is going to be sufficiently fast.
Otherwise you can split the vector into sectors and check only for the elements in the same sector as your player (and maybe a few around if it's close to the edge).
If you need something that's better for the memory you and use a KD-tree to index the healtpacks and search for them fast (O(logN) time).

Related

Snake game - random number generator for food tiles

I am trying to make a 16x16 LED Snake game using Arduino (C++).
I need to assign a random grid index for the next food tile.
What I have is a list of indices that are occupied by the snake (snakeSquares).
So, my thought is that I need to generate a list of potential foodSquares. Then I can pick a random index from that list, and use the value there for my next food square.
I have some ideas for this but they seem kind of clunky, so I was looking for some feedback. I am using the Arduino LinkedList.h library for my lists in lieu of stdio.h (and random() in place of rand()):
Generate a list (foodSquares) containing the integers [0, 255] so that the indices correspond to the values in the list (I don't know of a quick way to do this, will probably need to use a for loop).
When generating list of snakeSquares, set foodSquares[i] = -1. Afterwards, loop through foodSquares and remove all elements that equal -1.
Then, generate a random number randNum from [0, foodSquares.size()-1] and make the next food square index equal to foodSquares[randNum].
So I guess my question is, will this approach work, and is there a better way to do it?
Thanks.
Potential approach that won't require more lists:
Calculate random integer representing number of steps.
Take head or tail as a starting tile.
For each step move at random free adjacent tile.
I couldn't understand it completely your question as some of those points are quite waste of processor time (i.e. point 1 and 2). But, the first point could be solved quite easily in n proportional complexity as follows:
for (uint8_t i = 0; i < 256; i++) {
// assuming there is a list of food_squares
food_squares[i] = i;
}
Then to the second point you would have to set every food_square to -1, for what? Anyway. A way you could implement this would be as VTT has said and I will describe it further:
Take a random number between [0..255].
Does it is one the snake_squares? If so, back to one, else, go to three.
This is the same as your third point, use this random number to set the position of the food in food_square (food_square[random_number] = some_value).

Where to alter reference code to extract motion vectors from HEVC encoded video

So this question has been asked a few times, but I think my C++ skills are too deficient to really appreciate the answers. What I need is a way to start with an HEVC encoded video and end with CSV that has all the motion vectors. So far, I've compiled and run the reference decoder, everything seems to be working fine. I'm not sure if this matters, but I'm interested in the motion vectors as a convenient way to analyze motion in a video. My plan at first is to average the MVs in each frame to just get a value expressing something about the average amount of movement in that frame.
The discussion here tells me about the TComDataCU class methods I need to interact with to get the MVs and talks about how to iterate over CTUs. But I still don't really understand the following:
1) what information is returned by these MV methods and in what format? With my limited knowledge, I assume that there are going to be something like 7 values associated with the MV: the frame number, an index identifying a macroblock in that frame, the size of the macroblock, the x coordinate of the macroblock (probably the top left corner?), the y coordinate of the macroblock, the x coordinate of the vector, and the y coordinate of the vector.
2) where in the code do I need to put new statements that save the data? I thought there must be some spot in TComDataCU.cpp where I can put lines in that print the data I want to a file, but I'm confused when the values are actually determined and what they are. The variable declarations look like this:
// create motion vector fields
m_pCtuAboveLeft = NULL;
m_pCtuAboveRight = NULL;
m_pCtuAbove = NULL;
m_pCtuLeft = NULL;
But I can't make much sense of those names. AboveLeft, AboveRight, Above, and Left seem like an asymmetric mix of directions?
Any help would be great! I think I would most benefit from seeing some example code. An explanation of the variables I need to pay attention to would also be very helpful.
At TEncSlice.cpp, you can access every CTU in loop
for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )
then you can choose exact CTU by using address of CTU.
pCtu(TComDataCU class)->getCtuRsAddr().
After that,
pCtu->getCUMvField()
will return CTU's motion vector field. You can extract MV of CTU in that object.
For example,
TComMvField->getMv(g_auiRasterToZscan[y * 16 + x])->getHor()
returns specific 4x4 block MV's Horizontal element.
You can save these data after m_pcCuEncoder->compressCtu( pCtu ) because compressCtu determines all data of CTU such as CU partition and motion estimation, etc.
I hope this information helps you and other people!

Sorting objects to the front or back depending on their position

I am trying to sort my renderables/actors correctly and noticed that I have some troubles with walls since they get sorted by their centerpoint. So I am sorting all my actors before I draw them depending on their distance to the camera with an insertion sort. After that, I am trying to determine if the wall should be drawn behind or in front of the gamefield. To explain this, the game takes place inside of a cube which is out of 6 planes. Since I can rotate the camera around that cube I need a sorting which would put the planes in front/back depending on that. So here is a picture so you know what we are talking about:
You can clearly see the rendermisstake whats happening at the front of those kind of snake.
Okay here is my current sorting:
//list of Actors the abstract class which Wall and cube and so on extend
void Group::insertionSort(vector<Actor *> &actors)
{
int j;
for (int i = 1; i < actors.size(); i++)
{
Actor *val = actors[i];
j = i - 1;
while (j >= 0 && distanceToCamera(*actors[j]) < distanceToCamera(*val))
{
actors[j + 1] = actors[j];
j = j - 1;
}
actors[j + 1] = val;
}
}
float Group::distanceToCamera(Actor &a)
{
float result = 0;
XMVECTOR posActor = XMLoadFloat3(&a.getPosition()); //here i get the centerpoint of the object
XMVECTOR posCamera = XMLoadFloat3(&m_camera->getPosition());
XMVECTOR length = XMVector3Length(posCamera - posActor);
XMStoreFloat(&result, length);
return result;
}
To determine if it's a Wall I used kind like this dynamic_cast<Wall*>(val) but I don't get them in front/back of the vector depending on that. To remember the objects return their centerpoint. Can anyone lead me to the right way?
It's difficult to answer your question because it is a complex system which you haven't fully explained here and which you should also reduce to something simpler before posting. Chances are that you would find a fix yourself on the way. Anyway, I'll do some guessing...
Now, the first thing I'd fix is the sorting algorithm. Without analysing it in depth whether it works correctly in all cases or not, I'd throw it out and use std::sort(), which is both efficient and very unlikely to contain errors.
While replacing it, you need to think about the ordering between two rendered objects carefully: The question is when exactly does one object need to be drawn before the other? You are using the distance of the center point to the camera. I'm not sure if you are sorting 2D objects or 3D objects, but in both cases it's easy to come up with examples where this doesn't work! For example, a large square that doesn't directly face the camera could cover up a smaller one, even if the smaller square's center is closer. Another problem is when two objects intersect. Similarly for 3D objects, if they have different sizes or intersect then your algorithm doesn't work. If your objects all have the same size and they can't intersect, you should be fine though.
Still, and here I suspect one problem, it could be that a surface of an object and a surface of the cube grid have exactly the same position. One approach is that you shrink the objects slightly or enlarge the outside grid, so that the order is always clear. This would also work around an issue that you suffer from floating point rounding errors. Due to these, two objects that don't have an order mathematically could end up in different positions depending on the circumstances. This can manifest as them flickering between visible to covered depending on the camera angle.
One last thing: I'm assuming you want to solve this yourself for educational reasons, right? Otherwise, it would be a plain waste of time with existing rendering toolkits in place that would even offload all the computations to the graphics hardware.

c++ implementing collision detection and handling for tiled 2D world with smooth wall sliding

Im using SFML 2.1 for graphics and my game structure follows SFML book quite closely (SceneGraph implementation etc)
My world consists mostly of characters (around 1-400, moving around) and tiles (3600, stationary) and I'll check for collisions everytime something moves
In worst case scenario with ~400 characters moving around and ~3600 tiles, I have 4000 possible entities with collision and 800 collision check calls (separate X and Y movement) each frame -> 3.2M collision checks in total.
Almost all my entities have size of 16x16 pixels and I've been looking into implementing either quadtree or simpler grid for collision detection, which should bring number of collision checks down quite a bit. By grid I mean http://conkerjo.wordpress.com/2009/06/13/spatial-hashing-implementation-for-fast-2d-collisions/
But I have no idea how I should implement simple grid for example. All help is welcome. There's propably even a lot better ways to bruteforce this.
Entity update step.
I do X/Y-axis movement separately. Because I want to slide against entities when colliding diagonally.
Move entity horizontally
Check and handle collisions
Move entity vertically
Check and handle collisions
Repeat 1-4 for all entities
.
void Entity::updateCurrent(sf::Time dt, CommandQueue& commands)
{
setPreviousPosition(getPosition());
move(sf::Vector2f(mVelocity.x, 0) * dt.asSeconds());
handleCollision();
setPreviousPosition(getPosition());
move(sf::Vector2f(0, mVelocity.y) * dt.asSeconds());
handleCollision();
}
I've had the following problem before when I tried to handle both X and Y movement at the same time:
I had no idea if I should reset X or Y position after collision.
Collision handling.
I'll handle collisions only when entities are moving (currently only character entities, later projectiles and some special tiles)
if entity is tile -> do nothing
if entity is character -> check collisions with characters and tiles and reset movement if collision happened
.
void Entity::handleCollision()
{
if (getCategory() & Category::Tile)
return;
if (getCategory() & Category::Character)
{
std::set<SceneNode::Pair> collisionPairs;
checkCollision(*mSceneGraph, collisionPairs);
for (SceneNode::Pair pair : collisionPairs)
{
if (matchesCategories(pair, Category::Character, Category::NonPassableCharacterOrTile))
{
resetPreviousPosition();
break;
}
}
}
}
I'll check collision simply by using SFML's intersects-function. This is propably good enough for this?
bool collision(const SceneNode& l, const SceneNode& r)
{
return l.getBoundingRect().intersects(r.getBoundingRect());
}
If I were to implement grid or quadtree for collision detection, when should I populate it, when update? Should I update it every time I move one entity, or should I try to come up with a way to move all entities at once, then build grid/quadtree and only after that try to handle all collisions.
So my questions are: (1) In this scenario how and when should I do collision handling? My current implementation works, but I think I do it too often and all examples I looked into grids/quadtrees assumed that I do first all movement and do collision detection and handling after.
and (2) When do I clear/populate/update my grid/quadtree. For example if I have 3600 tiles and 3 moving characters. Should I seek for entity each time one moves in the grid and try to move it to different grid cell / tree branch?
Edit:
What I'll propably try next unless anyone gives better advice
Updated update step.
Is this smart or in anyway reasonable way to do this?
Remove entity from grid/quadtree
Move entity horizontally
Add entity to grid/quadtree
Check and handle collisions
Remove entity from grid/quadtree
Move entity vertically
Add entity to grid/quadtree
Check and handle collisions
Repeat 1-8 for all entities
.
Entity::move()
{
grid.getCell(getPosition()).remove(this);
... move x
grid.getCell(getPosition()).add(this);
... if collision, reset x
grid.getCell(getPosition()).remove(this);
... move y
grid.getCell(getPosition()).add(this);
... if collision, reset y
}
Entity::checkCollision()
{
list<Entity*> possibleColliders;
possibleColliders = grid.getEntitiesInRectangle(x - s, y - s, x + s, y + s);
... now only check collision against possibleColliders
}
I think a quadtree would work quite well and since it will be standalone there's really no issue in adding it into your current system.
The important question you've ask is probably, when to populate and update the quadtree. I think this largely depends on your use case. Since you have around 400 characters that can change position for each frame, it probably wouldn't make a lot of difference if you try to move the nodes in the quadtree or if you fully rebuild the quadtree. Which is really more performant depends on your algorithm and datastructure, which would need some performance testing.
In this tutorial, they also suggest to rebuild the quadtree every frame iteration.
For the "how to fix collision handling" you'll need to provide more information/a separate SO question, since it's not that clear what the issue is.

Excluding fields with certain state from 2D array; Game of life

I have an array - 2D(100 x 100 in this case) with some states limited within borders as shown on picture:
http://tinypic.com/view.php?pic=mimiw5&s=5#.UkK8WIamiBI
Each cell has its own id(color, for example green is id=1) and flag isBorder(marked as white on pic if true). What I am trying to do is exclude set of cell with one state limited with borders(Grain) so i could work on each grain separately which means i would need to store all indexes for each grain.
Any one got an idea how to solve it?
Now that I've read your question again... The algorithm is essentially the same as filling the contiguous area with color. The most common way to do it is a BFS algorithm.
Simply start within some point you are sure lays inside the current area, then gradually move in every direction, selecting traversed fields and putting them into a vector.
// Edit: A bunch of other insights, made before I understood the question.
I can possibly imagine an algorithm working like this:
vector<2dCoord> result = data.filter(DataType::Green);
for (2dCoord in result) {
// do some operations on data[2dCoord]
}
The implementation of filter in a simple unoptimized way would be to scan the whole array and push_back matching fields to the vector.
If you shall need more complicated queries, lazily-evaluated proxy objects can work miracles:
data.filter(DataType::Green)
.filter_having_neighbours(DataType::Red)
.closest(/*first*/ 100, /*from*/ 2dCoord(x,y))
.apply([](DataField& field) {
// processing here
});