New topics: Your Pet, IOU, Baby IQ, The Poisons, Birther II, Games, Future Power

Welcome to the Tech Space!

Do you like Books?

Skip to end of metadata
Go to start of metadata

Goal: This lesson will teach how to develop the game Hammurabi. We will write it in ActionScript, which is the language used in Flash files, and is very similar to Javascript. Instead of developing a full Flash program, we want to concentrate on programming techniques. So we will write our program to run from a DOS prompt using the Redtamarin library. Redtamarin is a project that allows ActionScript to be run from the commandline on Windows, Linux of MacOSX, without needing all the rest of Flash Player. A future tutorial will show how to take this code and put it into a simple Flash Application. But for now, to learn the basics of programming, we're going to keep it simple.

Here are some of the best references for getting started in programming with Actionscript:

  • "Essential Actionscript 3.0" by Colin Moock, published by O'Reilly in 2007
    • Page 13 - read about how to make comments in ActionScript
    • Page 44 - Chapter 2- Conditionals and loops - these are important control structures to learn
    • Page 172 - Chapter 10 - Statements and operators - has a really good summary of all the language elements in ActionScript. It is followed by a several page table listing all the operators
    • Page 186 - Chapter 11 - All about Arrays - Arrays are very important programming structures.

Beginning programmers should read all of the above to learn basic programming.

Yes, we could have used Java for this, but I wanted to focus on Actionscript programming, so that we can develop skills that can later be used in programming Flash Player, Flex, or AIR.

Here is BASIC source code for Hammurabi, and discussion of other Basic computer games such as Startrek.

About the retro programming we will be doing

In order to keep things simple, we're going to write "old school" retro programming style with just print statements and input statements. This will be very similar to how programming was done on personal computers in the late 1970's and very early 1980's. At that time, personal computers did not have graphical user interfaces (GUIs), but had character only screens. Often these screens were monochrome, meaning there was only one color and black. Later computers introduced the ability to set colors. Any graphically ability was done with character graphics, where there were "extended" characters for things like drawing borders of boxes, and playing card suit symbols, etc. The screens may have had 40 character width, by 25 lines. The entire screen was memory mapped, with each character on the screen corresponding to a specific location in memory. "Poking" a character at a certain memory location would cause that character to appear on the screen. Overwriting that character with a 32, which is the ANSI code for a space, would cause the character to disappear.

However, poking characters on the screen, and reading the keyboard for keystrokes to react immediately to what the user was doing, was an advanced technique. Some earlier computers only had a teletype typewriter, and a box of paper that was used to print all the responses from the computer. When the computer would need input from the user, the program would print out a prompt, and then wait for the user to type a response, and hit the enter key at the end. Then the program would get the input, and processing would continue. So there were no fancy joysticks, mice, touch screens, accelerometers, or wii input devices. And still, despite the simplicity of it all, people wrote game programs for the computer. So we will follow in their footsteps, and do the same.

About the game of Hammurabi

Hammurabi is one of the earliest resource management games written for computers. The game simulates ten years of being a ruler of a city, where you have to decide how much grain to feed your people, how much grain to use for planting, and how much grain to use for buying land. You are scored on your performance, and if you do terribly, you might get thrown out of office.

This website has an example of the hammurabi game: http://www.hammurabigame.com/hammurabi-game.php

I do not have the source code for what they are running, but we will figure out how to write our own game based on observing how that website works. So we are going to do some "reverse engineering" to design our own program that functions similarly.

Lets get started

First you will need to go to the Redtamarin page and download red tamarin. I have created a directory on my hard drive called c:\projects\tamarin\redtamarin to store things that I write that use this platform. I have placed the downloads for windows, and the additional SWC in an l subdirectory under redtamarin, that is, c:\projects\tamarin\redtamarin\l So the commandlines that I show will assume that you have put the redtamarin files in an l subdirectory under where you are writing your code.

Now open a file called Hammurabi.as Use an ASCII text file to do this, such as notepad, or qedit, or nano, or joe's editor. Microsoft Word will not work for this. You need an ASCII text only editor.

Enter the following code into the file:

// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


Notice:

  • We start with some comments about what the program is, who the authors are, the date, and any requrements
  • We import avmplus.System so that we can use routines under system
  • Then we use the System.writeLine() function to print out a welcome message.
// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", 0 people starved.");


   System.writeLine("");
}
// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushels:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");


   System.writeLine("");
}


Here are the writeLine statements to print out the full servant report at each year:

// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");


   System.writeLine("");
}


Now save the program, compile it, and run it.

Jonathan noticed that a lot of the variables are not changing! That is correct. We haven't written the code yet to change them!

But we can see that each of the yearly reports looks a lot like what the website prints out for each year.

// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;


var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
   input = System.readLine();

   System.writeLine("You entered "+input);

   System.writeLine("");
}


// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;


var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToSell: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;


   System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
   input = System.readLine();
   acresToSell = int(input);



   System.writeLine("You entered "+acresToSell+" acres to sell");


   System.writeLine("");
}


// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;


var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToSell: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;

   System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
   input = System.readLine();
   acresToSell = int(input);


   System.writeLine("How many bushels do you wish to feed your people?");
   input = System.readLine();
   bushelsToFeed = int(input);

   System.writeLine("How many acres do you wish to plant with seed?");
   input = System.readLine();
   acresToPlant = int(input);


   System.writeLine("Yes master. Here is what you told me:");
   System.writeLine("You want to sell "+acresToSell+" acres.");
   System.writeLine("You want to use "+bushelsToFeed + " bushels to feed your people.");
   System.writeLine("You want to plant "+acresToPlant + " acres with seed.");


   System.writeLine("");
}




Here is the output if we run this program:

C:\Projects\tamarin\redtamarin>java -jar l/asc.jar -AS3 -import l/builtin.abc -import l/toplevel.abc hammurabi.as

hammurabi.abc, 1751 bytes written

C:\Projects\tamarin\redtamarin>l\redshell_d hammurabi.abc
Welcome to Hammurabi, the classic game of strategy and resource allocation
Hammurabi: I beg to report to you,
In Year 1, 0 people starved.
0 people came to the city.
The city population is now 100.
The city now owns 1000 acres.
You harvested 3 bushels per acre.
Rats ate 200 bushels.
You now have 2800 bushels in store.
Land is trading at 25 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
0
How many bushels do you wish to feed your people?
2000
How many acres do you wish to plant with seed?
1000
Yes master. Here is what you told me:
You want to sell 0 acres.
You want to use 2000 bushels to feed your people.
You want to plant 1000 acres with seed.

Hammurabi: I beg to report to you,
In Year 2, 0 people starved.
0 people came to the city.
The city population is now 100.
The city now owns 1000 acres.
You harvested 3 bushels per acre.
Rats ate 200 bushels.
You now have 2800 bushels in store.
Land is trading at 25 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)

// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;


var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToBuy: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;

   System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
   input = System.readLine();
   acresToBuy = int(input);

   System.writeLine("How many bushels do you wish to feed your people?");
   input = System.readLine();
   bushelsToFeed = int(input);

   System.writeLine("How many acres do you wish to plant with seed?");
   input = System.readLine();
   acresToPlant = int(input);


   System.writeLine("Yes master. Here is what you told me:");
   System.writeLine("You want to buy "+acresToBuy+" acres.");
   System.writeLine("You want to use "+bushelsToFeed + " bushels to feed your people.");
   System.writeLine("You want to plant "+acresToPlant + " acres with seed.");

   cityAcres = cityAcres + acresToBuy;


   System.writeLine("");
}





// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;


var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToBuy: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;

   System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
   input = System.readLine();
   acresToBuy = int(input);

   System.writeLine("How many bushels do you wish to feed your people?");
   input = System.readLine();
   bushelsToFeed = int(input);

   System.writeLine("How many acres do you wish to plant with seed?");
   input = System.readLine();
   acresToPlant = int(input);


   System.writeLine("Yes master. Here is what you told me:");
   System.writeLine("You want to buy "+acresToBuy+" acres.");
   System.writeLine("You want to use "+bushelsToFeed + " bushels to feed your people.");
   System.writeLine("You want to plant "+acresToPlant + " acres with seed.");

   // Calculate change to city acres, and bushels in storage, according to number of acres to buy or sell
   cityAcres = cityAcres + acresToBuy;
   bushelsInStorage = bushelsInStorage - acresToBuy * priceOfLandPerAcre;

   // Subtract bushels for feeding of the people
   bushelsInStorage = bushelsInStorage - bushelsToFeed;

   // Subtract bushels used for planting
   bushelsInStorage = bushelsInStorage - 1 * acresToPlant;

   System.writeLine("");
}



// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;


var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToBuy: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;

   System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
   input = System.readLine();
   acresToBuy = int(input);

   System.writeLine("How many bushels do you wish to feed your people?");
   input = System.readLine();
   bushelsToFeed = int(input);

   System.writeLine("How many acres do you wish to plant with seed?");
   input = System.readLine();
   acresToPlant = int(input);


   System.writeLine("Yes master. Here is what you told me:");
   System.writeLine("You want to buy "+acresToBuy+" acres.");
   System.writeLine("You want to use "+bushelsToFeed + " bushels to feed your people.");
   System.writeLine("You want to plant "+acresToPlant + " acres with seed.");

   // Calculate change to city acres, and bushels in storage, according to number of acres to buy or sell
   cityAcres = cityAcres + acresToBuy;
   bushelsInStorage = bushelsInStorage - acresToBuy * priceOfLandPerAcre;

   // Subtract bushels for feeding of the people
   bushelsInStorage = bushelsInStorage - bushelsToFeed;

   // Subtract bushels used for planting
   bushelsInStorage = bushelsInStorage - 1 * acresToPlant;


   // Calculate the population change
   starved = 0; //TODO: What if they aren't fed enough? We need to figure this out.
                // People can starve from plague, or from not being fed enough.

   peopleWhoCameToCity = 10;

   cityPopulation = cityPopulation - starved + peopleWhoCameToCity;

   // Calculate the harvest
   harvestBushelsPerAcre = 1  + ( System.getTimer() %  4 );  // Use getTimer() % 4  to provide random number between 0 and 3

   bushelsInStorage = bushelsInStorage + harvestBushelsPerAcre * cityAcres;



   System.writeLine("");
}

// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;


var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToBuy: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;

   System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
   input = System.readLine();
   acresToBuy = int(input);

   System.writeLine("How many bushels do you wish to feed your people?");
   input = System.readLine();
   bushelsToFeed = int(input);

   System.writeLine("How many acres do you wish to plant with seed?");
   input = System.readLine();
   acresToPlant = int(input);


   System.writeLine("Yes master. Here is what you told me:");
   System.writeLine("You want to buy "+acresToBuy+" acres.");
   System.writeLine("You want to use "+bushelsToFeed + " bushels to feed your people.");
   System.writeLine("You want to plant "+acresToPlant + " acres with seed.");

   // Calculate change to city acres, and bushels in storage, according to number of acres to buy or sell
   cityAcres = cityAcres + acresToBuy;
   bushelsInStorage = bushelsInStorage - acresToBuy * priceOfLandPerAcre;

   // Subtract bushels for feeding of the people
   bushelsInStorage = bushelsInStorage - bushelsToFeed;

   // Subtract bushels used for planting
   bushelsInStorage = bushelsInStorage - 1 * acresToPlant;


   // Calculate the population change
   starved = 0; //TODO: What if they aren't fed enough? We need to figure this out.
                // People can starve from plague, or from not being fed enough.

   peopleWhoCameToCity = 10;

   cityPopulation = cityPopulation - starved + peopleWhoCameToCity;

   // Calculate the harvest
   harvestBushelsPerAcre = 1  + ( System.getTimer() %  4 );  // Use getTimer() % 4  to provide random number between 0 and 3

   bushelsInStorage = bushelsInStorage + harvestBushelsPerAcre * cityAcres;

   // Calculate how much the hungry rats ate

   ratsAteBushels = 100 * (System.getTimer() % 6 );

   bushelsInStorage = bushelsInStorage = ratsAteBushels;

   // Calculate new selling price for land
   price OfLandPerAcre = 17 + (System.getTimer() % 10);


   System.writeLine("");
}



C:\Projects\tamarin\redtamarin>java -jar l/asc.jar -AS3 -import l/builtin.abc -import l/toplevel.abc hammurabi.as

[Compiler] Error #1071: Syntax error: expected a definition keyword (such as function) after attribute price, not OfLandPerAcre.
   hammurabi.as, Ln 96, Col 24:
      price OfLandPerAcre = 17 + (System.getTimer() % 10);
   .......................^

[Compiler] Error #1084: Syntax error: expecting rightbrace before semicolon.
   hammurabi.as, Ln 96, Col 55:
      price OfLandPerAcre = 17 + (System.getTimer() % 10);
   ......................................................^

2 errors found

// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;


var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToBuy: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;

   System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
   input = System.readLine();
   acresToBuy = int(input);

   System.writeLine("How many bushels do you wish to feed your people?");
   input = System.readLine();
   bushelsToFeed = int(input);

   System.writeLine("How many acres do you wish to plant with seed?");
   input = System.readLine();
   acresToPlant = int(input);


   System.writeLine("Yes master. Here is what you told me:");
   System.writeLine("You want to buy "+acresToBuy+" acres.");
   System.writeLine("You want to use "+bushelsToFeed + " bushels to feed your people.");
   System.writeLine("You want to plant "+acresToPlant + " acres with seed.");

   // Calculate change to city acres, and bushels in storage, according to number of acres to buy or sell
   cityAcres = cityAcres + acresToBuy;
   bushelsInStorage = bushelsInStorage - acresToBuy * priceOfLandPerAcre;

   // Subtract bushels for feeding of the people
   bushelsInStorage = bushelsInStorage - bushelsToFeed;

   // Subtract bushels used for planting
   bushelsInStorage = bushelsInStorage - 1 * acresToPlant;


   // Calculate the population change
   starved = 0; //TODO: What if they aren't fed enough? We need to figure this out.
                // People can starve from plague, or from not being fed enough.

   peopleWhoCameToCity = 10;

   cityPopulation = cityPopulation - starved + peopleWhoCameToCity;

   // Calculate the harvest
   harvestBushelsPerAcre = 1  + ( System.getTimer() %  4 );  // Use getTimer() % 4  to provide random number between 0 and 3

   bushelsInStorage = bushelsInStorage + harvestBushelsPerAcre * cityAcres;

   // Calculate how much the hungry rats ate

   ratsAteBushels = 100 * (System.getTimer() % 6 );

   bushelsInStorage = bushelsInStorage = ratsAteBushels;

   // Calculate new selling price for land
   priceOfLandPerAcre = 17 + (System.getTimer() % 10);


   System.writeLine("");
}


