CIT 590 Assignment 3: Hammurabi
Spring 2009, David Matuszek

Purposes of this assignment:

General idea of the assignment:

Hammurabi is a very old computer game. Your job is to bring it into the 21st century by writing it in Java.

Here are the standard instructions for the game:

Congratulations, you are the newest ruler of ancient Samaria, elected for a ten year term of office. Your duties are to dispense food, direct farming, and buy and sell land as needed to support your people. Watch out for rat infestiations and the plague! Grain is the general currency, measured in bushels. The following will help you in your decisions:

Rule wisely and you will be showered with appreciation at the end of your term. Rule poorly and you will be kicked out of office!

Details:

This program will use lots of methods, many of them very short. Begin by working out, with your partner,

Each of you should write approximately half of the methods.

Initially, you will start out with

Each year, print out a summary similar to the following:

O great Hammurabi!
You are in year 1 of your ten year rule.
In the previous year 0 people starved to death.
In the previous year 5 people entered the kingdom.
The population is now 100.
We harvested 3000 bushels at 3 bushels per acre.
Rats destroyed 200 bushels, leaving 2800 bushels in storage.
The city owns 1000 acres of land.
Land is currently worth 19 bushels per acre.

The above summary represents the initial state, at the beginning of the first year--that is, when you first take office, and before you do any of the computations below). So, for example, the previous year (under a different ruler) must have started with 95 people; none starved, and 5 entered the kingdom, so as you enter office you rule 100 people.

Here's what you need to do each year, for 10 years:

Ask the player for:

Each of these questions should be asked in a separate method. For each question, do "sanity checking"; that is, test whether the answer is possible (you have enough grain, you have enough people to do the planting etc.), and keep asking until you get a possible value. (For example, O Great Hammurabi, we have only 3415 bushels left!)

Then you need to determine:

If there is a plague
Each year, there is a 15% chance of a horrible plague. When this happens, half your people die.
How many people starved
Each person needs 20 bushels of grain to survive. If you feed them more than this, they are happy, but the grain is still gone. If more than 45% of the people starve, you will be immediately thrown out of office, and the game ends.
How many people came to the city
Nobody will come to the city if people are starving. If everyone is well fed, compute how many people come to the city as: (20 * number of acres you have + amount of grain you have in storage) / (100 * population) + 1.
How good the harvest is
Choose a random number between 1 and 5. Each acre that was planted with seed will yield this many bushels of grain. (Example: if you planted 50 acres, and your number is 3, you harvest 150 bushels of grain).
If you have a problem with rats
There is a 40% chance that you will have a rat infestation. When this happens, rats will eat somewhere between 1/10 and 3/10 of your grain.
How much land costs (for next year)
The price of land is random, and ranges from 17 to 23 bushels per acre. The player will need this information in order to buy or sell land.

Do these computations, in this order, for each of ten years. Each computation should be done in a separate method, and none of these methods should read anything or print anything. Each method should return a result, and the method that calls these methods should save the result in an instance variable.

When the computations are finished, call yet another method to print the summary for the year.

At the end, use a method to print out a final summary, and to tell the player how good a job he/she did. I'll leave the details up to you, but the usual evaluation is based on how many people starved, and how many acres per person you end up with.

All the required arithmetic in this program should be integer. You do not need doubles.

I suggest that you first get the simplest possible version of the program running and tested out (that is, leave out things like rats, plagues, and immigration), then add these things one at a time to a working program, testing as you go.

Things you need to know:

Random numbers

To get a random number generator, you first need to import java.util.Random (or java.util.*). Then, you can create a random number generator with a statement such as:

static Random rand = new Random();

To get a new random number in the range 0..n-1, where n is an int, call rand.nextInt(n). To get a new random number in the range min..max, use the expression rand.nextInt(max - min + 1) + min. You can use the rand method in statements such as

myNewNumber = rand.nextInt(5);
if (rand.nextInt(100) < 15) { ... }

To do something that happens p percent of the time, use

if (rand.nextInt(100) < p) { ...do something... }

Getting input

You will need to import javax.swing.JOptionPane (or javax.swing.*). (Not needed in this assignment.)

To get a number from the player, add this method to your program:

/**
 * Prints the given message (which should ask the user for some integral
 * quantity), and returns the number entered by the user. If the user's
 * response isn't an integer, the question is repeated until the user
 * does give a integer response.
 * 
 * @param message The request to present to the user.
 * @return The user's numeric response.
 */
 int getNumber(String message) {
    while (true) {
        System.out.print(message);
        try {
            return scanner.nextInt();
        }
        catch (InputMismatchException e) {
            System.out.println("\"" + scanner.next() + "\" isn't a number!");
        }
    }
}

Here is an example of how you can use this method:

sell = getNumber("How many acres shall you sell?");

Structure of the assignment:

The above are requirements. You may have additional classes and methods as needed, and they should be documented and unit tested as appropriate.

Due date:

Thursday, February 5, before midnight. Turn in your zipped assignment via Blackboard -- see Instructions for Using Zip Files and Blackboard for instructions. Include all Javadoc files.

Just turn in one program for the two of you, please; whoever turns it in, please put your partner's name in the Blackboard comments field.