Loop Encountered When Using Flood Fill - c++

I have encountered an infinite loop when running the following code. Inside a grid that is surrounded by blocks, a predefined square is started with that this implementation runs off of. A square is labeled as one if it needs to be visited and two if it has been visited. I can't seem to find a solution and I would love a few helpful hints.
one_count=1;
while(one_count>0){
for(int i=0;i<24;i++){
for(int c=0;c<80;c++){
if(create[i][c]=='1'){
if(create[i-1][c]==' '){
create[i-1][c]='1';
}
if(create[i+1][c]==' '){
create[i+1][c]='1';
}
if(create[i][c-1]==' '){
create[i][c-1]='1';
}
if(create[i][c+1]==' '){
create[i][c+1]='1';
}
create[i][c]='2';
}
}
}
one_count=0;
for(int i=0;i<24;i++){
for(int c=0;c<80;c++){
if(create[i][c]=='1'){
one_count++;
}
}
}
}

I ran your code on random data (with the edges being 'X'). I didn't encounter any loops.
Also there is no reason why you should run into problems. Every pixel is checked in every iteration and all '1's are guaranteed to be changed to '2's. There is no way back, not possible to loop.
Maybe you could supply more information about the behaviour of the program.
BTW:
There is a small quirk in your code. The flood fills very fast to the bottom and the right because you're writing your map already during the cycle (difficult to explain -> example)
beginning of cycle: everything is ' ' except create[2][2]=='1'
check all elements until create[2][2], write '1' into neighbours and '2' into self
check next element i.e. create[2][3] which is also '1' and fill neighbours
etc.
so after the first cycle you would expect only create[2][2]=='2' but everything to the right and down from it is also =='2'.
It doesn't break your code at the moment but it might lead to unexpected results if you change something.

Related

C++: Why/How a Break Statement Works In This Code?

I have started to use C++ programming language as a complete beginner. With the aim of becoming a better programmer for my STEM degree and with the goal of competitive programming in mind. I have started Functions and Loops in C++ recently and there was a problem I was not sure how to approach.
The probelem: "Write a function to check whether a number is prime"
My Approach:
-> I wanted to implement it on my own so I didn't want to copy paste code online where others have used functions with return type bool.
-> Here is the final version of my code that works:
void prime(int k){
for(int k1=2;k1<k;k++){
if(k%k1==0){
cout<<"int is not prime"<<endl;
break;
}
else{
cout<<"int is prime"<<endl;
break;
}
}
}
->I would then call this in int Main() and get the user to input integers and so on.
-> The above code was due to many trial-and-errors on my part and my thought process was as follows: 1)if i don't include the "break;" statement my code results in an infinite loop 2)I needed a way to stop my code from going toward an infinite loop 3) I remember a topic covered in the functions segment of this website , where we can use it to terminate a loop at will. Thats why i incorporated it into my code to produce the final version
My Question:
Can someone explain how the break; statement is working in the context of my code? I know it produces my desired effect but I still haven't gotten an intuition as to how this would do my work.
Many online resources just cite the break statement as something that does so and so and then gives examples. Without going through the code mechanics. Like how a loop would be going through its conditions and then when it encounters the break; statement what does it do? and as a consequence of that what does it do to help my code?
Any advice would be helpful. I still couldn't wrap my head around this the first time I encountered it.
In your case if k % k1 does not show that the k1 being a factor of the k, the loop is broken after the print statement. If the k % k1 does show that the k1 being a factor of the k, it also breaks out of the loop.
So, either of the break statements leads to the loop termination on the first iteration here. If you test for whether a number is being a prime, it does not work.
In essence, you don't need either of the break statements here. They are mostly forced here. Take a look at the following approach:
#include <iostream>
#include <cmath>
bool prime(unsigned k){
if (k != 2) { // Direct check, so to remain similar to the OP's structure of the code
unsigned up_to = sqrt(k) + 1; // Calculate the limit up to which to check
for (unsigned i = 2; i < up_to; ++i) {
if (k % i == 0) {
std::cout << "Is not prime" << std::endl;
return false;
}
else std::cout << "Checking..." << std::endl;
}
}
std::cout << "Is prime" << std::endl;
return true;
}
// Note, we can check just up to the square root of a k
A note on the behavior of the break
The fact that it breaks out the the closest loop to it - has crucial nature for nested loops (all of them: for, while, and do while):
while (/* condition 1 */) // Outer loop
while (/* condition 2 */) // Inner loop
if (/* condition 3 */) break;
Here if the condition 3 is satisfied, the break will lead to break out of the Inner loop but the Outer loop will still continue to iterate.
For more, you may be interested in "How to exit nested loops?" thread. It addresses your second question.
Analogy... I found it in the last place I looked... like always!
Looking for your keys is the LOOP you are in... when you find them... you BREAK out and move on to another task... like maybe getting into your car...
SO if you are IN your car and know your car is where you left your keys... then you are in the PROCESS of getting prepared to drive away... BUT that process requires keys... THUS you change modes/focus and begin a cyclic process of looking for keys... when found to BREAK that searching process IMMEDIATLY and resume what your were doing.
MANY people would make use of the RETURN instrucion in your code pattern... in place of the break! Both do the same thing... however the RETURN is more descriptive english... and one should be concerned with the programmer behind him... Also a bit of digging might show how one is more efficient than the other...

