Hello,
I'm working on a text base space game, just for fun, and I've made a lot of progress. The problem I'm having right now is that sometimes, the psuedo-random is calculated out of its modulus. The way it works, as you can see in the code is that a random number is seeded based on the enemy's stats (like they can attack up to 50,40, etc), then that number is subtracted from a random location on the ship (hull, engine, etc.) However, at random times, I get stuff in the output that says like: "Your hull now has -2708998 health left." Is this a problem with the random function or is it a problem with my code? Thanks much!

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <conio.h>
#include <windows.h>

using namespace std;

//global vars
int zone;
int enemy;

//function declares
void zonePick(int theZone);
void zone1();
void fight(int theEnemy);
int getEnemy();

//Ship Stats
int hull   = 100;
int engine = 100;
int wepsys = 100;
int money  = 4000;


//Main Function
int main()
{
    string shipName;
    cout << "Space Simuator v0.1" << endl;
    Sleep(1000);
    cout << "Enter a name for your ship!" << endl;
    cin >> shipName;
    cout << "You are the captain of " << shipName << "!" << endl;
    Sleep(500);
    cout << "Your job is to guide the " << shipName << " through the perils of space!" << endl;
    cout << "Choose where you want to go in the map?" << endl;
    Sleep(1000);
    cout << "1-Zone One" << endl;
    Sleep(500);
    cout << "2-Zone Two" << endl;
    Sleep(500);
    cout<<"3-Zone Three"<<endl;
    Sleep(500);
    cout << "4-Zone Four" << endl;
    cin >> zone;
    zonePick(zone);
}


//There's only one zone right now
void zonePick(int theZone)
{
    switch(theZone)
    {
        case 1:
            zone1();
            break;
        default: cout << "Zone doesn't exist!" << endl;
    }
}


//Zone 1
void zone1() {
    int option;
    cout << "Welcome to Zone 1!" << endl;
    Sleep(500);
    cout << "Here's an update of your ship's condition!" << endl;
    cout << "Hull: " << hull << endl;
    cout << "Engine: " << engine << endl;
    cout << "Weapon System: " << wepsys << endl;
    cout << "Money: " << money << endl;
    Sleep(1000);
    getEnemy();
    cout << "Do you wish to (1) Fight or (2) Pay?" << endl;
    cin >> option;
    if (option == 1) {
        fight(enemy);
    }

    //Pay to get out!
    if (option == 2) {
        cout << "You now have only " << money-200 << " gold left!" << endl;
        cout << "Which zone would you like to go next?" << endl;
        cout << "1-Zone One" << endl;
        Sleep(500);
        cout << "2-Zone Two" << endl;
        Sleep(500);
        cout << "3-Zone Three" << endl;
        Sleep(500);
        cout << "4-Zone Four" << endl;
        cin >> zone;
        zonePick(zone);
    }
}

//fight function
void fight(int theEnemy) {
    int ENatk;
    int ENhull;
    int ENengine;
    int ENwepsys;
    switch (theEnemy) {
        case 1:
            cout << "You've encountered a Raider!" << endl;
            ENatk    = 40;
            ENhull   = 100;
            ENengine = 100;
            ENwepsys = 100;
            break;
        case 2:
            cout << "You've encountered a Bandit!" << endl;
            ENatk    = 30;
            ENhull   = 85;
            ENengine = 75;
            ENwepsys = 50;
            break;
        cout << "You've encountered a Ghost!" << endl;
        ENatk    = 50;
        ENhull   = 50;
        ENengine = 200;
        ENwepsys = 50;
    }
    //Attack Damage Random
    srand (time(NULL));

    int damage = rand() % ENatk;
    if (ENatk == 0) {
        cout << "The enemy missed!" << endl;
    }
    //Attack Location Random
    srand(time(NULL));

    int atkLocation = rand() % 3 + 1;
    switch (atkLocation) {
        //Damaged Hull
        case 1: {
            Sleep(1000);
            int currentHull = hull - damage;
            cout << "Your hull has only " << currentHull << " health left!" << endl;
            break;
        }
        //Damaged Engine
        case 2: {
            Sleep(1000);
            int currentEngine = engine - damage;
            cout << "Your engine has only " << currentEngine << " health left!" << endl;
            break;
        }
        //Damaged Weapon System
        case 3: {
            Sleep(1000);
            int currentWepSys = wepsys - damage;
            cout << "Your weapon system has only " << currentWepSys << " health left!" << endl;
        }
    }
    //Prompt User to Attack
    Sleep(1000);
    cout << "Now you attack!" << endl;
}

//Get Enemy Ship
int getEnemy() {
    srand(time(NULL));
    enemy = rand() % 3 + 1;
    return enemy;
}

Edited 4 Years Ago by mike_2000_17: fixed formatting

Anytime you get a large negative number, there are two things to check straight away:

  1. Any uninitialized variables in your math.
  2. Any out of bounds indexing or invalid pointers (they can corrupt other variables).

Either way the problem isn't in rand(), it's your code doing something funky.

Hey! Thanks for the reply. Yeah, I suspected that it was mostly something wrong with my code. I don't have any pointers at this time, so I'm thinking it might be problem number one. Hoever, I can't seem to find any unintialized variables, and if so my compiler would've given me a warning? This is not the case right now.

-- Hint: I fixed your formatting. Errors are easier to spot that way. You should develop the habit of doing so yourself in the future. --

My guess is that error comes from forgetting to put the default: statement (or case 3:) between line 118 and 119. Basically, if the "enemy" in not 1 or 2, then the variables (ENatk, ENhull, ENengine, ENwepsys) remain uninitialized, which explains the weird values you get afterwards (which comes from line 128 where ENatk might be uninitialized and cause "damage" to be some very weird / large number).

Thank you so much for the edit! I will definitely remember to post like this from now on. Also, thanks for pointing out the error, I actually forgot to type case 3 :P Thanks much both of you! Rep has been given.

Edited 4 Years Ago by Carpetfizz

This question has already been answered. Start a new discussion instead.