C:\Projects\tamarin\redtamarin>java -jar l/asc.jar -AS3 -import l/builtin.abc -import l/toplevel.abc hammurabi.as

hammurabi.abc, 2005 bytes written

C:\Projects\tamarin\redtamarin>l\redshell_d hammurabi.abc
Welcome to Hammurabi, the classic game of strategy and resource allocation
Hammurabi: I beg to report to you,
In Year 1, 0 people starved.
0 people came to the city.
The city population is now 100.
The city now owns 1000 acres.
You harvested 3 bushels per acre.
Rats ate 200 bushels.
You now have 2800 bushels in store.
Land is trading at 25 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
0
How many bushels do you wish to feed your people?
2000
How many acres do you wish to plant with seed?
800
Yes master. Here is what you told me:
You want to buy 0 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.

Hammurabi: I beg to report to you,
In Year 2, 0 people starved.
10 people came to the city.
The city population is now 110.
The city now owns 1000 acres.
You harvested 4 bushels per acre.
Rats ate 100 bushels.
You now have 100 bushels in store.
Land is trading at 18 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)

"You now have 100 bushels in store"??????? Shouldn't we have more than that?


   bushelsInStorage = bushelsInStorage = ratsAteBushels;

ooops... should be

   bushelsInStorage = bushelsInStorage - ratsAteBushels;

Now when we run, we see:

Welcome to Hammurabi, the classic game of strategy and resource allocation
Hammurabi: I beg to report to you,
In Year 1, 0 people starved.
0 people came to the city.
The city population is now 100.
The city now owns 1000 acres.
You harvested 3 bushels per acre.
Rats ate 200 bushels.
You now have 2800 bushels in store.
Land is trading at 25 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
10
How many bushels do you wish to feed your people?
2000
How many acres do you wish to plant with seed?
800
Yes master. Here is what you told me:
You want to buy 10 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.

Hammurabi: I beg to report to you,
In Year 2, 0 people starved.
10 people came to the city.
The city population is now 110.
The city now owns 1010 acres.
You harvested 1 bushels per acre.
Rats ate 400 bushels.
You now have 360 bushels in store.
Land is trading at 25 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)

Is the 360 bushels in storage correct? We're not sure. We need to examine the report, and look carefully at our program logic. To make things easier, lets add some extra comments to the code, and lets add some grouping to our code with some blocks:

// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;


var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToBuy: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;

   System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
   input = System.readLine();
   acresToBuy = int(input);

   System.writeLine("How many bushels do you wish to feed your people?");
   input = System.readLine();
   bushelsToFeed = int(input);

   System.writeLine("How many acres do you wish to plant with seed?");
   input = System.readLine();
   acresToPlant = int(input);


   System.writeLine("Yes master. Here is what you told me:");
   System.writeLine("You want to buy "+acresToBuy+" acres.");
   System.writeLine("You want to use "+bushelsToFeed + " bushels to feed your people.");
   System.writeLine("You want to plant "+acresToPlant + " acres with seed.");

   // Calculate change to city acres, and bushels in storage, according to number of acres to buy or sell
   {
     cityAcres = cityAcres + acresToBuy;
     bushelsInStorage = bushelsInStorage - acresToBuy * priceOfLandPerAcre;

     // Subtract bushels for feeding of the people
     bushelsInStorage = bushelsInStorage - bushelsToFeed;

     // Subtract bushels used for planting
     bushelsInStorage = bushelsInStorage - 1 * acresToPlant;
   }

   // Calculate changes in the kingdom during the year
   {
     // Calculate the population change
     starved = 0; //TODO: What if they aren't fed enough? We need to figure this out.
                // People can starve from plague, or from not being fed enough.

     peopleWhoCameToCity = 10;

     cityPopulation = cityPopulation - starved + peopleWhoCameToCity;

     // Calculate the harvest
     harvestBushelsPerAcre = 1  + ( System.getTimer() %  4 );  // Use getTimer() % 4  to provide random number between 0 and 3

     bushelsInStorage = bushelsInStorage + harvestBushelsPerAcre * cityAcres;

     // Calculate how much the hungry rats ate

     ratsAteBushels = 100 * (System.getTimer() % 6 );

     bushelsInStorage = bushelsInStorage - ratsAteBushels;

     // Calculate new selling price for land
     priceOfLandPerAcre = 17 + (System.getTimer() % 10);
   }

   System.writeLine("");
}

Adding this statement between the two blocks helps us to see if the program is doing the right thing:

   System.writeLine("After buying acres, feeding your population, and planting, you have "+ bushelsInStorage + " bushels.");

Or we could make the statement even more informative by including the number of bushels spent buying acres:

// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;

var bushelsSpentBuyingAcres = 0;

var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToBuy: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;

   System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
   input = System.readLine();
   acresToBuy = int(input);

   System.writeLine("How many bushels do you wish to feed your people?");
   input = System.readLine();
   bushelsToFeed = int(input);

   System.writeLine("How many acres do you wish to plant with seed?");
   input = System.readLine();
   acresToPlant = int(input);


   System.writeLine("Yes master. Here is what you told me:");
   System.writeLine("You want to buy "+acresToBuy+" acres.");
   System.writeLine("You want to use "+bushelsToFeed + " bushels to feed your people.");
   System.writeLine("You want to plant "+acresToPlant + " acres with seed.");

   // Calculate change to city acres, and bushels in storage, according to number of acres to buy or sell
   {
     cityAcres = cityAcres + acresToBuy;

     bushelsSpentBuyingAcres = acresToBuy * priceOfLandPerAcre;
     bushelsInStorage = bushelsInStorage - bushelsSpentBuyingAcres;

     // Subtract bushels for feeding of the people
     bushelsInStorage = bushelsInStorage - bushelsToFeed;

     // Subtract bushels used for planting
     bushelsInStorage = bushelsInStorage - 1 * acresToPlant;
   }

   System.writeLine("After spending " + bushelsSpentBuyingAcres +  " bushels buying acres, feeding your population, and planting, you have "+ bushelsInStorage + " bushels.");

   // Calculate changes in the kingdom during the year
   {
     // Calculate the population change
     starved = 0; //TODO: What if they aren't fed enough? We need to figure this out.
                // People can starve from plague, or from not being fed enough.

     peopleWhoCameToCity = 10;

     cityPopulation = cityPopulation - starved + peopleWhoCameToCity;

     // Calculate the harvest
     harvestBushelsPerAcre = 1  + ( System.getTimer() %  4 );  // Use getTimer() % 4  to provide random number between 0 and 3

     bushelsInStorage = bushelsInStorage + harvestBushelsPerAcre * cityAcres;

     // Calculate how much the hungry rats ate

     ratsAteBushels = 100 * (System.getTimer() % 6 );

     bushelsInStorage = bushelsInStorage - ratsAteBushels;

     // Calculate new selling price for land
     priceOfLandPerAcre = 17 + (System.getTimer() % 10);
   }

   System.writeLine("");
}


Welcome to Hammurabi, the classic game of strategy and resource allocation
Hammurabi: I beg to report to you,
In Year 1, 0 people starved.
0 people came to the city.
The city population is now 100.
The city now owns 1000 acres.
You harvested 3 bushels per acre.
Rats ate 200 bushels.
You now have 2800 bushels in store.
Land is trading at 25 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
10
How many bushels do you wish to feed your people?
2000
How many acres do you wish to plant with seed?
800
Yes master. Here is what you told me:
You want to buy 10 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
After spending 250 bushels buying acres, feeding your population, and planting, you have -250 bushels.

