math.randomseed(os.time());
local year = 0; -- current year
local pop = 100; -- current population, each needs 20 bushels/year
local births = 5; -- number of births in current year
local deaths = 0; -- number of deaths in current year
local totalDeaths = 0; -- cumulative deaths in all years
local pcntStarved = 0; -- cumulative percentage starved
local yield = 3; -- current-year harvest in bushels per acre
local rats = 200; -- bushels eaten by rats in current year
local stores = 2800; -- current bushels in stores
local acres = 1000; -- current acres owned by city
local cost = 0; -- current year change in acres
local plant = 0; -- acres planted in current year, each half bushel
local birthsFactor = 0; -- factor of the births
local ratsFactor = 0; -- factor of the rats
local plague = false; -- 15% chance of plague in any year, half die
function print(s, ...) io.write(s:format(...)); end;
function println(...) print(...); io.write('\n'); end;
function leaveIllegalInput()
println('\nHAMURABI: I CANNOT DO WHAT YOU WISH.');
println('GET YOURSELF ANOTHER STEWARD!!!!!');
os.exit(-1);
end;
function leaveByThrowOut()
println('DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY');
println('BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE');
println('ALSO BEEN DECLARED \'NATIONAL FINK\' !!');
os.exit(-1);
end;
function leaveAsStarved()
println('\nYOU STARVED %d PEOPLE IN ONE YEAR!!!', deaths);
leaveByThrowOut();
end;
function leaveAsNero()
println('YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV.');
println('THE PEOPLE (REMAINING) FIND YOU AN UNPLEASANT RULER, AND,');
println('FRANKLY, HATE YOUR GUTS!');
os.exit(-1);
end;
function leaveAsNotTooBad()
println('YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT');
println("REALLY WASN'T TOO BAD AT ALL.");
println('%d PEOPLE WOULD', math.floor(pop * 0.8 * math.random()));
println('DEARLY LIKE TO SEE YOU ASSASSINATED BUT WE ALL HAVE OUR');
println('TRIVIAL PROBLEMS.');
os.exit(-1);
end;
function leaveAsBest()
println('A FANTASTIC PERFORMANCE!!! CHARLEMANGE, DISRAELI, AND');
println('JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!');
os.exit(-1);
end;
function input(banner, ...)
function limits(q, ...)
for i = 1, table.getn(arg), 2 do
if 0 <= q and arg[i] < q then
println(arg[i+1]);
return false;
end;
end;
return true;
end;
local q;
repeat
print(banner);
q = math.floor(tonumber(io.read('*number')));
if q < 0 then
leaveIllegalInput();
end;
until limits(q, ...);
return q;
end;
function messageStoresLimit()
return string.format('HAMURABI: THINK AGAIN. YOU HAVE ONLY\n%d BUSHELS OF GRAIN. NOW THEN,', stores);
end;
function messageAcresLimit()
return string.format('HAMURABI: THINK AGAIN. YOU OWN ONLY %d ACRES. NOW THEN,', acres);
end;
function messagePopLimit()
return string.format('BUT YOU HAVE ONLY %d PEOPLE TO TEND THE FIELDS. NOW THEN,', pop);
end;
-- Welcome
println(' HAMURABI');
println(' CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n');
println('TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA');
println('SUCCESSFULLY FOR A TEN-YEAR TERM OF OFFICE.\n');
repeat
-- Print some statistics
year = year + 1
println('\n\nHAMURABI: I BEG TO REPORT TO YOU,');
println('IN YEAR %d, %d PEOPLE STARVED, %d CAME TO THE CITY.', year, deaths, births);
if plague then
println('A HORRIBLE PLAGUE STRUCK! HALF THE PEOPLE DIED.');
end
println('POPULATION IS NOW %d', pop);
println('THE CITY NOW OWNS %d ACRES.', acres);
println('YOU HARVESTED %d BUSHELS PER ACRE.', yield);
println('RATS ATE %d BUSHELS.', rats);
println('YOU NOW HAVE %d BUSHELS IN stores.', stores);
-- Get a bit randomness
cost = math.floor(math.random(17, 26));
yield = math.floor(math.random(1, 5));
birthsFactor = math.floor(math.random(1, 5));
ratsFactor = math.floor(math.random(1, 5));
plague = (math.random() > 0.85);
-- Buy-sell lands
println('LAND IS TRADING AT %d BUSHELS PER ACRE.', cost);
local dAcres = input('HOW MANY ACRES DO YOU WISH TO BUY? ', stores / cost, messageStoresLimit());
if dAcres == 0 then
dAcres = - input('HOW MANY ACRES DO YOU WISH TO SELL? ', acres - 1, messageAcresLimit());
end;
acres = acres + dAcres;
stores = stores - cost * dAcres;
-- Feed the people
println('');
feed = input('HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE? ', stores, messageStoresLimit());
stores = stores - feed;
-- Plant some seeds
println('');
plant = input('HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED? ',
acres, messageAcresLimit(),
2 * stores, messageStoresLimit(),
10 * pop, messagePopLimit());
stores = stores - math.floor(plant / 2);
rats = math.mod(ratsFactor, 2) * math.floor(stores / ratsFactor);
stores = stores - rats + plant * yield;
births = math.floor(birthsFactor * (20 * acres + stores) / pop / 100 + 1);
deaths = pop - math.floor(feed / 20);
if 0 <= deaths then
if 0.45 * pop < deaths then -- Starve enough for impeachment?
leaveImpeachment();
end;
pcntStarved = ((year - 1) * pcntStarved + deaths * 100 / pop) / year;
totalDeaths = totalDeaths + deaths;
else
deaths = 0;
end;
pop = pop + births - deaths;
if plague then
pop = math.floor(pop / 2);
end;
until year == 10
local perPerson = acres / pop;
println('IN YOUR 10-YEAR TERM OF OFFICE, %d PERCENT OF THE', pcntStarved);
println('POPULATION STARVED PER YEAR ON AVERAGE, I.E., A TOTAL OF');
println('%d PEOPLE DIED!!', totalDeaths);
println('YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH');
println('%d ACRES PER PERSON.\n', perPerson);
if 33 < pcntStarved or perPerson < 7 then
leaveThrowOut();
elseif 10 < pcntStarved or perPerson < 9 then
leaveAsNero();
elseif 3 < pcntStarved or perPerson < 10 then
leaveAsNotTooBad();
else
leaveAsBest();
end;