Java Notes

Programming: Hammurabi 0

Description

Your program will simulate the functioning of an early agricultural society. It is based on the ancient computer game Hammurabi, named after a Babylonian king (See en.wikipedia.org/wiki/Hammurabi) famous for his laws. He also ran a very authoritarian society in which the peasants were allocated fixed rations of food by the state.

Goal. The user, who has just become the ruler of a kingdom, wants to make a place in history by having having the largest population of peasants. The simulation will last five years or until everyone has starved.

Grain is the basic resource. Each year, ask the ruler how to use the grain in storage.

The remaining grain, if any, is saved for the next year in case of a bad harvest.

Initial Conditions

The Kingdom starts with the following resources: an area of 1000 acres, a population of 100, and with 3000 bushels of grain from the previous harvest.

Food and Population Rules

Each peasant needs a minimum of 20 bushels of grain per year to survive.

Starvation. If the ruler doesn't allocate enough food for everyone, some will starve. The population is then reduced by the number of peasants who starved.

Immigrants if lots of food. If people receive more than 20 bushels per person, immigrants from neighboring kingdoms will be attracted, resulting in a population increase.

Formula. This simplistic idea of the size of the population can be computed by simply dividing the total amount of food by the amount needed per person.

    k_peasants = food / FOOD_REQUIRED_PER_PERSON

This is inside the simulateOneYear method, where k_peasants is an instance variable representing the Kingdom's current population, and FOOD_REQUIRED_PER_PERSON is a constant predefined to be 20.

For example, if the ruler allocates 2400 bushels, this will support a population of 2400 / 20, which is 120. This would become the new population.

Agriculture

Seed for Planting. Not all grain can be used for feeding the people. Some must be used to plant next year's crop. It takes two bushels of grain to plant an acre. To plant everything therefore requires 2 * area bushels of grain.

Harvest. There are variations in the weather each year. The yield varies from 2 to 6 bushels per planted acre. This number is randomly generated each year.

issues

The main program gets information from the user/ruler on how to allocate the grain each year, simulates one year, and display the results for that year. It should continue in a loop until the end of the simulation time period or the peasants have starved.

The simulateOneYear method, which takes parameters for how much grain to use to plant the next crop, and how much grain to feed the population. Extend it to add population.

Keep all input/output in the main method.

Check for legal values, eg, don't allow the ruler to plant more grain than there is.

Copy these files to start your project

In the spirit of iterative programming, here is a working version, but it doesn't implement all features. Most notably the population isn't implemented. Some areas that must be extended are marked with "TODO" (ie, things remaining "to do").

Hammurabi first version

This class runs the simulation and provides the user interface. It contains the main method, as well as a couple of other methods.

  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
 79 
 80 
 81 
 82 
 83 
 84 
 85 
 86 
 87 
 88 
 89 
// File   : hammurabi-noop/Hammurabi0.java
// Purpose: Starting point for working on the Hammurabi program.
// Author : Fred Swartz - 2006-Dec-06 - Placed in public domain.
// TODO   : * Prompt for amount to feed peasants.
//          * Check that there is enough grain to meet requests.
//          * Also stop simulation if population is 0 (while condition)

import java.util.*;

public class Hammurabi0 {
    //=============================================================== constants
    private final static int MIN_GRAIN_TO_SURVIVE         = 20;
    private final static int MAX_LAND_FARMABLE_PER_PERSON = 15;
    private final static int SEED_REQUIRED_PER_ACRE       = 2;

    //=============================================================== variables
    // Everything prefixed with "k_" is part of the status of a Kingdom.
    //   All "k_" variables should be part of a Kingdom class, but....
    private static int k_grain = 3000; // Bushels of grain in storage.
    private static int k_area  = 1000; // Area of kingdom in acres.  Note that
                                       // k_area isn't used yet, but will be if
                                       // you add a check for the total amount
                                       // of land that can be planted.
    private static int k_year    = 0;  // Years since founding of kingdom.
    private static int k_harvest = 0;  // Last harvest in bushels.
    private static int k_peasants = 100; // Number of peasants.


    //================================================================== main
    public static void main(String[] args) {
    
        Scanner in = new Scanner(System.in);

        //... Run the simulation for 5 years or until everyone starves.
        while (k_year <= 5) {
            //... Display state of the kingdom at beginning of each year.
            System.out.println(getStatusReport());

            //TODO: Ask the ruler how much to feed the people.
            int food = 0;  // Temporary substitute for asking for input.

            //.. Ask the ruler how much grain should be used for seed.
            System.out.println("Exalted Ruler, how much of the remaining "
                    + (k_grain - food) + " bushels should be planted?");
            int seeds = in.nextInt();

            //... TODO: Check if not enough grain for this request, Reprompt.

            //... Update the food and population of this kingdom.
            simulateOneYear(food, seeds);
        }

        //... Show final state.
        System.out.println(getStatusReport());
    }
    //========================================================== getStatusReport
    public static String getStatusReport() {
        // TODO: Don't forget to add population here too.
        return "  Kingdom status at year " + k_year
               + ", last harvest = " + k_harvest
               + ", total grain = " + k_grain;
    }

    //========================================================= simulateOneYear
    public static void simulateOneYear(int food, int seed) {

        //TODO: Need to calculate new population.based on food.

        //... Reduce grain stockpile by amount used for food and seed
        k_grain = k_grain - food - seed;

        //... Calculate new harvest
        //    1. How many acres can be planted with seed.
        //    2. The yield per acre is random (2-6)
        //    3. Harvest is yield * area planted.
        int acresPlanted = seed / SEED_REQUIRED_PER_ACRE;
        
        // TODO: Check that there are enough people and there is
        //       enough land to actually plant that number of acres.
        int yieldPerAcre = 2 + (int)(5 * Math.random());
        
        k_harvest        = yieldPerAcre * acresPlanted;

        //... Compute new amount of grain in storage.
        k_grain += k_harvest;  // New amount of grain in storage.

        k_year++;              // Another year has passed.
    }
}

Misc info

Extra credit possibilities

This above game omits some interesting aspects. After you have the simple version of the program running as described above, you might want to make it more "realistic" by adding some of the following features.