Hammurabi: I beg to report to you,
In Year 2, 0 people starved.
10 people came to the city.
The city population is now 110.
The city now owns 1010 acres.
You harvested 2 bushels per acre.
Rats ate 100 bushels.
You now have 1670 bushels in store.
Land is trading at 22 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)

See the -250 bushels? We spent more than we had!

Also the 1670 bushels in store seems wrong....

     bushelsInStorage = bushelsInStorage + harvestBushelsPerAcre * cityAcres;

That assumes we planted every city acre, but that's not true, we only planted 800 acres. So we should change this to:

     bushelsInStorage = bushelsInStorage + harvestBushelsPerAcre * acresToPlant;

now we run and get:

C:\Projects\tamarin\redtamarin>l\redshell_d hammurabi.abc
Welcome to Hammurabi, the classic game of strategy and resource allocation
Hammurabi: I beg to report to you,
In Year 1, 0 people starved.
0 people came to the city.
The city population is now 100.
The city now owns 1000 acres.
You harvested 3 bushels per acre.
Rats ate 200 bushels.
You now have 2800 bushels in store.
Land is trading at 25 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
20
How many bushels do you wish to feed your people?
2000
How many acres do you wish to plant with seed?
800
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
After spending 500 bushels buying acres, feeding your population, and planting, you have -500 bushels.

Hammurabi: I beg to report to you,
In Year 2, 0 people starved.
10 people came to the city.
The city population is now 110.
The city now owns 1020 acres.
You harvested 4 bushels per acre.
Rats ate 300 bushels.
You now have 2400 bushels in store.
Land is trading at 24 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)

Validation

We cant use more bushels than what we have available. Checking that we dont do this, is called validation. We need to validate the inputs of the user.

// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;

var bushelsSpentBuyingAcres = 0;

var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToBuy: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;

   System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
   input = System.readLine();
   acresToBuy = int(input);

   System.writeLine("How many bushels do you wish to feed your people?");
   input = System.readLine();
   bushelsToFeed = int(input);

   System.writeLine("How many acres do you wish to plant with seed?");
   input = System.readLine();
   acresToPlant = int(input);

   // Keep asking for input, until we get legal (or valid) inputs
   var choicesAreLegal = 0;

   while (choicesAreLegal == 0)
   {

     System.writeLine("Yes master. Here is what you told me:");
     System.writeLine("You want to buy "+acresToBuy+" acres.");
     System.writeLine("You want to use "+bushelsToFeed + " bushels to feed your people.");
     System.writeLine("You want to plant "+acresToPlant + " acres with seed.");

     // Create a temporary variable, and calculate if the users choices use less bushels than are available.
     var bushelValidation;

     // Start with how many bushels we have
     bushelValidation = bushelsInStorage;

     // Calculate change to city acres, and bushels in storage, according to number of acres to buy or sell
     {
       cityAcres = cityAcres + acresToBuy;

       bushelsSpentBuyingAcres = acresToBuy * priceOfLandPerAcre;
       bushelValidation = bushelValidation - bushelsSpentBuyingAcres;

       // Subtract bushels for feeding of the people
       bushelValidation = bushelValidation - bushelsToFeed;

       // Subtract bushels used for planting
       bushelValidation = bushelValidation - 1 * acresToPlant;
     }

     // This is our decision if the inputs are valid
     if (bushelValidation >= 0)
     {
       choicesAreLegal = 1;
     }
     else
     {
       System.writeln("I'm sorry master, but those choices would use too many bushels. You would end up with "+bushelValidation+" bushels!");
     }

   }

   bushelsInStorage = bushelValidation;

   System.writeLine("After spending " + bushelsSpentBuyingAcres +  " bushels buying acres, feeding your population, and planting, you have "+ bushelsInStorage + " bushels.");

   // Calculate changes in the kingdom during the year
   {
     // Calculate the population change
     starved = 0; //TODO: What if they aren't fed enough? We need to figure this out.
                // People can starve from plague, or from not being fed enough.

     peopleWhoCameToCity = 10;

     cityPopulation = cityPopulation - starved + peopleWhoCameToCity;

     // Calculate the harvest
     harvestBushelsPerAcre = 1  + ( System.getTimer() %  4 );  // Use getTimer() % 4  to provide random number between 0 and 3

     bushelsInStorage = bushelsInStorage + harvestBushelsPerAcre * acresToPlant;

     // Calculate how much the hungry rats ate

     ratsAteBushels = 100 * (System.getTimer() % 6 );

     bushelsInStorage = bushelsInStorage - ratsAteBushels;

     // Calculate new selling price for land
     priceOfLandPerAcre = 17 + (System.getTimer() % 10);
   }

   System.writeLine("");
}


Gives us a runtime error:

C:\Projects\tamarin\redtamarin>l\redshell_d hammurabi.abc
Welcome to Hammurabi, the classic game of strategy and resource allocation
Hammurabi: I beg to report to you,
In Year 1, 0 people starved.
0 people came to the city.
The city population is now 100.
The city now owns 1000 acres.
You harvested 3 bushels per acre.
Rats ate 200 bushels.
You now have 2800 bushels in store.
Land is trading at 25 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
20
How many bushels do you wish to feed your people?
2000
How many acres do you wish to plant with seed?
800
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.

TypeError: Error #1006: writeln is not a function.
        at global$init()

Fixing that, then running, and we have this repeating on the screen:

Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!

Why is that? What did we forget?

So we fix that, and now our program looks like this:

// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;

var bushelsSpentBuyingAcres = 0;

var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToBuy: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;

   // Keep asking for input, until we get legal (or valid) inputs
   var choicesAreLegal = 0;

   while (choicesAreLegal == 0)
   {

     System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
     input = System.readLine();
     acresToBuy = int(input);

     System.writeLine("How many bushels do you wish to feed your people?");
     input = System.readLine();
     bushelsToFeed = int(input);

     System.writeLine("How many acres do you wish to plant with seed?");
     input = System.readLine();
     acresToPlant = int(input);


     System.writeLine("Yes master. Here is what you told me:");
     System.writeLine("You want to buy "+acresToBuy+" acres.");
     System.writeLine("You want to use "+bushelsToFeed + " bushels to feed your people.");
     System.writeLine("You want to plant "+acresToPlant + " acres with seed.");

     // Create a temporary variable, and calculate if the users choices use less bushels than are available.
     var bushelValidation;

     // Start with how many bushels we have
     bushelValidation = bushelsInStorage;

     // Calculate change to city acres, and bushels in storage, according to number of acres to buy or sell
     {
       cityAcres = cityAcres + acresToBuy;

       bushelsSpentBuyingAcres = acresToBuy * priceOfLandPerAcre;
       bushelValidation = bushelValidation - bushelsSpentBuyingAcres;

       // Subtract bushels for feeding of the people
       bushelValidation = bushelValidation - bushelsToFeed;

       // Subtract bushels used for planting
       bushelValidation = bushelValidation - 1 * acresToPlant;
     }

     // This is our decision if the inputs are valid
     if (bushelValidation >= 0)
     {
       choicesAreLegal = 1;
     }
     else
     {
       System.writeLine("I'm sorry master, but those choices would use too many bushels. You would end up with "+bushelValidation+" bushels!");
     }

   }

   bushelsInStorage = bushelValidation;

   System.writeLine("After spending " + bushelsSpentBuyingAcres +  " bushels buying acres, feeding your population, and planting, you have "+ bushelsInStorage + " bushels.");

   // Calculate changes in the kingdom during the year
   {
     // Calculate the population change
     starved = 0; //TODO: What if they aren't fed enough? We need to figure this out.
                // People can starve from plague, or from not being fed enough.

     peopleWhoCameToCity = 10;

     cityPopulation = cityPopulation - starved + peopleWhoCameToCity;

     // Calculate the harvest
     harvestBushelsPerAcre = 1  + ( System.getTimer() %  4 );  // Use getTimer() % 4  to provide random number between 0 and 3

     bushelsInStorage = bushelsInStorage + harvestBushelsPerAcre * acresToPlant;

     // Calculate how much the hungry rats ate

     ratsAteBushels = 100 * (System.getTimer() % 6 );

     bushelsInStorage = bushelsInStorage - ratsAteBushels;

     // Calculate new selling price for land
     priceOfLandPerAcre = 17 + (System.getTimer() % 10);
   }

   System.writeLine("");
}


