Home > Software engineering >  C outer loop not going past first iteration even though change inside works fine
C outer loop not going past first iteration even though change inside works fine

Time:10-09

I am working on an ASCII animation and after the image prints from the .txt file, I tested out a block of 6 characters changing each "frame" in a for loop, which worked fine and the code for which is in the block commented out section. However, after adding an algorithm to have a blast cone looking animation, the outermost for loop in the function only iterates once.


The block of text that is meant to be generated each iteration of the outermost loop is generated the first time, but the loop stops there and then within 0.5s from this block of text being printed the program closes for some reason even though the animation_section() function iterated through the for loop fine and the program did not suddenly terminate.


Because the block of text is actually generated for every line, I don't know how the problem would originate from that change since that would mean both of the two inner for loops in the new code would run through fine, and the outermost for loop ran fine with the more manual approach of outputting text seen in the block commented out section.

#include <iostream>
#include <fstream>
#include <string>
#include <chrono>
#include <thread>
#include <limits>
#include <windows.h>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std::literals;

void gotoxy( int column, int line ){
  COORD coord;
  coord.X = column;
  coord.Y = line;
  SetConsoleCursorPosition(
    GetStdHandle( STD_OUTPUT_HANDLE ),
    coord
    );
}

void setPos(int col, int row){
    gotoxy(col, row); // windows
    //printf("\033[%d;%dH", row, col); // linux/terminal
    //std::cout << "\033[F"; // for single line up, linux/terminal

}

std::string global_sequence1 = "!@#$%^&*()-_ =`~,.<>/';]}[{\\|";
std::string global_sequence2 = "qwertyuiopasdfghjklzxcvbnm";

std::string sequence_selection(std::string x){
    std::string y = x;
    random_shuffle(y.begin(), y.end());
    std::string first_five = y.substr(0, 5);
    return first_five;
}

void list_generation(std::vector<std::string>& list1, std::vector<std::string>& list2){
    for (int i=0; i<30; i  ){
        list1.push_back(sequence_selection(global_sequence1));
        list2.push_back(sequence_selection(global_sequence2));
    }
}

void Animation_section(){
    std::vector<std::string> s_list1; // random 5 chars from global_sequence1
    std::vector<std::string> s_list2; // random 5 chars from global_sequence2
    list_generation(s_list1, s_list2);

    
    
    auto duration = 10000s;
    auto duration_step = 50ms;
    for (auto i = 0; i < (duration/duration_step);   i) {
        // new code start
        int col_ref0 = 53;
        for (int k = 11; k <= 33; k  ){ // per line
            setPos(col_ref0-floor(k*1.3), k); // higher floor coef moves blast cone left
            int a = floor(1.1892*k - 13.614); // min line length, line eq = 1.1892*k - 13.614
            int b = a   floor(k/6);
            int line_len = a   (rand() % static_cast<int>(b - a   1));
            // add a scrambler for list1 and list2 before iterating through each line to avoid repeititon
            for (int j = 0; j <= line_len; j  ){ // iterates through each col in the line length
                if ( 0.80 > ((float) rand() / (RAND_MAX)) ){ // selects whether or not the coord displays something
                    if ( 0.60 > ((float) rand() / (RAND_MAX)) ){
                        std::cout << s_list1[j][i%s_list1[j].size()]; // print list1
                    }else{
                        std::cout << s_list2[j][i%s_list2[j].size()]; // print list2
                    }
                }else{
                    std::cout << " ";
                }
                if (j == line_len){
                    std::cout << std::flush;
                }
            }
        }
        // new code end
        

        /*
        setPos(20,20);
        std::cout << s_list1[0][i%s_list1[0].size()] << s_list1[1][i%s_list1[1].size()] <<
         s_list1[2][i%s_list1[2].size()] << "\n" << std::flush;

        setPos(20,21);

        std::cout << s_list2[0][i%s_list2[0].size()] << s_list2[1][i%s_list2[1].size()] <<
         s_list2[2][i%s_list2[2].size()] << std::flush;

        setPos(20,20);
        */

        std::this_thread::sleep_for(duration_step);
        // add if statement for breaking animation to next screen for linux
        if (GetAsyncKeyState(VK_RETURN)){
            break;
        }
    }
}


int main(){
    //welcome();
    Animation_section();
    //std::cin.get();   //press key to continue
    std::system("cls");
    loadingSymbol();
    std::cin.get(); //press key to continue

}
       

this is produced before the program terminates on its own

this is produced from the old block commented out section, and the block of 6 characters on the left is changing every "frame" as intended

CodePudding user response:

in last iteration, you end up with:

a = 25
b = 30 

int line_len = a   (rand() % static_cast<int>(b - a   1))

b - a   1  == 6

25   rand % 6 has a maximum value of 30

30 is out of range on your s_list2 and s_list1 arrays
  • Related