Calling functions randomly using a vector - c++

#assume everything needed is included
void Robot::moveRobot()
{
//calls a random directon for robot to move in
//if direction returns false (not able to move in that direction),
//call another random direction up to 4 times, excluding the one(s)
//already called. If they all return false, do not move the robot.
//vecDir = {moveForward(), moveBackward(), moveRight(), moveLeft()}
// = {0,1,2,3} initially
vector<int> vecDir{0,1,2,3}; //vetor indicating direction to move
int num = rand() % vecDir.size();
if(num == vecDir[0])
{
//if not able to move forward, try a different random direction
if(Robot::moveForward() == false)
{
vecDir.erase(num);
//here, vector will be vecDir={1,2,3}
}
}
else if(num == vecDir[1])
{
Robot::moveBackward();
}
else if(num == vecDir[2])
{
Robot::moveRight();
}
else //num == vecDir[3]
{
Robot::moveLeft();
}
}
Hi! I'm trying to randomly call these four functions within the moveRobot() function using a vector whose size is changed depending on if a direction cannot be called. I set moveForward() to the first element, moveBackward() to the second element, etc. If any of the moveXXXX() functions are false, I want to delete that element of the array. Example code shown
Example output:
//before doing anything, vecDir = {0,1,2,3}
int num = rand() % vecDir.size(); //assume num = 1, so it calls moveBackward()
//assume moveBackward() is false, so gets rid of that element
vecDir.erase(num); //new vecDir = {0,2,3};
// vecDir(0) would be moveForward(), vecDir(1) is now moveRight(), vecDir(1) is now moveLeft()
How would I continue this process to exhaust all elements and not move a robot? I know a for loop would be involved, but I cannot think of where to use it. I am also not sure if my thinking is correct by using if else for each element. Any help is appreciated, and I apologize if the question is confusing. I can clear it up if there are any misunderstandings.

Just have a vector of function pointers, rather then numbers.
void Robot::moveRobot() {
// vector of pointers to functions to move
std::vector<bool()> moves{
moveForward(), moveBackward(), moveRight(), moveLeft()
};
// we repeat the process until any moves are available.
while (moves.size() > 0) {
// pick a random move
const int num = rand() % moves.size();
// try to move
if (moves[num]() == true) {
// yay, we moved!
break;
}
// we did not move - remove current option and repeat
moves.erase(moves.begin() + num);
}
}

Related

Why is my output freezing when it gets to this section of the code?