C:\Projects\tamarin\redtamarin>l\redshell_d hammurabi.abc
Welcome to Hammurabi, the classic game of strategy and resource allocation
Hammurabi: I beg to report to you,
In Year 1, 0 people starved.
0 people came to the city.
The city population is now 100.
The city now owns 1000 acres.
You harvested 3 bushels per acre.
Rats ate 200 bushels.
You now have 2800 bushels in store.
Land is trading at 25 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
20
How many bushels do you wish to feed your people?
2000
How many acres do you wish to plant with seed?
800
Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
1
How many bushels do you wish to feed your people?
2000
How many acres do you wish to plant with seed?
775
Yes master. Here is what you told me:
You want to buy 1 acres.
You want to use 2000 bushels to feed your people.
You want to plant 775 acres with seed.
After spending 25 bushels buying acres, feeding your population, and planting, you have 0 bushels.

Hammurabi: I beg to report to you,
In Year 2, 0 people starved.
10 people came to the city.
The city population is now 110.
The city now owns 1021 acres.
You harvested 1 bushels per acre.
Rats ate 400 bushels.
You now have 375 bushels in store.
Land is trading at 19 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)

// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;

var bushelsSpentBuyingAcres = 0;

var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToBuy: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;

   // Keep asking for input, until we get legal (or valid) inputs
   var choicesAreLegal = 0;

   while (choicesAreLegal == 0)
   {

     System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
     input = System.readLine();
     acresToBuy = int(input);

     System.writeLine("How many bushels do you wish to feed your people?");
     input = System.readLine();
     bushelsToFeed = int(input);

     System.writeLine("How many acres do you wish to plant with seed?");
     input = System.readLine();
     acresToPlant = int(input);

     System.writeLine("");

     System.writeLine("Yes master. Here is what you told me:");
     System.writeLine("You want to buy "+acresToBuy+" acres.");
     System.writeLine("You want to use "+bushelsToFeed + " bushels to feed your people.");
     System.writeLine("You want to plant "+acresToPlant + " acres with seed.");

     // Create a temporary variable, and calculate if the users choices use less bushels than are available.
     var bushelValidation;

     // Start with how many bushels we have
     bushelValidation = bushelsInStorage;

     // Calculate change to city acres, and bushels in storage, according to number of acres to buy or sell
     {
       bushelsSpentBuyingAcres = acresToBuy * priceOfLandPerAcre;
       bushelValidation = bushelValidation - bushelsSpentBuyingAcres;

       // Subtract bushels for feeding of the people
       bushelValidation = bushelValidation - bushelsToFeed;

       // Subtract bushels used for planting
       bushelValidation = bushelValidation - 1 * acresToPlant;
     }

     // This is our decision if the inputs are valid
     if (bushelValidation >= 0)
     {
       choicesAreLegal = 1;
     }
     else
     {
       System.writeLine("I'm sorry master, but those choices would use too many bushels. You would end up with "+bushelValidation+" bushels!");
     }

     System.writeLine(" ");

   }

   // We have finished our validation, now lets make the user's choices affect our variables

   cityAcres = cityAcres + acresToBuy;
   bushelsInStorage = bushelValidation;


   System.writeLine("After spending " + bushelsSpentBuyingAcres +  " bushels buying acres, feeding your population, and planting, you have "+ bushelsInStorage + " bushels.");

   // Calculate changes in the kingdom during the year
   {
     // Calculate the population change
     starved = 0; //TODO: What if they aren't fed enough? We need to figure this out.
                // People can starve from plague, or from not being fed enough.

     peopleWhoCameToCity = 10;

     cityPopulation = cityPopulation - starved + peopleWhoCameToCity;

     // Calculate the harvest
     harvestBushelsPerAcre = 1  + ( System.getTimer() %  4 );  // Use getTimer() % 4  to provide random number between 0 and 3

     bushelsInStorage = bushelsInStorage + harvestBushelsPerAcre * acresToPlant;

     // Calculate how much the hungry rats ate

     ratsAteBushels = 100 * (System.getTimer() % 6 );

     bushelsInStorage = bushelsInStorage - ratsAteBushels;

     // Calculate new selling price for land
     priceOfLandPerAcre = 17 + (System.getTimer() % 10);
   }

   System.writeLine("");
}

So now we play the game:

C:\Projects\tamarin\redtamarin>java -jar l/asc.jar -AS3 -import l/builtin.abc -import l/toplevel.abc hammurabi.as

hammurabi.abc, 2427 bytes written

C:\Projects\tamarin\redtamarin>l\redshell_d hammurabi.abc
Welcome to Hammurabi, the classic game of strategy and resource allocation
Hammurabi: I beg to report to you,
In Year 1, 0 people starved.
0 people came to the city.
The city population is now 100.
The city now owns 1000 acres.
You harvested 3 bushels per acre.
Rats ate 200 bushels.
You now have 2800 bushels in store.
Land is trading at 25 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
1
How many bushels do you wish to feed your people?
2000
How many acres do you wish to plant with seed?
800

Yes master. Here is what you told me:
You want to buy 1 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -25 bushels!

How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
20
How many bushels do you wish to feed your people?
2000
How many acres do you wish to plant with seed?
800

Yes master. Here is what you told me:
You want to buy 20 acres.
You want to use 2000 bushels to feed your people.
You want to plant 800 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -500 bushels!

How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
1
How many bushels do you wish to feed your people?
2000
How many acres do you wish to plant with seed?
775

Yes master. Here is what you told me:
You want to buy 1 acres.
You want to use 2000 bushels to feed your people.
You want to plant 775 acres with seed.

After spending 25 bushels buying acres, feeding your population, and planting, you have 0 bushels.

Hammurabi: I beg to report to you,
In Year 2, 0 people starved.
10 people came to the city.
The city population is now 110.
The city now owns 1001 acres.
You harvested 2 bushels per acre.
Rats ate 300 bushels.
You now have 1250 bushels in store.
Land is trading at 20 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
2200
How many bushels do you wish to feed your people?
1000
How many acres do you wish to plant with seed?
1000

Yes master. Here is what you told me:
You want to buy 2200 acres.
You want to use 1000 bushels to feed your people.
You want to plant 1000 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -44750 bushels!

How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
0
How many bushels do you wish to feed your people?
2200
How many acres do you wish to plant with seed?
1000

Yes master. Here is what you told me:
You want to buy 0 acres.
You want to use 2200 bushels to feed your people.
You want to plant 1000 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -1950 bushels!

How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
-50
How many bushels do you wish to feed your people?
2200
How many acres do you wish to plant with seed?
1000

