Thread: running out of room when I run my program

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    43

    running out of room when I run my program

    The problem is that sometimes when I run my program, sometimes it works, perfectly, then during the game, it just stops, and I can't do anything else.. (No errors/crashing etc..)

    Sometimes it just appears empty, and nothing happens...

    I am not sure why, can someone help me with this im confused, it should work

    Code:
    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    int main ()
        {
        int players_lives = 50;
        int players_points = 0;
        bool me = true;
        int q_n = 1;
        int q_right = 0;
        int q_wrong = 0;
        while (me)
        {
        string wd[50];
        string h[50];
        h[1] = "A common greeting";
        h[2] = "Another word for requirement";
        h[3] = "The end of life";
        h[4] = "To raise your voice";
        h[5] = "Something square that you keep things in";
        h[6] = "None";
        h[7] = "Over time this happens";
        h[8] = "None";
        h[9] = "A living thing";
        h[10] = "None";
        h[11] = "Does not cost anything";
        h[12] = "Green and wavy";
        h[13] = "Another word for bottle";
        h[14] = "A small insect";
        h[15] = "A metal substance";
        h[16] = "Top level of your field";
        h[17] = "Often white, and poofy";
        h[18] = "Always the right thing to tell";
        h[19] = "None";
        h[20] = "An archers weapon";
        h[21] = "Another word for immediately";
        h[22] = "A place for pigs";
        h[23] = "Thy";
        h[24] = "A human emotion";
        h[25] = "Large, green, brown, & woody";
        wd[1] = "hello";
        wd[2] = "need";
        wd[3] = "death";
        wd[4] = "yell";
        wd[5] = "box";
        wd[6] = "annoy";
        wd[7] = "grow";
        wd[8] = "flat";
        wd[9] = "organ";
        wd[10] = "fair";
        wd[11] = "free";
        wd[12] = "grass";
        wd[13] = "flask";
        wd[14] = "fly";
        wd[15] = "led";
        wd[16] = "elite";
        wd[17] = "fluff";
        wd[18] = "truth";
        wd[19] = "all";
        wd[20] = "bow";
        wd[21] = "now";
        wd[22] = "sty";
        wd[23] = "you";
        wd[24] = "love";
        wd[25] = "tree";
        string subs[50];
        int low_index = 1;
        int high_index = 25;
        int lsub_index = low_index;
        int hsub_index = high_index;
        bool can_use[50];
        int x; int i;
        bool cont = true;
        for (int t = 0; t < 50; t++)
            {
            can_use[t] = true;
            }
        string players_word;
        string scrambledword;
        //makes a random number, to select the word we will use
        srand((unsigned)time(0));   
        x = (rand()%high_index)+low_index;
        //gets the length of the string for the while loop
        string::size_type word_length = wd[x].length();
        
        //begins to set subs[] to each letter of wd
        while (low_index-1 < word_length)
            {
            subs[low_index] = wd[x][low_index-1];
            low_index++;
            }
        //loops so all characters are used and not overlap
        while (cont == true)
            {
            i = (rand()%word_length+1)+0;
            if (can_use[i] == true)
                {
                scrambledword = scrambledword + subs[i];
                can_use[i] = false;  
                }
            string::size_type new_word_length = scrambledword.length();
            if (new_word_length == word_length && scrambledword != wd[x])
                {
                cont = false; 
                }
            }
        //for (int keep_top = 0; keep_top < 25; keep_top++) //clears the screen, and shows below at the top
            //{
            //if (keep_top == 10)
                //{
                cout<<"Question ["<<q_n<<"]"<<"\n"<<"\n";
                cout<<"Lives ["<<players_lives<<"]"<<"\n";
                cout<<"Questions right ["<<q_right<<"]"<<"\n";
                cout<<"Questions wrong ["<<q_wrong<<"]"<<"\n"<<"\n";
                cout<<"Word to unscramble is "<<scrambledword<<", Good luck "<<"\n"<<"\n";
                cout<<"Hint - "<<h[x]<<"\n";
            //cout<<"\n";
            //}
        
        getline(cin, players_word);
        //for (int clear_screen = 0; clear_screen < 25; clear_screen++)//clears screen and shows below at the top
            //{
            //if (clear_screen == 4)
                //{ 
                if (players_word == wd[x])
                    {
                    players_points = players_points + 1;
                    cout<<"\n"<<players_word<<" is correct, +1 Point, current points: ["<<players_points<<"]"<<"\n"<<"\n";
                    cout<<"Press enter to continue"<<"\n";
                    q_right = q_right+1;
                    }
                else
                    {
                    cout<<"\n"<<players_word<<" is incorrect, current points: ["<<players_points<<"]"<<"\n"<<"\n";
                    cout<<"Press enter to continue"<<"\n";
                    players_lives = players_lives -1;
                    q_wrong = q_wrong+1;
                    }
                q_n = q_n + 1;
                //}
            //cout<<"\n";
            //}
        if (players_lives <= 0)
            {
            players_lives = 0;
            cout<<"You have lost!"<<"\n";
            cout<<"Press enter to exit"<<"\n";
            me = false;
            } 
        cin.get();
        }
        }
    - reposted code
    Last edited by Mythic Fr0st; 01-18-2007 at 01:51 AM.

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Not that I managed to figure out the cause, but there seems to be a few things that might cause problems. It seems to get into an endless loop. Some cout statements may help to find out where. But better read on.

    The worst of these seems to be that you are starting indexing both at 0 and 1, this is really confusing. This is also probably the reason why I see a +1 in a rand() call: 0-based indexes work really nicely with the % operator, while 1-based require hard work.
    Try to get used to and follow the convention that in C++ all arrays start at index 0, and index a[SIZE] is one beyond the end of the array. Works really nice with %: rand() % SIZE; gives you always a valid index.
    All ranges (as in random_shuffle arguments) include the first element, and the end of the range is one beyond the end of it.
    If you break these rules, it is very easy to get into trouble.

    What you could do:
    make a copy of the program that is runnable without user input. I suppose the error happens at random places and with your random shuffling, so it is easier to debug if you can just let it run and see what happens.

    Or a much-much better idea: throw away a large part of the code and do all the random shuffling (both the list of the words and separate words) using std::random_shuffle() from <algorithm>.

    Code:
    #include <string>
    #include <algorithm>
    #include <iostream>
    
    int main()
    {
        std::string a("CUCUMBER");
        std::string b(a);
        
        std::random_shuffle(b.begin(), b.end()); //see how easy it can be
        
        std::cout << a << '\n' << b << '\n';
        std::cin.get();
    }
    With this method, you'll need a simple struct for starters, to keep the word and the hint together, so they won't end up in different order if each are in a separate array. (Shuffle the questions once, then draw them one after another from the array. Things like can_use complicate things - and may be the readon of the lockup.

    Code:
    #include <cstdlib>
    #include <ctime>
    #include <string>
    #include <algorithm>
    #include <iostream>
    
    struct WordKey
    {
        std::string word;
        std::string key;
    };
    
    int main()
    {
        srand(time(NULL)); //random_shuffle uses rand(), seed yourself
        const int MAX = 3;
        WordKey word_list[MAX]; //std::vector is safer
        //I would consider reading these from a file
        word_list[0].word = "hello";
        word_list[0].key = "A common greeting";
        word_list[1].word = "need";
        word_list[1].key = "Another word for requirement";
        word_list[2].word = "death";
        word_list[2].key = "The end of life";
        
        std::random_shuffle(word_list, word_list+MAX); //here you go
        
        for (int i = 0; i < MAX; i++) {
            std::cout << word_list[i].key << ": " << word_list[i].word << '\n';
        }
        std::cin.get();
    }
    Breaking your code up into smaller functions is also a Good Thing. Your main loop is enormous and does a lot of meaningless work (initializing the same data all over and over). This program should look something like that:
    Code:
    // initialize data, from file or hard-coded
    // random_shuffle words and keys
    while (still_have_questions) { //main game loop
         //random_shuffle word
        //display question
        // get user input
        // evaluate user input
    }
    //sorry out of questions, good-bye
    Last edited by anon; 01-18-2007 at 02:55 AM.

  3. #3
    Registered User
    Join Date
    Jan 2007
    Posts
    43

    hmm

    My script doesn't shuffle the words, it shuffles the "text" inside...

    E.G

    word[1] = "Hello"

    if it picks Word[1], it turns Hello into something like
    hlleo or lleho or 5 random characters of the letters in there

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Well, you display your questions in a random order (x). Shuffling the questions first and then displaying them one after another is the easiest way + it avoids asking the same question several times.

    My first example shows how to shuffle letters in a std::string.

    By the way, I tracked down your error (I think).
    Code:
    while (cont == true)
            {
            i = (rand()%word_length+1)+0; use 0-indexed arrays 
    //and you won't need weird things like that
    //it takes a lot of effort to confirm that this statement doesn't have an error
    //for example, may-be the brackets are in wrong places?
            if (can_use[i] == true)
                {
                scrambledword = scrambledword + subs[i];
                can_use[i] = false;  
                }
            string::size_type new_word_length = scrambledword.length();
            if (new_word_length == word_length && scrambledword != wd[x]) //Cause of lock-up 
                {
                cont = false; 
                }
            }
    I see the intent, but what happens if the shuffled word is the same as the original word? You don't clear the shuffled word, and you don't reset the flags. Therefore the shuffled string cannot be changed and the loop runs for ever.

    Again, with random_shuffle everything would be easier and clearer.

    Code:
        do {
            shuffled_word = std::random_shuffle(original.begin(), original.end());
        } while (shuffled_word == original);
    (This assumes, that it is possible for the shuffled_word to differ from original: original is longer than 1 character and contains more than 1 different letters.)


    [edit] And take the advice and make your arrays run from 0 to (SIZE-1), not 1 to (SIZE). You have mysterious +1's and -1's all over the place only because of that. Breaking the convention makes coding and debugging much harder.[/edit]
    Last edited by anon; 01-18-2007 at 10:12 AM.

  5. #5
    Registered User
    Join Date
    Jan 2007
    Posts
    43

    mm

    Thanks, I understand now, but still few problems

    42 C:\Documents and Settings\Craig\Desktop\Projects - C++\Trivia\Trivia.cpp no match for 'operator=' in 'shuffled_word = std::random_shuffle [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >]((&original)->std::basic_string<_CharT, _Traits, _Alloc>::begin [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>](), (&original)->std::basic_string<_CharT, _Traits, _Alloc>::end [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]())'
    error, from using

    shuffled_word = std::random_shuffle(original.begin(), original.end());

    I also dont understand how I put a string array in this, I get an error too...

    whole code:


    Code:
    #include <cstdlib>
    #include <ctime>
    #include <string>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    struct WordKey
        {
        std::string word;
        std::string key;
        };
        
    int main ()
        { 
        bool me = true;
        srand((unsigned)time(0));
        int players_lives = 50;
        int players_points = 0;
        int q_n = 1;
        int q_right = 0;
        int q_wrong = 0;
        string frog="Hello";
        while (me)
            {
            int low_index = 0;
            int high_index = 25;
            string players_word;
            string scrambledword;
            string shuffle_word;
            std::random_shuffle(frog.begin(), frog.end());
            srand(time(NULL));
            const int MAX = 3;
            WordKey word_list[MAX];
            word_list[0].word = "hello";
            word_list[0].key = "A common greeting";
            word_list[1].word = "need";
            word_list[1].key = "Another word for requirement";
            word_list[2].word = "death";
            word_list[2].key = "The end of life";
        
            std::random_shuffle(word_list, word_list+MAX);
        
            for (int i = 0; i < MAX; i++) 
                {
                std::cout << word_list[i].key << ": " << word_list[i].word << '\n';
                }
            std::cin.get();
            }
        }
    Last edited by Mythic Fr0st; 01-18-2007 at 03:15 PM.

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I'm sorry, my bad. std::random_shuffle returns void: meaning you can't assign the result to anything. The range that you give it will be shuffled in place.

    Here's a reference.

    The function takes two iterators (pointers do just well).

    If you have an array int collection[4], "collection" itself will be a pointer to the beginning of the array. The second parameter is "one past the end" of the range. That would be "collection[4]" and using pointer arithmetics it would be found at address "collection + 4".

    So you'll call: std::random_shuffle(collection, collection + 4);

    With strings and vectors it's a bit easier. Both have a begin() method, that returns an iterator to the beginning of the collection (required as first parameter), and end() method, that returns an iterator to "one past the end".

    Code:
    std::string myString("House");
    std::random_shuffle(myString.begin(), myString.end());
    //now myString is shuffled...

  7. #7
    Registered User
    Join Date
    Jan 2007
    Posts
    43

    hmm

    I did a while (word_list[0].word != real_word[0])
    {
    do the random word thing again for both of em
    }

    (Real_Word, is so that the word stays intact, to check if the player got it correct)

    it works great, thank you for your help

    STILL how do I compare hint, as it is not the same (real_word, and word_list, are the same)

    omg...

    it stops at question 17, everytime

    could it be that there are only 17 words, and if so, how can I repeat them?

    Code:
    #include <cstdlib>
    #include <ctime>
    #include <string>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    struct WordKey
        {
        std::string word;
        std::string key;
        };
    int main()
        {
        int players_lives = 50;
        int players_points = 0;
        int q_n=0;
        int q_r=0;
        int q_w=0;
        bool me = true;
        srand((unsigned)time(0));
        const int MAX = 18;
        WordKey word_list[MAX];
        word_list[0].word = "hello";
        word_list[0].key = "A common greeting";
        word_list[1].word = "need";
        word_list[1].key = "Another word for requirement";
        word_list[2].word = "death";
        word_list[2].key = "The end of life";
        word_list[3].word = "german";
        word_list[3].key = "A language";
        word_list[4].word = "dragon";
        word_list[4].key = "A mythical beast";
        word_list[5].word = "truth";
        word_list[5].key = "The right thing to say";
        word_list[6].word = "orange";
        word_list[6].key = "an orange fruit";
        word_list[7].word = "working";
        word_list[7].key = "The opposite of faulty";
        word_list[8].word = "idiot";
        word_list[8].key = "An insult";
        word_list[9].word = "hint";
        word_list[9].key = "Giving away a tip to someone";
        word_list[10].word = "nut";
        word_list[10].key = "None";
        word_list[11].word = "All";
        word_list[11].key = "None";
        word_list[12].word = "monkey";
        word_list[12].key = "A hairy animal";
        word_list[13].word = "dog";
        word_list[13].key = "A common animal";
        word_list[14].word = "cat";
        word_list[14].key = "An evil animal";
        word_list[15].word = "tree";
        word_list[15].key = "Large, hard & woody";
        word_list[16].word = "water";
        word_list[16].key = "Something you drink alot";
        word_list[17].word = "air";
        word_list[17].key = "You can't breathe without it";
        int high_index = 17;
        string real_word[high_index];
        for (int loop = 0; loop < high_index; loop++)
            {
            real_word[loop] = word_list[loop].word;
            }
            
        string players_word;
        string scrambledword;
        string shuffle_word;
        while (me)
            { 
            std::random_shuffle(word_list, word_list+17);
            std::random_shuffle(real_word, real_word+17); 
            while (word_list[0].word != real_word[0])
                {
                std::random_shuffle(word_list, word_list+17);
                std::random_shuffle(real_word, real_word+17);
                }
            string::size_type word_length = word_list[0].word.length();
            std::random_shuffle(word_list[0].word.begin(), word_list[0].word.end()); 
            q_n = q_n + 1;
            if (q_n == 1)
                {
                cout<<"Question ["<<q_n<<"]\n\n";
                cout<<"Lives ["<<players_lives<<"]\n"<<"Questions Right ["<<q_r<<"]\n"<<"Questions Wrong ["<<q_w<<"]\n"<<"Points ["<<players_points<<"]\n\n";
            
                std::cout <<"Word to unscramble is ["<<word_list[0].word<<"], Good luck.\n";
                std::cout <<"The answer is ["<<real_word[0]<<"]\n";
                getline(cin, players_word);
                }
            else
                {
                cout<<"\n\n\nNext Question ["<<q_n<<"]\n\n";
                cout<<"Lives ["<<players_lives<<"]\n"<<"Questions Right ["<<q_r<<"]\n"<<"Questions Wrong ["<<q_w<<"]\n"<<"Points ["<<players_points<<"]\n\n";
            
                std::cout <<"Word to unscramble is ["<<word_list[0].word<<"], Good luck.\n";
                getline(cin, players_word);
                }
            if (players_word == real_word[0])
                {
                q_r = q_r + 1;
                players_points = players_points + 1;
                cout<<players_word<<" is correct, +1 point.\n";
                }
            else
                {
                q_w=q_w+1;
                players_lives=players_lives-1;
                cout<<players_word<<" is incorrect, -1 life.\n";
                }
             
            std::cin.get();
            }
        cin.get();
        }
    Last edited by Mythic Fr0st; 01-18-2007 at 06:49 PM.

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    A couple of things:
    you have 18 words, so int high_index = 17; should be 18. (And you should use it everywhere instead of magic 17). Remember in C++ ranges, the pointer to the last elements always points to the next element after the collection (if the last element you can access has index 17, the size of the array is 18, and the end of the range is &array[18]).

    struct WordKey is there so you can shuffle words and hints together without them ending up in a different order. The struct keeps the related data together.
    This struct also already contains the "real_word": don't make a copy of the data, if you shuffle the copy, it will not end up in the same order as the WordKey array.

    Before shuffling the letters in the word that is in WordKey struct, make a copy of it and shuffle it. Otherwise, yes, you will destroy the original word in the struct and won't have anything to compare player's answer against.

    Code:
    std::string word_to_use = word_list[n].word;
    std::random_shuffle(word_to_use.begin(), word_to_use.end());
    Also, don't shuffle the array before each question. This function is good if you want to ask the questions in a random order without asking the same word twice. (Or you may re-shuffle the array when you run out of questions and start from index 0 all over.)

    If you don't care if the same word pops up more than once, you don't need to shuffle anything. Just pick a random number (z = rand()%size_of_array; //18 in this case!), random_shuffle the letters in the (copy of the) word and display it.

  9. #9
    Registered User
    Join Date
    Jan 2007
    Posts
    43

    hmm

    I'd rather it doesnt pop up twice, but...

    so I just use the random thing for ".key" and for".word" and they'll match up correctly?

    so the Word will be hello, and the Hint (key) will be "A common greeting"

    Question 1: how do I refer to the "ORIGINAL" word?

    and

    Question 2: how do I reshuffle?
    Last edited by Mythic Fr0st; 01-20-2007 at 11:44 PM.

  10. #10
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Quote Originally Posted by Mythic Fr0st
    I'd rather it doesnt pop up twice, but...

    so I just use the random thing for ".key" and for".word" and they'll match up correctly?

    so the Word will be hello, and the Hint (key) will be "A common greeting"
    That's why you are using a struct (WordKey), and you'll be shuffling an array of structs. WordKey.word and WordKey.key belong together and and are swapped together if you are shuffling the structs.

    Question 1: how do I refer to the "ORIGINAL" word?
    The original word is inside word_list[n].word. You can shuffle the word_list array itself, but don't shuffle the word in it. Assign that to another string first and shuffle the copy.

    Question 2: how do I reshuffle?
    By calling random_shuffle again. Here's some pseudocode how you might do the game logic:
    Code:
    read data
    int question_iterator = ARRAY_SIZE; //18 in your case, but use a variable
    while (player wants to continue) {
        if (question_iterator == ARRAY_SIZE) {
            random_shuffle(the questions);
            question_iterator = 0; //start from the first question
        }
    
        std::string anagram = word_list[question_iterator]; //copy of the word
        random_shuffle(anagram); //shuffle the copy
        display anagram and show hint word_list[question_iterator].key
        get user input and compare against word_list[question_iterator].word
        give feedback and add points
    
        question_iterator++; //increase the iterator to move on to the next question
    } //end game-loop
    The reshuffling is done at the beginning of the loop. If you run out of questions (loop iterator becomes equal to how many questions you have), you'll just random_shuffle the array and set the counter back to 0. Note that before entering the loop, loop iterator is initialized with a value, so that this would happen first time the game loop runs.

    What happens is:
    shuffle
    ask questions: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
    shuffle
    ask questions: 0 1 2 etc

    Because the array is shuffled randomly (like a pack of cards), you can take the questions from it sequencially (like when dealing cards - you don't shuffle the deck between dealing each card) without worrying that you might get the same sequence again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Running program in unix
    By Cpro in forum Linux Programming
    Replies: 2
    Last Post: 02-10-2008, 09:28 PM
  2. DEV-C++ made program crashes when run from outside the ide
    By rainmanddw in forum C++ Programming
    Replies: 3
    Last Post: 01-20-2006, 10:27 PM
  3. Running my program in the background
    By shoobsie in forum Windows Programming
    Replies: 4
    Last Post: 10-09-2005, 02:38 AM
  4. Cannot run program in background?
    By registering in forum Linux Programming
    Replies: 3
    Last Post: 06-16-2003, 05:47 AM
  5. Why is my program running away?
    By badkitty in forum C++ Programming
    Replies: 4
    Last Post: 09-19-2001, 04:27 PM