none
using arrays/loops RRS feed

  • Question

  • im creating the game hammurabi and im stuck ive got the base game all running with the codes for inputs and everything working but im at the stage where i now need to create the results after 10 years and im having trouble storing data after each year for example i need to store the the amount of people starved for every year and then work out the average and display, my code so far is as follows

    // variables
            int year = 1;
            int arrivals = 0;
            int population = 100;
            int acres = 1000;
            int harvested = 0;
            int rats = 5;
            int trading = 18;
            int ratsAte = 0;
            int bushels = 2800;
            int bushelsHarvested = 0;
            int bushelsTrading = 0;
            int plague = 0;
            int starved = 0;

            

            


            private void btnAllocate_Click(object sender, EventArgs e)

            {
                

               
                


                // moves the game forward a year every time the allocate button is clicked
                year = year + 1;


                // random amount of people come to the city
                Random random = new Random();
                arrivals = random.Next(1, 16);
     
                // plague that halfs the population
                Random random4 = new Random();
                plague = random.Next(1, 21);
                if (plague == 1)
                {
                    population = population / 2;
                    MessageBox.Show("You were hit by a plague, half your population died");
                }
                else
                {
                    plague = 0;
                    
                }


                

                // working out the amount of people starved
                if (int.Parse(txtFeeding.Text) < (22 * population / 2))
                {
                    MessageBox.Show("You starved " + population);
                    
                }
                if (int.Parse(txtFeeding.Text) >= (22 * population / 2) && int.Parse(txtFeeding.Text) < 20 * population)
                {
                    starved = ((20 * population) - (int.Parse(txtFeeding.Text))) / 20;
                   
                }

                // possibilty of rats
                Random random2 = new Random();
                rats = random.Next(1, 11);

                if (rats == 5)
                {
                    ratsAte = bushels * 10 / 100;
                    lblRats.Text = "Rats ate " + ratsAte + " bushels.";
                    
                }
                else
                {
                    ratsAte = 0;
                    lblRats.Text = "Rats ate 0 bushels";
                    
                }

                // new population total
                population = population + arrivals - plague - starved;

                // randomised number for trading
                Random random3 = new Random();
                trading = random.Next(17, 27);

                // calculating the amount of acres that are left
                acres = acres + int.Parse(txtBuySell.Text);

                //randomised number of bushels harvested per acre
                Random random1 = new Random();
                harvested = random.Next(1, 6);


                // calculates the amount of bushels harvested and stores it in a variable

                bushelsHarvested = harvested * int.Parse(txtSeed.Text);

                bushels = bushels + bushelsHarvested  - ratsAte - int.Parse(txtFeeding.Text) - int.Parse(txtSeed.Text);

                


                // resets the textboxes
                txtBuySell.Text = ""; 
                txtFeeding.Text = "";
                txtSeed.Text = "";

                // changing the lables to show the new information remaining labels
                lblBushels.Text = "You now have " + bushels;
                lblNewPeople.Text = arrivals + " people came to the city.";
                lblHarvest.Text = "You harvested " + harvested + " bushels per acre.";
                lblPopulation.Text = "The city population is now " + population;
                lblTrading.Text = "land is trading at" + trading + " bushels per acre.";
                lblYear.Text = "In Year " + year + ", " + starved + " people starved.";
                lblRemaining.Text = bushels + " Remaining";



            }

            private void txtBuySell_Leave(object sender, EventArgs e)
            {
                // buy/sell calculation
                if (int.Parse(txtBuySell.Text) < 0)
                {
                    bushelsTrading = Math.Abs(int.Parse(txtBuySell.Text) * trading);
                }
                else if (int.Parse(txtBuySell.Text) >= 0)
                {
                    bushelsTrading = -int.Parse(txtBuySell.Text) * trading;
                }

                bushels = bushels + bushelsTrading;

                // calculating the amount of acres that are left
                acres = acres + int.Parse(txtBuySell.Text);

                lblAcres.Text = "The city now owns " + acres + " acres.";

                lblRemaining.Text = bushels + " Bushels Remaining";
            }

            private void txtFeeding_Leave(object sender, EventArgs e)
            {
                // warning user they dont have enough bushels
                if (int.Parse(txtFeeding.Text) > bushels)
                {
                    MessageBox.Show("You do not have enough bushels in store");
                    return;
                }

                lblRemaining.Text = (bushels - int.Parse(txtFeeding.Text)) + " Bushels Remaining";
            }

            private void txtSeed_Leave(object sender, EventArgs e)
            {
                // tells user that they can not seed more than 10 seed per person
                if (int.Parse(txtSeed.Text) > (10 * population))
                {
                    MessageBox.Show("You can only Plant a max of 10 seeds per person");
                    return;
                }
                if (int.Parse(txtSeed.Text) > acres)
                {
                    MessageBox.Show("you can only plant a max of 1 bushel per acre");
                    return;
                }
                

                lblRemaining.Text = (bushels - int.Parse(txtFeeding.Text)) + " Bushels Remaining";

            }

    Monday, January 21, 2019 7:43 AM