Yes master. Here is what you told me:
You want to buy -50 acres.
You want to use 2200 bushels to feed your people.
You want to plant 1000 acres with seed.
I'm sorry master, but those choices would use too many bushels. You would end up with -950 bushels!

How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
-100
How many bushels do you wish to feed your people?
2200
How many acres do you wish to plant with seed?
1000

Yes master. Here is what you told me:
You want to buy -100 acres.
You want to use 2200 bushels to feed your people.
You want to plant 1000 acres with seed.

After spending -2000 bushels buying acres, feeding your population, and planting, you have 50 bushels.

Hammurabi: I beg to report to you,
In Year 3, 0 people starved.
10 people came to the city.
The city population is now 120.
The city now owns 901 acres.
You harvested 4 bushels per acre.
Rats ate 300 bushels.
You now have 3750 bushels in store.
Land is trading at 24 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)

So now we can't get credit for buying acres that didn't validate. But what error can you find above?

That's right, we were able to plant more acres than we have after selling acres. We need more validation.

We could do this:

     // This is our decision if the inputs are valid
     if ( (bushelValidation >= 0) &&
          (acresToPlant <= (cityAcres + acresToBuy))
        )

     {
       choicesAreLegal = 1;
     }
     else
     {
       System.writeLine("I'm sorry master, but those choices would use too many bushels. You would end up with "+bushelValidation+" bushels!");
     }

But if the user got their bushels right, but planted too many acres, the error message would be about bushels and not the acres. So we need to make two separate conditionals, one for each different thing we are validating, so that we have an else clause for each that we can use for giving an appropriate error for that validation.

So here it is as two separate conditionals:

     // This is our decision if the inputs are valid
     if (bushelValidation >= 0)
     {
       choicesAreLegal = 1;
     }
     else
     {
       System.writeLine("I'm sorry master, but those choices would use too many bushels. You would end up with "+bushelValidation+" bushels!");
       choicesAreLegal = 0;
     }

     // This is our decision if the inputs are valid
     if (acresToPlant <= (cityAcres + acresToBuy))
     {
       choicesAreLegal = 1;
     }
     else
     {
       System.writeLine("I'm sorry master, but you dont have "+ acresToPlant + " acres, that is more acres than you own! ");
       choicesAreLegal = 0;
     }

So what would happen if the user enters numbers that cause the bushels to validate, but the acres to plant doesn't validate? What happens to choicesAreLegal if the first condition validates, but the second condition goes into the else clause because it doesn't validate? What would be the final value of choicesAreLegal?

Jonathan says "The first one runs the choicesAreLegal=1 setting the variable, and the first else clause does not run. But on the second, the else clause runs, but there is no statement to set choicesAreLegal back to zero!" So what happens to our loop? We would get out of our loop! Jonathan says "We should go back into the loop, because we got one thing wrong!" Exactly! So what do we do about it? What do we have to do to make sure we stay in the loop. "choicesAreLegal must be set to 0, with choicesAreLegal=0, and we have to put this in the else, we can put it after the System.writeLine". Very good Jonathan, that is correct.

For sake of consistency, we will put this choicesAreLegal in both of the else clauses, eventhough it isn't really needed in the first one, because choicesAreLegal is zero before anything sets it to 1.

Jonathan pointed out, "I was just thinking about this, and why don't we validate all the things that the user entered?" Excellent suggestion Jonathan! Lets think about all the ways a user could enter the wrong inputs into our program.

What about the number of acres the user is buying or selling? Jonathan says "The user could be buying when they want to sell." Well, that is true, but we can't do much about that. But, lets say the user was buying, how could the user get that number wrong? Jonathan says "By putting too many acres to buy." OK, great, what condition will help us detect that?

So at first we think of writing,

if (acresToBuy > cityAcres)

But what! The user my have enough bushels to buy more acres than he has! We took care of this issue when we validated the number of bushels left.

What we really want to look at is that the user doesnt sell more acres than he has. Selling is a negative number for acresToBuy. So we end up with this conditional:

     if (-acresToBuy > cityAcres)
     {
       System.writeLine("I'm sorry master, but that is more acres than you have!");
       choicesAreLegal = 0;
     }

We really dont need to set choicesAreLegal to 1 if this is valid, because a previous conditional validation should have done that. Which causes us to look at all our validation conditionals:

     // This is our decision if the inputs are valid
     if (bushelValidation >= 0)
     {
       choicesAreLegal = 1;
     }
     else
     {
       System.writeLine("I'm sorry master, but those choices would use too many bushels. You would end up with "+bushelValidation+" bushels!");
       choicesAreLegal = 0;
     }

     // This is our decision if the inputs are valid
     if (acresToPlant <= (cityAcres + acresToBuy))
     {
       choicesAreLegal = 1;
     }
     else
     {
       System.writeLine("I'm sorry master, but you dont have "+ acresToPlant + " acres, that is more acres than you own! ");
       choicesAreLegal = 0;
     }

     if (-acresToBuy > cityAcres)
     {
       System.writeLine("I'm sorry master, but that is more acres than you have!");
       choicesAreLegal = 0;
     }

Hmm... What happens if bushelValidation fails, but then acresToPlant validation is ok? The second validation would override the first! This is not what we want. So lets fix that, but I only looking for the acresToPlant validation to fail.

     // This is our decision if the inputs are valid
     if (bushelValidation >= 0)
     {
       choicesAreLegal = 1;
     }
     else
     {
       System.writeLine("I'm sorry master, but those choices would use too many bushels. You would end up with "+bushelValidation+" bushels!");
       choicesAreLegal = 0;
     }

     // This is our decision if the inputs are valid
     if (acresToPlant > (cityAcres + acresToBuy))
     {
       System.writeLine("I'm sorry master, but you dont have "+ acresToPlant + " acres, that is more acres than you own! ");
       choicesAreLegal = 0;
     }

     if (-acresToBuy > cityAcres)
     {
       System.writeLine("I'm sorry master, but that is more acres than you have!");
       choicesAreLegal = 0;
     }

OK so what are some other validations we can do? Here are two more we came up with:

     // validate bushels to feed the people is a positive number (outside the loop, we'll figure out how many people starved!
     if (bushelsToFeed >= 0)
     {
       System.writeLine("I'm sorry master, but you can't feed the people less than nothing!");
       choicesAreLegal = 0;
     }

     if (acresToPlant < 0)
     {
       System.writeLine("I'm sorry master, but you can't plant less than nothing!");
       choicsAreLegal = 0;
     }

Here is our whole program so far:

// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;

var bushelsSpentBuyingAcres = 0;

