Hamurabi

Problem #225

Tags: scheme challenge artificial-intelligence games c-1 c-0 special

This task has a Challenge attached.
You may View Stats or read a Help on Challenges.

No translations... yet

Note: this problem should be solved in TinyScheme-R7 - try simpler Scheme Problems if you feel unacquainted.

Once upon a time there was an ancient computer game Hamurabi - a kind of simple economy simulation. Now we want to write a simple artificial intelligence in a form of function in Scheme language - which can play this game, i.e., rule this simulated Kingdom of Babylon.

We need to learn calculations behind the game screen to create adequate algorithme, even simple. So the description goes below - and above the javascript version allows us to get acquainted with the game.

Game flow and rules

  1. As a king, you have three assets: people (initially 100), land (initially 1000 acres) and grain (initially 2800 bushels).
  2. Each year you decide to buy or sell land (for grain), to share some grain for your people's food, and to sow some grain for get plentiful harvest.
  3. Firstly you are told current land prices (in range 17 ... 26 bushels per acre) and are asked how many land to buy (negative value means selling land). Land and grain amounts are updated immediately after your decision.
  4. Next you tell how many of remaining grain to spend to feeding people. One human needs 20 bushels per year.
  5. Then you tell how many acres of land should be plantd with seed. One acre needs half a bushel of grain and also no more land could be used than you have, or your people can work (1 person can tend 10 acres).
  6. After this the year starts. Grain is given to people and sown into soil immediately.
  7. At this point, some of your remaining grain could be eaten by rats.
  8. When year ends, those of your people who was not fed enough, dies immediately (or rather leaves to other kingdom). If you starve over 45% of population in a single year, you are impeached and game ends immediately.
  9. At the same time, harvest is taken - it is equals to amount of acres used multiplied by random integer in range 1 ... 5.
  10. Also some random number of people may come to your city (maximum depends vaguely on your assets).
  11. At this point plague may struck, killing half of your people (with probability about 12.5%).
  12. Now everything repeats, and so continues for 10 years.

Scoring

Whether you are impeached or successfully run for all 10 years, the scoring after the end is the same: points are given for amount of "well-provided" people - that's to say, for each person for whom you have yet 25 bushels of grain and 6.67 acres of land; result is multiplied by 5.

score = 5 * min(pop, grain/25, area*3/20)

the idea behind this formula is that area with average harvest factor of 3 will yield pop*20 bushels to feed the people further. And even if harvest should fail, there is comparable extra stock of grain for one year - to feed and sow

Other details

There are really 10 kingdoms and your solution is run for each of them (technically they differ by "random" number sequences driving rats, harvests, newcomers and plagues). Of course if you retry execution, these 10 kingdoms are the same (so you should get the same results with the same solution).

Of all 10 results only 5 best are taken - their average is your overall score for attempt.

Precise formulas for rats and newcomers are considered unimportant, so if needed, you may find them in the original code of the game, in the book "101 BASIC Games".

Input / Output

Your code should contain function (advisor pop area grain price xdata) - it is called at the beginning of each year and tells you about current situation. You should return list of three values '(buy feed sow) with amounts of land to buy (acres), grain to feed people (bushels) and land to plant the seed (acres).

Example of the function could be like this (feel free to try submitting it - it's not that bad):

(define (advisor pop area grain price xdata)
    (list 0 (* pop 20) area))

Of course if such function is called with pop=100 and grain=1500 the checker will find you can't spend 2000 bushels to feed the people and will automatically reduce this to 1500. Then it will find there are no grain to sow and will continue assuming we sow nothing. So it's ok if values are beyond limits - they'll be adjusted. However returning some garbage most probably will cause error.

Your submission is accepted if the score is above 300.

The xdata attribute may be easily ignored - it holds the secondary values from the past year: '(died came harvest eaten plague) - e.g. how many people have died, how many came, harvest multiplier, how many bushels were eaten by rats, and whether plague happened (boolean). They are provided in case someone needs them for very whimsical intelligence logic.

Please mind overall execution limit of 3 millions steps. Your function will be called about 10*10=100 times and checker driver code takes below 50000 steps. Thus you may spend average of 29500 steps on every call. (further details)

You need to login to get test data and submit solution.