I'm trying to compare two decks of cards, yet every time I try another method of doing it, I get the same result... Everything before the code outputs, and it just freezes as soon as it hits the comparison code, as if it's stuck in an infinite loop.
I've tried for loops, static variables, do-while loops, etc. This is my first time leaving the loop at the client code.
The code that supposedly throws the program into an infinite loop.
while (repeatLoop == false)
{
deck1.shuffleDeck();
counter++;
repeatLoop = deck1.compareDecks();
}
compareDecks function.
bool deck::compareDecks()
{
int deckCount = 0;
suitType tempOriginalSuit;
suitType tempShuffleSuit;
rankType tempOriginalRank;
rankType tempShuffleRank;
while (index < 52)
{
tempOriginalSuit = originalCardDeck[index].getSuit();
tempShuffleSuit = shuffledCardDeck[index].getSuit();
if (int(tempOriginalSuit) == int(tempShuffleSuit))
{
tempOriginalRank = originalCardDeck[index].getRank();
tempShuffleRank = shuffledCardDeck[index].getRank();
if (int(tempOriginalRank) == int(tempShuffleRank))
{
deckCount++;
if (deckCount == 52)
return true;
}
}
else
{
return false;
index++;
}
}
}
The shuffleDeck function
(This function pushes back the first card from the first half of the deck and the first card from the second half of the deck towards the end until all 52 cards have been pushed in this pattern. This makes the deck have 52 x 2 cards (with the second half of the deck being the perfect shuffle), so I delete the first half of the cards using .erase as it is not needed)
void deck::shuffleDeck()
{
for (int a = 0, b = 2; a < 2 && b < 4; a++, b++)
{
for (int i = 2; i < 15; i++)
{
shuffledCardDeck.push_back(card{ static_cast<cardSpace::suitType>(a),
static_cast<cardSpace::rankType>(i) });
shuffledCardDeck.push_back(card{ static_cast<cardSpace::suitType>(b),
static_cast<cardSpace::rankType>(i) });
}
}
shuffledCardDeck.erase(shuffledCardDeck.begin(),
shuffledCardDeck.begin() + (shuffledCardDeck.size() / 2));
}
The two decks initialized by this constructor.
deck::deck()
{
for (int i = 0; i < 4; i++)
{
for (int j = 2; j < 15; j++)
{
originalCardDeck.push_back(card{ static_cast<cardSpace::suitType>(i),
static_cast<cardSpace::rankType>(j) });
shuffledCardDeck.push_back(card{ static_cast<cardSpace::suitType>(i),
static_cast<cardSpace::rankType>(j) });
}
}
}
Also note that I've done a perfect shuffle on the shuffledCardDeck vector in another function. I'm trying to repeat the perfectShuffle function until it reaches it's original state and output how many times it took to do this.
I get an infinite loop.
EDIT: I've decided to add the return false; statement in the compareDecks function into the if-else. Also, I think what's causing the problem is that my index i is reset to zero everytime it is called again. Are there any solutions you guys could propose to this? I've tried using static variables, but they just would not increment in the for loop.
EDIT 2: I enclosed my if statements within the curly braces, per users' request, as it's a flaw in my code.
EDIT 3: After commenting out
deck1.shuffleDeck()
The compareDecks function returned true, stating that the decks are equal, which isn't supposed to happen... This caused the loop to end after only one loop.
I was expecting you to actually shuffle the deck.
Your code was pushing a specific, newly synthesized card onto the end of the deck:
shuffledCardDeck.push_back(card{ static_cast<cardSpace::suitType>(a),
static_cast<cardSpace::rankType>(i) });
For example, the first card it will push is always the 2 of 0's (Whatever the 0th suit is). That's not what you want. You actually want to push a copy of the card that is at a specific position index in the deck. For example, loop index from 0 to 25 and then push shuffledCardDeck[index] and shuffledCardDeck[26 + index].
Then you can still wrap up by using your technique of erasing the first half of the deck.
void deck::shuffleDeck()
{
for (int index = 0; index < 26; ++index) {
shuffledCardDeck.push_back(shuffledCardDeck[index]);
shuffledCardDeck.push_back(shuffledCardDeck[26 + index]);
}
shuffledCardDeck.erase(shuffledCardDeck.begin(),
shuffledCardDeck.begin() + 52);
}
You are not modifying the value in the loop, you're using a double equals sign:
repeatLoop == deck1.compareDecks();
That would explain your observed behavior.

Checking for a cycle in an undirected graph using DFS?

