QValueList reverse iterator - qt

How to make reverse looping for QValueList?
i found, thanks to all
QValueList<int> l;
for (int i = 0; i < 10; i++) l.append(i);
QValueListIterator<int> it = l.end(); --it;
for (; it != l.end(); --it)
{
qDebug(QString::number(*it));
}

The first thing you should do is change it to a QLinkedList
As it happens, the linked article shows an example of reverse looping.

Related

Is there an efficient algorithm for calculating which tiles are within a set walking distance of your character in a 2d grid?

Lets say that on a 2d grid of 20x20, you have your character at position (5,5).
He is able to walk up to 4 tiles in his move. However, there may be obstacles blocking your path such as a wall.
Is there any efficient / easy way for calculating exactly which tiles he would be able to walk to without checking every single possible move ( e.g. move up 0 and right 0 then move up 0 and right 1 e.t.c )?
At the moment I'm calculating the places that you can walk through with this horrific thing:
int playerx = GridPane.getRowIndex(button);
int playery = GridPane.getColumnIndex(button);
int position = playery*8+playerx;
for (int i = 0; i < 5; i++)
{
for (int j = i-4; j < 5-i; j++)
{
try
{
int expectedCollumn = playerx+j;
int actualCollumn = ((position+i+j*8)-((position+i+j*8)%8))/8;
if(expectedCollumn==actualCollumn)
{
Button temp = (Button)gridPane.getChildren()
.get(position+i+j*8);
if (!temp.getText().equals("W") &&
!temp.getText().equals("P"))
{
temp.setText("T");
}
}
actualCollumn = ((position-i+j*8)-((position-i+j*8)%8))/8;
if(expectedCollumn==actualCollumn)
{
Button temp2 = (Button)
gridPane.getChildren().get(position-i+j*8);
if (!temp2.getText().equals("W") &&
!temp2.getText().equals("P"))
{
temp2.setText("T");
}
}
}
}
}
However, its showing as if you are able to walk to the otherside of the wall and I'm not sure how I would go about fixing this.
Many thanks in advance.
For path finding, you should figure out how this works:
https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
and then move on to A* or something more efficient.
Thanks to everyone that answered but the solution was simple
incase somehow someone finds this post and is interested it was a simple recursive call
void getReachableTiles(Tile current, Int stamina, List<Tile> visited, List<Tile> reachable) {
if (stamina <= 0) return;
List<Tile> neighbours = new List<>(current + up, current + left, ..)
for (Tile t in neighbours) {
if (!visited.contains(t)) {
visited.append(t);
if (!t.isWall()) {
reachable.append(t);
getReachableTiles(t, stamina - 1, visited, reachable);
}
}
}
}

Random Values from a variable set of entries in a vector

i have a problem which is the following:
i have for example 4 objects. One object is randomly selected to do a certain action. E.g. if object 1 does an action, the other 3 objects do nothing.
So, i have a vector of these objects.
vector{object1,object2, object3, object4}
In the beginning, i can easily randomly select one object with vector[random].
And here comes the problem: An object can also "die" meaning the object should not be part of the random-step anymore.
For example, if object2 dies, if want to random between 1,3,4 and let the 2 out.
Is this possible somehow? (using C++)
Thanks!
I was just under the shower and thought about it.. i think i found a workaround for this. Pseudo-Code:
vector<figure> all_figure_types;
vector<figure> all_figure_types_alive;
for (int i = 0; i < 5; i++) {
all_figure_types.push_back(generate_random_number(1,10));
}
all_figure_types_alive.clear();
for (int i = 0; i < all_figure_types.size(); i++) {
if (all_figure_types[i].is_alive) {
all_figure_types_alive.push_back(all_figure_types[i]);
}
}
int start = 0;
int end = all_figure_types_alive.size();
int random_num = generate_random_number(start, end);
int object_type = all_figure_types_alive[random_num].type;
If there is a nicer version without resetting this helping-construct all_figure_types_alive, let me know would be nice to hear!

Appending to / removing elements from vector while iterating over said vector [duplicate]

What is the idiomatic way to iterate (read) over the first half of the vector and change the structure of the second half of the vector depending on the first? This is very abstract but some algorithms could be boiled down to this problem. I want to write this simplified C++ example in Rust:
for (var i = 0; i < vec.length; i++) {
for (var j = i + 1 ; j < vec.length; j++) {
if (f(vec[i], vec[j])) {
vec.splice(j, 1);
j--;
}
}
}
An idiomatic solution of this generic problem will be the same for Rust and C, as there's no constraints which would allow simplification.
We need to use indexes because vector reallocation will invalidate the references contained by the iterators. We need to compare the index against the current length of the vector on each cycle because the length could be changed. Thus an idiomatic solution will look like this:
let mut i = 0;
while i < v.len() {
let mut j = i + 1;
while j < v.len() {
if f(v[i], v[j]) {
v.splice(j, 1);
} else {
j += 1;
}
}
i += 1;
}
Playground link
While this code covers the general case, it is rarely useful. It doesn't capture specifics, which are usually inherent to the problem at hand. In turn, the compiler is unable to catch any errors at compile time. I don't advise writing something like this without considering another approaches first.

Arduino - For Loop with Array not working

