Genghis Khan
Genghis Khan

Reputation: 19

C++ Variable not updating in While Loop

I have been programming for about 3 weeks now and I'm making this civ game. The only problem is during each round, your stats for civ update each round but after the second round, they do not update. Basically what I want the program to do is add up each of resources after each round and calculate the population and gold, but it's not happening after the first round. I have never gotten classes to work, so don't expect me to get it right the first time.

Here is the code for the update that should happen each round inside the function:

int RoundTotal(int yg, int yk, int yf, int ys, int yr, int yfi,
    int co, int rtp, int gtp, int ap, double tr, int yp, int dp,
    int int yd, double fp) {

    int YourGold = yg, YourStrength = ys, YourKnow = yk, YourFood = yf, 
    YourResource = yr, YourFields = yfi, YourPopulation = yp, YourDefense = yd;

    int ResourceTradeProfit = rtp, GoldTradeProfit = gtp, DroughtProduction = dp;

    int totals, count = co, ArcherPay = ap;
    double taxrate = tr,  FoodProduction = fp;

    if (YourStrength<0) {
        YourStrength = 0;
    }
    FoodProduction = (0.5*YourFields + 0.5*YourKnow - 0.02*YourPopulation)*DroughtProduction;

    YourFood = YourFood + FoodProduction;

    YourGold = YourGold + (taxrate/100)*YourPopulation; 

    YourGold -= (YourStrength / 2);
    YourGold -= YourKnow;
    YourGold -= YourFood;
    YourGold -= ArcherPay;
    YourResource += ResourceTradeProfit;
    YourGold += GoldTradeProfit;

    YourPopulation = YourPopulation + YourFood*FoodProduction;

return totals, YourGold, YourKnow, YourFood, YourStrength,
        YourResource, YourFields, count, ResourceTradeProfit,
        GoldTradeProfit, ArcherPay, taxrate, YourPopulation,
        DroughtProduction, FoodProduction;

Disregard all of the abbreviations for the variables up top, unless they are the problem.

Upvotes: 1

Views: 5216

Answers (2)

pstrjds
pstrjds

Reputation: 17428

Your objects are not being updated because you are only passing out a single integer from your method and since you are copying all of the data, all of the operations you are performing in the update function are only operating on the copies and not the original values from the calling side of the operation.

As I mentioned in my comment, you should probably reconsider your design and consider using a class which contains the values you want to update. This answer is not intended to show the "best" design, but it should point you in the right direction. In general, having a method signature that takes more than 3 or 4 arguments is difficult to use and makes reading the code much more difficult (I highly recommend reading Robert Martin's book Clean Code). This is an example of how you could use a class to pass around the necessary data. You may want to make the update function a part of this class. You may also want to consider just passing in the data object as a reference and updating it directly, but that will all depend on your overall design.

Note I didn't test this and may have missed one of your operations in the update method, but hopefully this points you in the right direction.

class YourData
{
    public:
        int Gold;
        int Strength;
        int Know;
        int Food;
        int Resource;
        int Fields;
        int Population;
        int Defense;

        int ResourceTradeProfit;
        int GoldTradeProfit;
        int DroughtProtection;
        double FoodProduction;

        // Normally you would split out the function definitions between
        // a header file and a .cpp file, but for the example I am just
        // putting the code here.
        YourData() {} // Default constructor
        YourData(const YourData& data) // Copy constructor
        {
            Gold = data.Gold;
            Strength = data.Strength;
            // Left out other data members for brevity
        }

        void updateFoodProduction()
        {
            FoodProduction = (0.5 * Fields + 0.5 * Know - 0.02 * Population) * DroughtProduction;
        }
}

YourData roundTotals(const YourData& data, double taxRate, int archerPay)
{
    YourData updated(data);
    if (updated.Strength < 0) updated.Strength=0;

    updated.updateFoodProduction();
    updated.Food += updated.FoodProduction;
    updated.Gold += (taxrate/100) * updated.Population; 
    updated.Gold -= (updated.Strength / 2);
    updated.Gold -= updated.Know;
    updated.Gold -= updated.Food;
    updated.Gold -= archerPay;
    updated.Resource += updated.ResourceTradeProfit;
    updated.Gold += GoldTradeProfit;

    updated.Population += updated.Food * FoodProduction;

    return updated;
}

Upvotes: 3

Josh Simani
Josh Simani

Reputation: 107

Instead of trying to return all of the values, which is not an option in C++, you could pass the parameters of the function by reference, so that they are updated even when the function ends. To do this, you simply place the & operator before the name of the variable in the function prototype and definition. For example, the function square, which multiplies an integer by itself and updates the value of that integer:

#include <iostream>
using namespace std;

void square(int &n);

int main()
{
    int i = 4;
    cout << "Before: " << i << endl;
    square(i);
    cout << "After: " << i << endl;

    return 0;
}

void square(int &n) 
{
    n = n * n;
}

Output:

Before: 4
After: 16

Upvotes: 0

Related Questions