So, I made the following code for DFS:
void dfs (graph * mygraph, int foo, bool arr[]) // here, foo is the source vertex
{
if (arr[foo] == true)
return;
else
{
cout<<foo<<"\t";
arr[foo] = true;
auto it = mygraph->edges[foo].begin();
while (it != mygraph->edges[foo].end())
{
int k = *it;
if (arr[k] == false)
{
//cout<<k<<"\n";
dfs(mygraph,k,arr);
//cout<<k<<"\t";
}
it++;
}
}
//cout<<"\n";
}
Now, I read up that in an undirected graph, if while DFS, it returns to the same vertex again, there is a cycle. Therefore, what I did was this,
bool checkcycle( graph * mygraph, int foo, bool arr[] )
{
bool result = false;
if (arr[foo] == true)
{
result = true;
}
else
{
arr[foo] = true;
auto it = mygraph->edges[foo].begin();
while (it != mygraph->edges[foo].end())
{
int k = *it;
result = checkcycle(mygraph,k,arr);
it++;
}
}
return result;
}
But, my checkcycle function returns true even if their is no cycle. Why is that? Is there something wrong with my function? There is no execution problem, otherwise I would have debugged, but their seems to be something wrong in my logic.
Notice that your function doesn't quite do what you think it does. Let me try to step through what's happening here. Assume the following relationships: (1,2), (1,3), (2,3). I'm not assuming reflexibility (that is, (1,2) does not imply (2,1)). Relationships are directed.
Start with node 1. Flag it as visited
Iterate its children (2 and 3)
When in node 2, recursively call check cycle. At this point 2 is also flagged as visited.
The recursive call now visits 3 (DEPTH search). 3 is also flagged as visited
Call for step 4 dies returning false
Call for step 3 dies returning false
We're back at step 2. Now we'll iterate node 3, which has already been flagged in step 4. It just returns true.
You need a stack of visited nodes or you ONLY search for the original node. The stack will detect sub-cycles as well (cycles that do not include the original node), but it also takes more memory.
Edit: the stack of nodes is not just a bunch of true/false values, but instead a stack of node numbers. A node has been visited in the current stack trace if it's present in the stack.
However, there's a more memory-friendly way: set arr[foo] = false; as the calls die. Something like this:
bool checkcycle( graph * mygraph, int foo, bool arr[], int previousFoo=-1 )
{
bool result = false;
if (arr[foo] == true)
{
result = true;
}
else
{
arr[foo] = true;
auto it = mygraph->edges[foo].begin();
while (it != mygraph->edges[foo].end())
{
int k = *it;
// This should prevent going back to the previous node
if (k != previousFoo) {
result = checkcycle(mygraph,k,arr, foo);
}
it++;
}
// Add this
arr[foo] = false;
}
return result;
}
I think it should be enough.
Edit: should now support undirected graphs.
Node: this code is not tested
Edit: for more elaborate solutions see Strongly Connected Components
Edit: this answer is market as accepted although the concrete solution was given in the comments. Read the comments for details.
are all of the bools in arr[] set to false before checkcycle begins?
are you sure your iterator for the nodes isn't doubling back on edges it has already traversed (and thus seeing the starting node multiple times regardless of cycles)?

Vector Collision

I am quite green regarding vectors, and this is my first time actually using them for collision checking. This is for my project, and I am stumped on how to implement the collision. The current Collision check and response codes I have seem to be ... bad design.
This is my code:
for(auto it = ArrayofEntities.begin(); it != ArrayofEntities.end(); it++)
{
CEntity * go = (*it);
for(auto i = ArrayofEntities.begin(); i != ArrayofEntities.end();)
{
//Collision for entities. Collision Event returns the iterator after an element is erased.
CEntity * other = (*i);
if (go != other)
{
if (!theCollision.CheckCollision(go, other, false, false, false, false)) //Checks if it has collided go with other
{
i = go->CollisionEvent(*other, ArrayofEntities); //Run collision code, setting i to the iterator which is returned.
//break;
}
else
{
i++;
}
}
else
{
i++;
}
}
}
CEntity is the base class for all the entities.
My CheckCollision just returns a true or false on the collision, and my collision event runs the collision and returns an iterator (because I might have to destroy things in the vector).
My collision event is below
vector<CEntity*>::iterator bullet::CollisionEvent(CEntity &other, vector<CEntity*> & theArray)
{
case ZOMBIE:
{
other.hp -= power * 0.01;//Effect
int Counter, index, bulletindex;
auto it = theArray.begin();
//Find the bullet and the other in the array.
for (it = theArray.begin(), Counter = 0; it != theArray.end();it++, Counter++)
{
CEntity *go = NULL;
go = (*it);
if (go == &other)
{
index = Counter;
}
if(go->ID == BULLET && go->GetX() == GetX() && go->GetY() == GetY())
{
bulletindex = Counter;
}
}
this->~bullet();//Delete the bullet
theArray.erase(theArray.begin() + bulletindex);
if(other.hp <= 0)
{
other.~CEntity();
it = theArray.erase(theArray.begin() + index); //delete from array.
return it;
}
it = theArray.begin() + index;
return it;
}
}
I have basically done this like how I would do an array. Just check it against itself. The error it gives is "Vector Iterator not Incrementable", on the first for loop after the collision event has been run.
So my question: 1) What am I doing wrong?
2) Is my thinking to do this like checking arrays wrong?
This is my school project, so I have full control of the codes.
I would prefer to have a quick fix over a complete rewriting of all the collision codes, but if it really comes down to it, I will rewrite my codes.
If you look at the implementation of std::remove_if, you'll see that they've solved the issue of iterator invalidation in another way. instead of erasing elements, they move them to the end of the array.
This may be the easiest solution for you as well. Keep an iterator which points after the last "live" entirty. It starts out at .end but as bullets hit things, you swap the entities to the back of your range and decrement that last-live iterator.
Then, when you're done looping over your array, you clean up with a single call to .erase.
And yes, you should use either std::unique_ptr<CEntity> or std::shared_ptr<CEntity> in the collection. In that way, .erase won't just erase the pointer but also the object pointed to.