var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToBuy: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;

   // Keep asking for input, until we get legal (or valid) inputs
   var choicesAreLegal = 0;

   while (choicesAreLegal == 0)
   {

     System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
     input = System.readLine();
     acresToBuy = int(input);

     System.writeLine("How many bushels do you wish to feed your people?");
     input = System.readLine();
     bushelsToFeed = int(input);

     System.writeLine("How many acres do you wish to plant with seed?");
     input = System.readLine();
     acresToPlant = int(input);

     System.writeLine("");

     System.writeLine("Yes master. Here is what you told me:");
     System.writeLine("You want to buy "+acresToBuy+" acres.");
     System.writeLine("You want to use "+bushelsToFeed + " bushels to feed your people.");
     System.writeLine("You want to plant "+acresToPlant + " acres with seed.");

     // Create a temporary variable, and calculate if the users choices use less bushels than are available.
     var bushelValidation;

     // Start with how many bushels we have
     bushelValidation = bushelsInStorage;

     // Calculate change to city acres, and bushels in storage, according to number of acres to buy or sell
     {
       bushelsSpentBuyingAcres = acresToBuy * priceOfLandPerAcre;
       bushelValidation = bushelValidation - bushelsSpentBuyingAcres;

       // Subtract bushels for feeding of the people
       bushelValidation = bushelValidation - bushelsToFeed;

       // Subtract bushels used for planting
       bushelValidation = bushelValidation - 1 * acresToPlant;
     }

     // This is our decision if the inputs are valid
     if (bushelValidation >= 0)
     {
       choicesAreLegal = 1;
     }
     else
     {
       System.writeLine("I'm sorry master, but those choices would use too many bushels. You would end up with "+bushelValidation+" bushels!");
       choicesAreLegal = 0;
     }

     // This is our decision if the inputs are valid
     if (acresToPlant > (cityAcres + acresToBuy))
     {
       System.writeLine("I'm sorry master, but you dont have "+ acresToPlant + " acres, that is more acres than you own! ");
       choicesAreLegal = 0;
     }

     if (-acresToBuy > cityAcres)
     {
       System.writeLine("I'm sorry master, but that is more acres than you have!");
       choicesAreLegal = 0;
     }

     // validate bushels to feed the people is a positive number (outside the loop, we'll figure out how many people starved!
     if (bushelsToFeed >= 0)
     {
       System.writeLine("I'm sorry master, but you can't feed the people less than nothing!");
       choicesAreLegal = 0;
     }

     if (acresToPlant < 0)
     {
       System.writeLine("I'm sorry master, but you can't plant less than nothing!");
       choicsAreLegal = 0;
     }

     System.writeLine(" ");

   }

   // We have finished our validation, now lets make the user's choices affect our variables

   cityAcres = cityAcres + acresToBuy;
   bushelsInStorage = bushelValidation;


   System.writeLine("After spending " + bushelsSpentBuyingAcres +  " bushels buying acres, feeding your population, and planting, you have "+ bushelsInStorage + " bushels.");

   // Calculate changes in the kingdom during the year
   {
     // Calculate the population change
     starved = 0; //TODO: What if they aren't fed enough? We need to figure this out.
                // People can starve from plague, or from not being fed enough.

     peopleWhoCameToCity = 10;

     cityPopulation = cityPopulation - starved + peopleWhoCameToCity;

     // Calculate the harvest
     harvestBushelsPerAcre = 1  + ( System.getTimer() %  4 );  // Use getTimer() % 4  to provide random number between 0 and 3

     bushelsInStorage = bushelsInStorage + harvestBushelsPerAcre * acresToPlant;

     // Calculate how much the hungry rats ate

     ratsAteBushels = 100 * (System.getTimer() % 6 );

     bushelsInStorage = bushelsInStorage - ratsAteBushels;

     // Calculate new selling price for land
     priceOfLandPerAcre = 17 + (System.getTimer() % 10);
   }

   System.writeLine("");
}

Now lets figure out the starvation issue!

How can people starve?

  • The rule might not feed them enough!
  • Or, there might be a plague!

We made a note earlier that we need to deal with this issue of starvation, see

     // Calculate the population change
     starved = 0; //TODO: What if they aren't fed enough? We need to figure this out.
                // People can starve from plague, or from not being fed enough.

Starvation due to plagues seems to be random, although we weren't sure if not feeding the people made a plague more likely. Seems reasonable if the people are being starved, they might be more likely to get sick. So we'll write some code to figure this out.

So how do we figure out how much food the people need?

Jonathan says, "Take 20 times the amount of people, and compare that with the amount of food the user wanted to feed with."

So we wanted to make plagues more likely if the people are starving, and less likely, but still possible, even if the people are being well fed. So we came up with this new variable, plagueIsHappening, and this conditional to set it:

     var plagueIsHappening:int = 0;

     var foodNeeded:int = cityPopulation * 20;
     if (foodNeeded > bushelsToFeed)
     {  // This is a problem, not enough food!
        if  ((System.getTimer() % 3) == 0)
            { plagueIsHappening = 1;
            }
     }
     else
     {  // Food sufficient for the population
        if  ((System.getTimer() % 6) == 0)
            { plagueIsHappening = 1;
            }
     }

We still have to figure out starvation and the plague. We'll reduce the population if there is a plague, and then see if we have enough food to feed whoever remains.

     if (plagueIsHappening == 1)
     { cityPopulation = cityPopulation / 2;

       // Recalculate the food needs based on who is left
       foodNeeded = cityPopulation * 20;
     }

     if (foodNeeded > bushelsToFeed)
     {
        peopleWhoCanBeFed = (bushelsToFeed / 20);
        starved = cityPopulation - peopleWhoCanBeFed;
        cityPopulation = peopleWhoCanBeFed;
     }

Now, what if our ruler is very cruel, and doesn't feed too large of a percentage of his people? How would the people respond? Jonathan says, "The would die off." Yeah, and what else, what about your chance to keep ruling? Jonathan says "They would boot you out of the place. So much for security!"

     if (starved > cityPopulation * 1 / 10)
     {  System.writeLine("Bad news Hammurabi! More than 10% of your population has starved, and the remaining people have revolted against your rule! You are no longer in office!");
        
        // No more years. Break out of the loop
        break;  
     }

With a devious look in his eye, Jonathan starts his rule, seeing what happens if he starves his populace:

C:\Projects\tamarin\redtamarin>l\redshell_d hammurabi.abc
Welcome to Hammurabi, the classic game of strategy and resource allocation
Hammurabi: I beg to report to you,
In Year 1, 0 people starved.
0 people came to the city.
The city population is now 100.
The city now owns 1000 acres.
You harvested 3 bushels per acre.
Rats ate 200 bushels.
You now have 2800 bushels in store.
Land is trading at 25 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
0
How many bushels do you wish to feed your people?
100
How many acres do you wish to plant with seed?
2000

Yes master. Here is what you told me:
You want to buy 0 acres.
You want to use 100 bushels to feed your people.
You want to plant 2000 acres with seed.
I'm sorry master, but you dont have 2000 acres, that is more acres than you own!
I'm sorry master, but you can't feed the people less than nothing!

How many acres do you wish to buy or sell? (Enter a negative number to sell acres)

Jonathan says, "WHAT! I fed them more than nothing!"

OK, lets look at our logic....

We found this:

     // validate bushels to feed the people is a positive number (outside the loop, we'll figure out how many people starved!
     if (bushelsToFeed >= 0)
     {
       System.writeLine("I'm sorry master, but you can't feed the people less than nothing!");
       choicesAreLegal = 0;
     }

What we really wanted was bushelsToFeed less than or equal to 0! Ooops!

C:\Projects\tamarin\redtamarin>l\redshell_d hammurabi.abc
Welcome to Hammurabi, the classic game of strategy and resource allocation
Hammurabi: I beg to report to you,
In Year 1, 0 people starved.
0 people came to the city.
The city population is now 100.
The city now owns 1000 acres.
You harvested 3 bushels per acre.
Rats ate 200 bushels.
You now have 2800 bushels in store.
Land is trading at 25 bushels per acre.
Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.
How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
0
How many bushels do you wish to feed your people?
100
How many acres do you wish to plant with seed?
2000

Yes master. Here is what you told me:
You want to buy 0 acres.
You want to use 100 bushels to feed your people.
You want to plant 2000 acres with seed.
I'm sorry master, but you dont have 2000 acres, that is more acres than you own!

How many acres do you wish to buy or sell? (Enter a negative number to sell acres)
100
How many bushels do you wish to feed your people?
200
How many acres do you wish to plant with seed?
10