All replies

  • This is a pretty straightforward question to answer but it relies on how much you know about C#. If you haven't heard about List<T> yet then an array is the best choice to store the years but it is going to complicate the code. If you haven't heard about classes/structs yet then you'll have to use multiple parallel arrays which will dramatically increase the complexity of your app.

    Let's go with the parallel array approach as the most complex solution to start with. You'll need a parallel array for each data point you want to track (e.g. arrival, plague). The arrays are synced such that index 1 of arrival goes with index 1 of plague, etc. You only need a single index to track the "current year". Arrays are fixed at creation in terms of size so you'll need to allocate the array for the most # of years you intend to support (e.g. 100). You can dynamically resize arrays later but it is expensive.

    //The data
    const int maximumYears = 100;
    int currentYearIndex = 0;
    
    //The parallel arrays
    int[] arrivals = new int[maximumYears];
    int[] plagues = new int[maximumYears];
    int[] starved = new int[maximumYears];
    
    //Create a new year, using a function here
    int CreateNewYear ()
    {
       return ++currentYearIndex;
    }
    
    //Get information about the current year
    int numberStarved = starved[currentYearIndex];
    
    //Determine average # of starved per year (excluding current year)
    double GetAverageStarved ()
    {
       //Return starved[currentYearIndex] if including the current year
       if (currentYearIndex == 0)
          return 0;
    
       //Using a traditional for loop, to include the current year use <= instead of <
       var sum = 0;
       for (int x = 0; x < currentYearIndex; ++x)
          sum += starved[x];
    
       //Use currentYearIndex + 1 if including current year
       return sum / currentYearIndex;
    }
    
    

    This code becomes simpler if you know about classes because you can replace the parallel arrays with a single class For example you could do this.

    class YearData
    {
       //Using properties here
       public int Arrived { get; set; }
       public int Plague { get; set; }
       public int Starved { get; set; }
    }

    Since this is a class you also don't really need to track the current index anymore, just use an instance of the class.

    YearData CreateNewYear ()
    {
       var data = new YearData();
    
       //Add to your array
       years[++currentYearIndex] = data;
    
       return data;
    }
    
    //To use current year
    currentYear = CreateNewYear();
    currentYear.Plagued
    

    Note that in the array code you have to be careful that you don't skip year 0 which means you'll probably start currentYearIndex at -1. Furthermore using for loops to enumerate the years can get ugly as the usage increases. Replacing the array with List<T> would be the next step and it eliminates the need for an index altogether. It also eliminates the need for tracking the # of current years and specifying a maximum number of years.

    //Init code
    List<YearData> years = new List<YearData>();
    
    YearData CreateNewYear ()
    {
       var data = new YearData();
       years.Add(data);
    
       return data;
    }
    
    //Store the current year where you need it
    var currentYear = CreateNewYear();
    
    //Calculate average, includes current year
    double GetAverageStarved ( )
    {
       if (years.Count == 0)
          return 0;
    
       var sum = 0;
       foreach (var year in years)
          sum += year.Starved;
    
       return sum / years.Count;
    }

    Finally, whenever you see a for/foreach loop there is a good chance you can simply use LINQ to reduce the code.

    double GetAverageStarved ()
    {
       return years.Average(y => y.Starved);
    }
    
    //Or if using the newest compiler and expression bodies
    double GetAverageStarved => years.Averagee(y => y.Starved);
    Note that less code does not mean it is more readable so find a happy balance between what you understand and what works.


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, January 21, 2019 6:08 PM
    Moderator
  • hey im writing up the code for my hammurabi game for my college work and im having some issues with using arrays, the game isset to play over 10 years where the year moves forward by 1 every time you click the button which works out different things based on the data entered by the user


            private void Form1_Load(object sender, EventArgs e)
            {
    
            }
            // variables
            int year = 1;
            int arrivals = 0;
            int population = 100;
            int acres = 1000;
            int harvested = 0;
            int rats = 5;
            int trading = 18;
            int ratsAte = 0;
            int bushels = 2800;
            int bushelsHarvested = 0;
            int bushelsTrading = 0;
            int plague = 0;
            int died = 0;
            double averageStarved = 0;
            double averageAcres = 0;
            double totalStarved = 0;
            
    
            private void btnAllocate_Click(object sender, EventArgs e)
    
            {
               
                // moves the game forward a year every time the allocate button is clicked
                year = year + 1;
    
                // random amount of people come to the city
                Random random = new Random();
                arrivals = random.Next(1, 16);
     
                // plague that halfs the population
                Random random4 = new Random();
                plague = random.Next(1, 21);
                if (plague == 1)
                {
                    population = population / 2;
                    MessageBox.Show("You were hit by a plague, half your population died", "Plague", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else
                {
                    plague = 0;
                    
                }
    
                // working out the amount of people starved
                if (int.Parse(txtFeeding.Text) < (22 * population / 2))
                {
                    population = population / 2;
                    MessageBox.Show(population + " You starved Half your population", "Starved", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    
                }
                if (int.Parse(txtFeeding.Text) >= (22 * population / 2) && int.Parse(txtFeeding.Text) < 20 * population)
                {
                    died = ((20 * population) - (int.Parse(txtFeeding.Text))) / 20;
    
                }
                else
                {
                    died = 0;
                }
    
     
                // new population total
                population = population + arrivals - plague - died;
    
                // randomised number for trading
                Random random3 = new Random();
                trading = random.Next(17, 27);
    
                
    
                //randomised number of bushels harvested per acre
                Random random1 = new Random();
                harvested = random.Next(1, 6);
    
                // possibilty of rats
                Random random2 = new Random();
                rats = random.Next(1, 11);
    
                
    
                // calculates the amount of bushels harvested and stores it in a variable
    
                bushelsHarvested = harvested * int.Parse(txtSeed.Text);
    
                // adds the bushels harvested to the users bushels
                bushels = bushels + bushelsHarvested;
    
                // works out how much rats have eaten 
                if (rats == 5)
                {
                    ratsAte = bushels * 10 / 100;
                    lblRats.Text = "Rats ate " + ratsAte + " bushels.";
                    MessageBox.Show("Rats ate " + ratsAte + " bushels");
    
                }
                else
                {
                    ratsAte = 0;
                    lblRats.Text = "Rats ate 0 bushels";
    
                }
    
                // takes the amount of bushels that the rats ate away fromthe remaining bushels
                bushels = bushels - ratsAte;
    
                // adds the amount died from starvation each year to a variable
                averageStarved = died + averageStarved;
                totalStarved = averageStarved;
    
                // end of year evaluation 
                if (year == 11)
                {
                    pnlEvaluation.Visible = true;
                    pnlResults.Visible = true;
                    lblResultsTitle.Visible = true;
                    averageAcres = acres / population;
                    averageStarved = averageStarved / 10;
                    lblAverageAcres.Text = "You started with an average of 10 acres per person and ";
                    lblAverageAcres2.Text = "ended with an average of " + averageAcres + " per person.";
                    lblAverageStarved.Text = averageStarved + " people starved on average every year, ";
                    lblAverageStarved2.Text = totalStarved + " in total died during your reign.";
                    
                    if (averageAcres <= 7 && averageStarved > 0)
                    {
                        lblEvaluation.Text = "Due to your reckless missmanagement of resources the people ";
                        LBLEvaluation2.Text = "find you a horrible and disgusting ruler and want you beheaded.";
                    } 
                    if (averageAcres >= 13 && averageStarved < 1)
                    {
                        lblEvaluation.Text = "You have managed to keep every fed and happy over the years, ";
                        LBLEvaluation2.Text = "your people are looking forward to your next reign.";
                    }
                    if ((averageAcres > 7 && averageAcres < 13  ) && (averageStarved == 0))
                    {
                        lblEvaluation.Text = "You have had a very average reign and your people expected more, ";
                        LBLEvaluation2.Text = "Improvement need or yoou may be overthrown.";
                    }
                    
                    return;
                }
    
                // resets the textboxes
                txtBuySell.Text = "";
                txtFeeding.Text = "";
                txtSeed.Text = "";
    
                // changing the lables to show the new information remaining labels
                lblNewPeople.Text = arrivals + " people came to the city.";
                lblHarvest.Text = "You harvested " + harvested + " bushels per acre."; 
                lblPopulation.Text = "The city population is now " + population;
                lblTrading.Text = "land is trading at " + trading + " bushels per acre.";
                lblYear.Text = "In Year " + year + ", " + died + " people starved.";
                lblBushels.Text = "You now have " + bushels;
                lblRemaining.Text = bushels + " Bushels Remaining";
    
              
    
            }
    
            private void txtBuySell_Leave(object sender, EventArgs e)
            {
                // validation, making sure user doesnt leave the textbox empty
                if (string.IsNullOrWhiteSpace(txtBuySell.Text) == true)
                {
                    MessageBox.Show("Please enter an amount of acres to sell/buy");
                    return;
                }
                 
                // buy/sell calculation
                if (int.Parse(txtBuySell.Text) < 0)
                {
                    bushelsTrading = Math.Abs(int.Parse(txtBuySell.Text) * trading);
                }
                else if (int.Parse(txtBuySell.Text) >= 0)
                {
                    bushelsTrading = -int.Parse(txtBuySell.Text) * trading;
                }
    
                // calculating the amount of acres that are left
                acres = acres + int.Parse(txtBuySell.Text);
    
                // updating the bushels amount
                bushels = bushels + bushelsTrading;
    
                // changing the labels to reflect new information
                lblRemaining.Text = bushels + " Bushels Remaining";
                lblAcres.Text = "The city now owns " + acres + " acres.";
                lblBushels.Text = "You now have " + bushels;
    
            }
    
            private void txtFeeding_Leave(object sender, EventArgs e)
            {
                // validation, making sure user doesnt leave the textbox empty
                if (string.IsNullOrWhiteSpace(txtFeeding.Text) == true)
                {
                    MessageBox.Show("Please enter an amount of bushels to feed your peopl");
                    return;
                }
    
    
                // warning user they dont have enough bushels
                if (int.Parse(txtFeeding.Text) > bushels)
                {
                    MessageBox.Show("You do not have enough bushels in store");
                    return;
                }
    
                bushels = bushels - int.Parse(txtFeeding.Text);
                lblRemaining.Text = bushels + " Bushels Remaining";
                lblBushels.Text = "You now have " + bushels;
    
            }
    
            private void txtSeed_Leave(object sender, EventArgs e)
            {
                // validation, making sure user doesnt leave the textbox empty
                if (string.IsNullOrWhiteSpace(txtSeed.Text) == true)
                {
                    MessageBox.Show("Please enter an amount of bushels to seed");
                    return;
                }
    
                // tells user that they can not seed more than 10 seed per person
                if (int.Parse(txtSeed.Text) > (10 * population))
                {
                    MessageBox.Show("You can only Plant a max of 10 seeds per person");
                    return;
                }
    
                bushels = bushels - int.Parse(txtSeed.Text);
    
                lblRemaining.Text = bushels + " Bushels Remaining";
                lblBushels.Text = "You now have " + bushels;
    
           
    
            }

    thats my code at the moment, what im looking to do is use arrays so that i can store the amount of people that have starved each year(each button click) and be able to call back to them later so that i can work out the averages over a 10 year period

    Friday, February 1, 2019 2:52 PM
  • Friday, February 1, 2019 4:28 PM