Cellular automaton doesn't make new cells

I'm trying to make a program that is able to create every kind of cellular automatons, such as Conway's game of life and everything else too.
The graphic implementation works perfectly already, so I wouldn't waste your time with that (especially that it uses Allegro libraries), but the functions that counts the cells, doesn't work properly.
That's what I have at the moment. (the code is in order, I just break it with commentary to make everything clear for you)
Pre-definitions:
#define fldwidth 110
#define fldheight 140
A structure for graphics:
typedef struct tiles
{
unsigned char red, green, blue;
}tiles;
Two predefined structures: the RGB code of an alive and a dead test cell.
const tiles TEST_ALIVE = {200,0,0};
const tiles TEST_DEAD = {100,0,0};
A function that checks the color equality of a structure variable and a constant structure.
bool equality(tiles& a, const tiles& b)
{
if (a.red == b.red && a.green == b.green && a.blue == b.blue)
{
return true;
} else {
return false;
}
}
The main function. It gets two arrays of structures (first one is the current round, second one is where counting happens; in round loop, after the counting, b array will be copied into a array); when started, it does the following steps for every structures: counts, how many living cells it has in its neighborhood (if its a living cell, it starts from -1 to avoid counting itself as neighbours, otherwise it start from 0 regularly), then if itself is NOT a living test cell (but anything else) and has 5 neighbours, it becomes a living test cell; if itself is a living test cell and has 2 neighbours, it becomes a dead cell.
void Test(tiles arra[fldwidth][fldheight], tiles arrb[fldwidth][fldheight])
{
int a,b,i,j,counter;
for (j=1;j<fldheight-1;j++)
{
for (i=1;i<fldwidth-1;i++)
{
if (equality(arra[i][j], TEST_ALIVE) == true)
{
counter = -1;
} else {
counter = 0;
}
for (b=j-1;b<j+1;b++)
{
for (a=i-1;a<i+1;a++)
{
if (equality(arra[a][b], TEST_ALIVE) == true)
{
counter+=1;
}
}
}
arrb[i][j] = arra[i][j];
if (equality(arra[i][j], TEST_ALIVE) == false && counter == 5)
{
arrb[i][j] = TEST_ALIVE;
}
if (equality(arra[i][j], TEST_ALIVE) == true && counter == 2)
{
arrb[i][j] = TEST_DEAD;
}
}
}
}
The problem is that when the counting begins, every living cell becomes dead immediately in the first round and sometimes they just disappear, even without becoming dead cell (which is a darker red colour obviously), and it happens for almost every "counter == XY" check.
I've already got some tips, but I have no idea, why it doesn't work. Does it have logic failure? Because I can't see the mistake, even though it is there.
EDIT:
arra[fldwidth][fldheight]
is replaced by
arra[i][j]
and
arrb[i][j] = arra[i][j];
is added. Now everything stays as they were put.
Why do you access arra[fldwidth][fldheight] for the equality checks? This is outside of the array, one element behind the last element in the array! What you want to access is arra[i][j].
And unless arrb starts as a copy of arra, you probably want to add arrb[i][j] = arra[i][j]; in front of the two equality checks. That way if a cell doesn't meet any of the two state change rules, it will keep its current state.
Edit:
You also need to let the loop run between i-1 and i+1, so it should be: for (a = i-1; a <= i+1; a++), same for b!
I think your bug is in the line:
if (equality(arra[fldwidth][fldheight], TEST_ALIVE) == false && counter == 5)
This should be:
if (equality(arra[i][j], TEST_ALIVE) == false && counter == 5)
and similarly for the line:
if (equality(arra[fldwidth][fldheight], TEST_ALIVE) == true && counter == 2)

Array PopFront Method C++