Yes master. Here is what you told me:
You want to buy 100 acres.
You want to use 200 bushels to feed your people.
You want to plant 10 acres with seed.

After spending 2500 bushels buying acres, feeding your population, and planting, you have 90 bushels.
Bad news Hammurabi! More than 10% of your population has starved, and the remaining people have revolted against your rule! You are no longer in office!

We came up with a couple more validations.

// Program: hammurabi.as
// Authors: Garnet R. Chaney, Jonathan Chaney
// Date: 2011/07/17

// Requirements:
//    Runs with redtamarin

import avmplus.System;

System.writeLine("Welcome to Hammurabi, the classic game of strategy and resource allocation");


var year:int;

var starved:int = 0;
var peopleWhoCameToCity:int = 0;
var cityPopulation:int      = 100;
var cityAcres:int           = 1000;
var harvestBushelsPerAcre:int      = 3;
var ratsAteBushels:int      = 200;
var bushelsInStorage:int    = 2800;
var priceOfLandPerAcre:int  = 25;

var bushelsSpentBuyingAcres = 0;

var input:String;


// Main program loop, play for 10 years
for (year = 1; year <= 10 ; year=year +1)
{
   System.writeLine("Hammurabi: I beg to report to you,");
   System.writeLine("In Year " + year + ", " + starved + " people starved.");
   System.writeLine(peopleWhoCameToCity + " people came to the city.");
   System.writeLine("The city population is now " + cityPopulation + ".");
   System.writeLine("The city now owns " + cityAcres +" acres.");
   System.writeLine("You harvested " + harvestBushelsPerAcre + " bushels per acre.");
   System.writeLine("Rats ate " + ratsAteBushels + " bushels.");
   System.writeLine("You now have " + bushelsInStorage + " bushels in store.");
   System.writeLine("Land is trading at " + priceOfLandPerAcre + " bushels per acre.");

   System.writeLine("Please decide how many acres do you wish to buy or sell, how many bushels do you want to feed your people, how many acres do you wish to plant with seed.");

   var acresToBuy: int = 0;
   var bushelsToFeed : int = 0;
   var acresToPlant : int = 0;

   // Keep asking for input, until we get legal (or valid) inputs
   var choicesAreLegal = 0;

   while (choicesAreLegal == 0)
   {

     System.writeLine("How many acres do you wish to buy or sell? (Enter a negative number to sell acres)");
     input = System.readLine();
     acresToBuy = int(input);

     System.writeLine("How many bushels do you wish to feed your people?");
     input = System.readLine();
     bushelsToFeed = int(input);

     System.writeLine("How many acres do you wish to plant with seed?");
     input = System.readLine();
     acresToPlant = int(input);

     System.writeLine("");

     System.writeLine("Yes master. Here is what you told me:");
     System.writeLine("You want to buy "+acresToBuy+" acres.");
     System.writeLine("You want to use "+bushelsToFeed + " bushels to feed your people.");
     System.writeLine("You want to plant "+acresToPlant + " acres with seed.");

     // Create a temporary variable, and calculate if the users choices use less bushels than are available.
     var bushelValidation;

     // Start with how many bushels we have
     bushelValidation = bushelsInStorage;

     // Calculate change to city acres, and bushels in storage, according to number of acres to buy or sell
     {
       bushelsSpentBuyingAcres = acresToBuy * priceOfLandPerAcre;
       bushelValidation = bushelValidation - bushelsSpentBuyingAcres;

       // Subtract bushels for feeding of the people
       bushelValidation = bushelValidation - bushelsToFeed;

       // Subtract bushels used for planting
       bushelValidation = bushelValidation - 1 * acresToPlant;
     }

     // This is our decision if the inputs are valid
     if (bushelValidation >= 0)
     {
       choicesAreLegal = 1;
     }
     else
     {
       System.writeLine("I'm sorry master, but those choices would use too many bushels. You would end up with "+bushelValidation+" bushels!");
       choicesAreLegal = 0;
     }

     // This is our decision if the inputs are valid
     if (acresToPlant > (cityAcres + acresToBuy))
     {
       System.writeLine("I'm sorry master, but you dont have "+ acresToPlant + " acres, that is more acres than you own! ");
       choicesAreLegal = 0;
     }
     if (acresToPlant > 10*cityPopulation)
     {
       System.writeLine("I'm sorry master, but you dont have enough people to plan "+ acresToPlant + " acres! ");
       choicesAreLegal = 0;
     }


     if (-acresToBuy > cityAcres)
     {
       System.writeLine("I'm sorry master, but that is more acres than you have!");
       choicesAreLegal = 0;
     }

     // validate bushels to feed the people is a positive number (outside the loop, we'll figure out how many people starved!
     if (bushelsToFeed < 0)
     {
       System.writeLine("I'm sorry master, but you can't feed the people less than nothing!");
       choicesAreLegal = 0;
     }

     if (acresToPlant < 0)
     {
       System.writeLine("I'm sorry master, but you can't plant less than nothing!");
       choicsAreLegal = 0;
     }

     System.writeLine(" ");

   }

   // We have finished our validation, now lets make the user's choices affect our variables

   cityAcres = cityAcres + acresToBuy;
   bushelsInStorage = bushelValidation;


   System.writeLine("After spending " + bushelsSpentBuyingAcres +  " bushels buying acres, feeding your population, and planting, you have "+ bushelsInStorage + " bushels.");

   // Calculate changes in the kingdom during the year
   {
     // Calculate the population change
     starved = 0; //TODO: What if they aren't fed enough? We need to figure this out.
                // People can starve from plague, or from not being fed enough.

     var plagueIsHappening:int = 0;

     var foodNeeded:int = cityPopulation * 20;
     if (foodNeeded > bushelsToFeed)
     {  // This is a problem, not enough food!
        if  ((System.getTimer() % 3) == 0)
            { plagueIsHappening = 1;
            }
     }
     else
     {  // Food sufficient for the population
        if  ((System.getTimer() % 6) == 0)
            { plagueIsHappening = 1;
            }
     }

     if (plagueIsHappening == 1)
     { cityPopulation = cityPopulation / 2;

       // Recalculate the food needs based on who is left
       foodNeeded = cityPopulation * 20;
     }

     var peopleWhoCanBeFed:int = (bushelsToFeed / 20);
     if (foodNeeded > bushelsToFeed)
     {
        starved = cityPopulation - peopleWhoCanBeFed;
     }

     if (starved > cityPopulation * 1 / 10)
     {  System.writeLine("Bad news Hammurabi! You only fed "+peopleWhoCanBeFed+" people! More than 10% of your population has starved, and the remaining people have revolted against your rule! You are no longer in office!");

        // No more years. Break out of the loop
        break;
     }


     peopleWhoCameToCity = 10;

     cityPopulation = cityPopulation - starved + peopleWhoCameToCity;

     // Calculate the harvest
     harvestBushelsPerAcre = 1  + ( System.getTimer() %  4 );  // Use getTimer() % 4  to provide random number between 0 and 3

     bushelsInStorage = bushelsInStorage + harvestBushelsPerAcre * acresToPlant;

     // Calculate how much the hungry rats ate

     ratsAteBushels = 100 * (System.getTimer() % 6 );

     bushelsInStorage = bushelsInStorage - ratsAteBushels;

     // Calculate new selling price for land
     priceOfLandPerAcre = 17 + (System.getTimer() % 10);
   }

   System.writeLine("");
}

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.