Collision of two sprite lists - SFML 2.0

I am making a simple game in SFML 2 and it came smoothly so far. I created two sf::Sprite lists, one for enemies and one for lasers. The enemies spawn randomly off-screen and the lasers are created whenever input is given. I created a collision loop for both the lists and executed my code. There are no compile time and run time errors. The laser-enemy collision works fine for the first 3 to 4 enemies but after that, the collision does not occur. What might be causing this problem? Please help me on this. Thanks. Here's my code.
std::list<sf::Sprite>::iterator enemyit = enemy.begin(), next;
std::list<sf::Sprite>::iterator greenlaserit = greenlaser.begin(), reload;
while(enemyit != enemy.end())
{
next = enemyit;
next++;
while(greenlaserit != greenlaser.end())
{
reload = greenlaserit;
reload++;
if(enemyit->getGlobalBounds().intersects(greenlaserit->getGlobalBounds()))
{
enemy.erase(enemyit);
greenlaser.erase(greenlaserit);
++erased;
}
greenlaserit = reload;
}
enemyit = next;
}
It seems to be that you are doing a lot of iterator manipulation and that is likely to be where the problem is occurring.
If you can use c++11, I would suggest looking into the for each loop (http://www.cprogramming.com/c++11/c++11-ranged-for-loop.html), to keep things really simple to read and understand (and thus, easier to debug).
You could do something like this:
std::list<sf::Sprite> enemies;
std::list<sf::Sprite> lasers;
for (sf::Sprite enemy: enemies) {
for (sf::Sprite laser : lasers) {
if (enemy.getGlobalBounds().intersects(laser.getGlobalBounds())) {
enemies.remove(enemy);
lasers.remove(laser);
}
}
}
Edit: otherwise, one method I have found for figuring out an iterator problem is stepping through it by hand. I draw two rectangles with cells for each location, and keep track of the iterators and run through the logic step by step. Before each iteration of your logic, write down your expected results. Then go through it by hand and see if your results match your expectations.

C++ do while loop

I have a vector holding 10 items (all of the same class for simplicity call it 'a'). What I want to do is to check that 'A' isn't either a) hiding the walls or b) hiding another 'A'. I have a collisions function that does this.
The idea is simply to have this looping class go though and move 'A' to the next position, if that potion is causing a collision then it needs to give itself a new random position on the screen. Because the screen is small, there is a good chance that the element will be put onto of another one (or on top of the wall etc). The logic of the code works well in my head - but debugging the code the object just gets stuck in the loop, and stay in the same position. 'A' is supposed to move about the screen, but it stays still!
When I comment out the Do while loop, and move the 'MoveObject()' Function up the code works perfectly the 'A's are moving about the screen. It is just when I try and add the extra functionality to it is when it doesn't work.
void Board::Loop(void){
//Display the postion of that Element.
for (unsigned int i = 0; i <= 10; ++i){
do {
if (checkCollisions(i)==true){
moveObject(i);
}
else{
objects[i]->ResetPostion();
}
}
while (checkCollisions(i) == false);
objects[i]->SetPosition(objects[i]->getXDir(),objects[i]->getYDir());
}
}
The class below is the collision detection. This I will expand later.
bool Board::checkCollisions(int index){
char boundry = map[objects[index]->getXDir()][objects[index]->getYDir()];
//There has been no collisions - therefore don't change anything
if(boundry == SYMBOL_EMPTY){
return false;
}
else{
return true;
}
}
Any help would be much appreciated. I will buy you a virtual beer :-)
Thanks
Edit:
ResetPostion -> this will give the element A a random position on the screen
moveObject -> this will look at the direction of the object and adjust the x and Y cord's appropriately.
I guess you need: do { ...
... } while (checkCollisions(i));
Also, if you have 10 elements, then i = 0; i < 10; i++
And btw. don't write if (something == true), simply if (something) or if (!something)
for (unsigned int i = 0; i <= 10; ++i){
is wrong because that's a loop for eleven items, use
for (unsigned int i = 0; i < 10; ++i){
instead.
You don't define what 'doesn't work' means, so that's all the help I can give for now.
There seems to be a lot of confusion here over basic language structure and logic flow. Writing a few very simple test apps that exercise different language features will probably help you a lot. (So will a step-thru debugger, if you have one)
do/while() is a fairly advanced feature that some people spend whole careers never using, see: do...while vs while
I recommend getting a solid foundation with while and if/else before even using for. Your first look at do should be when you've just finished a while or for loop and realize you could save a mountain of duplicate initialization code if you just changed the order of execution a bit. (Personally I don't even use do for that any more, I just use an iterator with while(true)/break since it lets me pre and post code all within a single loop)
I think this simplifies what you're trying to accomplish:
void Board::Loop(void) {
//Display the postion of that Element.
for (unsigned int i = 0; i < 10; ++i) {
while(IsGoingToCollide(i)) //check is first, do while doesn't make sense
objects[i]->ResetPosition();
moveObject(i); //same as ->SetPosition(XDir, YDir)?
//either explain difference or remove one or the other
}
}
This function name seems ambiguous to me:
bool Board::checkCollisions(int index) {
I'd recommend changing it to:
// returns true if moving to next position (based on inertia) will
// cause overlap with any other object's or structure's current location
bool Board::IsGoingToCollide(int index) {
In contrast checkCollisions() could also mean:
// returns true if there is no overlap between this object's
// current location and any other object's or structure's current location
bool Board::DidntCollide(int index) {
Final note: Double check that ->ResetPosition() puts things inside the boundaries.

Numberofcomparison and nunber of item movements

Im using c++ and is using insertion sort
Where in the insertion sort algoithm should we put a counter to monitor number of item movements and number of item comparison. I have included my setup below
void InsertionSort::insertion_sort()
{
int key,i,count = 0;
for(int j=1;j<10;j++)
{
key=Arr1[j];
i=j-1;
while(Arr1[i]>key && i>=0)
{
Arr1[i+1]=Arr1[i];
i--;
numberOfItemMovements++;
}
Arr1[i+1]=key;
}
}
}
as you can see, i cant seem to figure out where comparison counter should be put, although the item movement counter is good and work as expected. thanks
A way of getting this to work is using numberOfComparisons in the loop.
while(++numberOfComparisons && Arr1[i]>key && i>=0)
{
Arr1[i+1]=Arr1[i];
numberOfItemMovements++;
i--;
}
1) Do you understand why ++numberOfComparisons can be used in the while loop but numberOfComparisons++ would fail?
2) You have a problem where Arr1[-1] could be evaluated. Can you figure out where this is happening and how you can change your code to fix it?
The movement counter is indeed correct.
In order to implement the comparison counter, you need to restructure your code a bit. In particular, you need to be able to distinguish between Arr1[i]>key and i>=0, since one of them entails a comparison while the other doesn't.
Since this looks like homework, I'll leave the rest for you to figure out.

A* pathfinding slow

I am currently working on a A* search algorithm. The algorithm would just be solving text file mazes. I know that the A* algorithm is supposed to be very quick in finding the finish. Mine seems to take 6 seconds to find the path in a 20x20 maze with no walls. It does find the finish with the correct path it just takes forever to do so.
If I knew which part of code was the problem I would just post that but I really have no idea what is going wrong. So here is the algorithm that I use...
while(!openList.empty()) {
visitedList.push_back(openList[index]);
openList.erase(openList.begin() + index);
if(currentCell->x_coor == goalCell->x_coor && currentCell->y_coor == goalCell->y_coor)
}
FindBestPath(currentCell);
break;
}
if(map[currentCell->x_coor+1][currentCell->y_coor] != wall)
{
openList.push_back(new SearchCell(currentCell->x_coor+1,currentCell->y_coor,currentCell));
}
if(map[currentCell->x_coor-1][currentCell->y_coor] != wall)
{
openList.push_back(new SearchCell(currentCell->x_coor-1,currentCell->y_coor,currentCell));
}
if(map[currentCell->x_coor][currentCell->y_coor+1] != wall)
{
openList.push_back(new SearchCell(currentCell->x_coor,currentCell->y_coor+1,currentCell));
}
if(map[currentCell->x_coor][currentCell->y_coor-1] != wall)
{
openList.push_back(new SearchCell(currentCell->x_coor,currentCell->y_coor-1,currentCell));
}
for(int i=0;i<openList.size();i++) {
openList[i]->G = openList[i]->parent->G + 1;
openList[i]->H = openList[i]->ManHattenDistance(goalCell);
}
float bestF = 999999;
index = -1;
for(int i=0;i<openList.size();i++) {
if(openList[i]->GetF() < bestF) {
for(int n=0;n<visitedList.size();n++) {
if(CheckVisited(openList[i])) {
bestF = openList[i]->GetF();
index = i;
}
}
}
}
if(index >= 0) {
currentCell = openList[index];
}
}
I know this code is messy and not the most efficient way to do things but I think it should still be faster then what it is. Any help would be greatly appreciated.
Thanks.
Your 20x20 maze has no walls, and therefore many, many routes which are all the same length. I'd estimate trillions of equivalent routes, in fact. It doesn't seem so bad when you take that into account.
Of course, since your heuristic looks perfect, you should get a big benefit from excluding routes that are heuristically predicted to be precisely as long as the best route known so far. (This is safe if your heuristic is correct, i.e. never overestimates the remaining distance).
Here is a big hint.
If ever you find two paths to the same cell, you can always throw away the longer one. If there is a tie, you can throw away the second one to get there.
If you implement that, with no other optimizations, the search would become more than acceptably fast.
Secondly the A* algorithm should only bother backtracking if the length to the current cell plus the heuristic exceeds the length to the current cell plus the heuristic for any other node. If you implement that, then it should directly find a path and stop. To facilitate that you need to store paths in a priority queue (typically implemented with a heap), not a vector.
openList.erase is O(n), and the for-loop beginning with for(int i=0;i<openList.size();i++) is O(n^2) due to the call to CheckVisited - these are called every iteration, making your overall algorithm O(n^3). A* should be O(n log n).
Try changing openList to a priority-queue like it's supposed to be, and visitedList to a hash table. The entire for loop can then be replaced by a dequeue - make sure you check if visitedList.Contains(node) before enqueuing!
Also, there is no need to recalculate the ManHattenDistance for every node every iteration, since it never changes.
Aren't you constantly backtracking?
The A* algorithm backtracks when the current best solution becomes worse than another previously visited route. In your case, since there are no walls, all routes are good and never die (and as MSalters correctly pointed, there are several of them). When you take a step, your route becomes worse than all the others that are one step shorter.
If that is true, this may account for the time taken by your algorithm.