Trying not to lose it here. As you can see below I have assigned intFrontPtr to point to the first cell in the array. And intBackPtr to point to the last cell in the array...:
bool quack::popFront(int& nPopFront)
{
nPopFront = items[top+1].n;
if ( count >= maxSize ) return false;
else
{
items[0].n = nPopFront;
intFrontPtr = &items[0].n;
intBackPtr = &items[count-1].n;
}
for (int temp; intFrontPtr < intBackPtr ;)
{
++intFrontPtr;
temp = *intFrontPtr;
*intFrontPtr = temp;
}
return true;
}
In the else statement I'm simply reassigning to ensure that my ptrs are where I want them. For some reason I'm popping off the back instead of off the front.
Anyone care to explain?
I'm not entirely sure I understand what you're trying to do, but if I;m guessing right you're trying to 'pop' the 1st element of the array (items[0]) into the nPopFront int reference, then move all the subsequent elements of the array over by one so that the 1st element is replaced by the 2nd, the 2nd by the 3rd, and so on. After this operation, the array will contain one less total number of elements.
Not having the full declaration of the quack class makes most of the following guesswork, but here goes:
I'm assuming that item[0] represents the 'front' of your array (so it's the element you want 'popped').
I'm also assuming that 'count` is the number of valid elements (so item[count-1] is the last valid element, or the 'back' of the array).
Given these assumptions, I'm honestly not sure what top is supposed to represent (so I might be entirely wrong on these guesses).
Problem #1: your nPopFront assignment is reversed, it should be:
nPopFront = items[0].n;
Problem #2; your for loop is a big no-op. It walks through the array assigning elements back to their original location. I think you want it to look more like:
for (int i = 1; i < count; ++i)
{
items[i-1].n = items[i].n; // move elements from back to front
}
Finally, you'll want to adjust count (and probably top - if you need it at all) before you return to adjust the new number of elements in the data structure. The whole thing might look like:
bool quack::popFront(int& nPopFront)
{
if ( count >= maxSize ) return false;
if ( count == 0 ) return false; // nothing to pop
nPopFront = items[0].n;
intFrontPtr = &items[0].n; // do we really need to maintain these pointers?
intBackPtr = &items[count-1].n;
for (int i = 1; i < count; ++i)
{
items[i-1].n = items[i].n; // move elements from back to front
}
count -= 1; // one less item in the array
return true;
}
The original question seems to be that you don't understand why the function popFront returns 3 times when there are 3 elements?
If that's the case, I think you are missing the point of recursion.
When you make a recursive call, you are calling the same function again, basically creating a new stack frame and jumping back to the same function. So if there are 3 elements, it will recurse by encountering the first element, encountering the second element, encountering the third element, returning from the third encounter, returning from the second encounter, and returning from the first encounter (assuming you are properly consuming your array, which you don't appear to be).
The current function cannot return until the recursive call has iterated, thus it may appear to return from the last element before the second, and the second before the first.
That is how recursion works.
I wasn't able to make sense of your example, so I whipped one up real fast:
#include <iostream>
using namespace std;
bool popfront(int* ptr_, int* back_) {
cerr << ptr_[0] << endl;
if(ptr_ != back_) {
popfront(++ptr_, back_);
}
return true;
}
int main() {
int ar[4] = {4,3,2,1};
popfront(ar, ar + 3);
return 0;
}
That's not great, but it should get the point across.
Can't you just use a std::list?
That makes it really to pop from either end using pop_front or pop_back. You can also add to the front and the back. It also has the advantage that after popping from the front (or even removing from the middle of the list) you don't have to shift anything around (The link is simply removed) which makes it much more efficient than what you are, seemingly, proposing.
I'm assuming you're trying to assign the popped value to nPopFront?
bool stack::popFront(int& nPopFront)
{
//items[4] = {4,3,2,1}
if ( intFrontPtr < intBackPtr )
{
nPopFront = *intFrontPtr;
++intFrontPtr;
}
return true;
}
bool quack::popFront(int& nPopFront)
{
if(items.n==0) throw WhateverYouUseToSignalError;
nPopFront = items[0];
for (int =0;i<items.n-1,++i){
items[i]=items[i+1]
}
//update size of items array
}