I have a problem with for loops and an array in Arduino IDE.
test1 does not work
test2 does work
test3 does work
How can I get test1 to work?
void test1(){
for(int i=1; i<5; i++) {
individualPixels[i]==1;
}
}
void test2(){
individualPixels[1]=1;
individualPixels[2]=1;
individualPixels[3]=1;
individualPixels[4]=1;
}
}
void test3(){
for(int i=1; i<5; i++) {
Serial.println(individualPixels[i]); //prints out 0 4 times
}
}
You're not actually assigning anything in test1, you're testing
for equality (individualPixels[i]==1 should be individualPixels[i] = 1, note the single equality sign).
Also, as other commenters mentioned, C/C++ uses zero based indexing.
C/C++ uses zero indexed arrays, so your for loops in test1 and test3 should look like this:
for(int i=0; i<4; i++) {
individualPixels[i]==1;
}
Test2 has an unmatched bracket and the array indexes should start at zero:
void test2(){
individualPixels[0]=1;
individualPixels[1]=1;
individualPixels[2]=1;
individualPixels[3]=1;
//} this shouldn't be here
}
The for loops start with i = 1 that should be 0 as an element in an array can be accessed with an index from 0 to size-1. An array with 4 elements can be accessed as follows:
array[0] --- first element
array[1] --- second element
array[2] --- third element
array[3] --- fourth element
Apart from that, the first for loop (that doesn't work) used the == operator, which checks if two variables are equal and then returns a boolean as a result. Instead you should use a single = that will set the value.
The second test has an extra } ,which should be removed
I suggest you to start actually learning programming, for example by reading a (e)book, as you will teach yourself bad habits (accessing arrays in a wrong way), which may work, but may not be efficient.
Thanks very much to all of you.
I have a large array with 60 indexes and want to set some of them 1 with a for loop. The "==" was the main problem. It's working now like I want it to:
void test1(){
for(int i=1; i<5; i++) {
individualPixels[i]=1;
}
}
void test2(){
individualPixels[1]=1;
individualPixels[2]=1;
individualPixels[3]=1;
individualPixels[4]=1;
}
void test3(){
for(int i=1; i<5; i++) {
Serial.println(individualPixels[i]); //prints out 0 4 times
}
}

QGraphicsItem: Why no `stackAfter` method?

I'm having an annoying time trying to get around the 'recommended' way of doing something.
So, I have a stack of cards. I want to make it so that when I deal a card, it becomes the last-drawn object of the entire scene (typical bring_to_front functionality).
The recommended way to do this is just adding to the object's zValue until it is larger than all the rest, but I was hoping to do away with rather "lazy" integers running around all over the place with judicious use of the stackBefore method, which simulates reorganizing the order in which objects were added to the scene.
This works perfectly fine when I shuffle my cards in a limited set (get list of selected items, random.shuffle, for item do item.stackBefore(next item)), but it is certainly not working when it comes to bubbling the card to the top of the entire scene.
I considered adding a copy of the object to the scene and then removing the original, but it just seems like I should be able to do stackAfter like I would when using a Python list (or insertAt or something).
Sample code:
def deal_items(self):
if not self.selection_is_stack():
self.statusBar().showMessage("You must deal from a stack")
return
item_list = self.scene.sorted_selection()
for i,item in enumerate(item_list[::-1]):
width = item.boundingRect().width()
item.moveBy(width+i*width*0.6,0)
another_list = self.scene.items()[::-1]
idx = another_list.index(item)
for another_item in another_list[idx+1:]:
another_item.stackBefore(item)
This works. It just seems somewhat... ugly.
self.scene.items returns the items in the stacking order (link). So if you want to stackAfter an item, you can just query the z value of the current topmost item and then set the z value of the new topmost card to a value one larger.
item.setZValue(self.scene.items().first().zValue() + 1)
Hope that helps.
Edit added src for stackBefore and setZValue from http://gitorious.org/qt/
src/gui/graphicsview/qgraphicsitem.cpp
void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
{
if (sibling == this)
return;
if (!sibling || d_ptr->parent != sibling->parentItem()) {
qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
return;
}
QList<QGraphicsItem *> *siblings = d_ptr->parent
? &d_ptr->parent->d_ptr->children
: (d_ptr->scene ? &d_ptr->scene->d_func()->topLevelItems : 0);
if (!siblings) {
qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
return;
}
// First, make sure that the sibling indexes have no holes. This also
// marks the children list for sorting.
if (d_ptr->parent)
d_ptr->parent->d_ptr->ensureSequentialSiblingIndex();
else
d_ptr->scene->d_func()->ensureSequentialTopLevelSiblingIndexes();
// Only move items with the same Z value, and that need moving.
int siblingIndex = sibling->d_ptr->siblingIndex;
int myIndex = d_ptr->siblingIndex;
if (myIndex >= siblingIndex) {
siblings->move(myIndex, siblingIndex);
// Fixup the insertion ordering.
for (int i = 0; i < siblings->size(); ++i) {
int &index = siblings->at(i)->d_ptr->siblingIndex;
if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
++index;
}
d_ptr->siblingIndex = siblingIndex;
for (int i = 0; i < siblings->size(); ++i) {
int &index = siblings->at(i)->d_ptr->siblingIndex;
if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
siblings->at(i)->d_ptr->siblingOrderChange();
}
d_ptr->siblingOrderChange();
}
}
void QGraphicsItem::setZValue(qreal z)
{
const QVariant newZVariant(itemChange(ItemZValueChange, z));
qreal newZ = newZVariant.toReal();
if (newZ == d_ptr->z)
return;
if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
// Z Value has changed, we have to notify the index.
d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ);
}
d_ptr->z = newZ;
if (d_ptr->parent)
d_ptr->parent->d_ptr->needSortChildren = 1;
else if (d_ptr->scene)
d_ptr->scene->d_func()->needSortTopLevelItems = 1;
if (d_ptr->scene)
d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
itemChange(ItemZValueHasChanged, newZVariant);
if (d_ptr->flags & ItemNegativeZStacksBehindParent)
setFlag(QGraphicsItem::ItemStacksBehindParent, z < qreal(0.0));
if (d_ptr->isObject)
emit static_cast<QGraphicsObject *>(this)->zChanged();
}

Resources