Created
March 9, 2013 01:07
-
-
Save inmatarian/5121902 to your computer and use it in GitHub Desktop.
Hamurabi.bas.lua: Port of an old and classic computer game. Feed your people 20 bushels of grain a year each or you'll be a national fink.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- HAMURABI DOT BAS DOT LUA | |
-- Port of HAMURABI.BAS | |
-- See the wikipedia article for more information. | |
-- Use parameter -c or --color to play with ansi colors | |
random, floor, write = math.random, math.floor, io.write | |
---------------------------------------- | |
do | |
USECOLOR = false | |
for i = 1, select('#', ...) do | |
local arg = select(i, ...) | |
if arg == "-c" or arg == "--color" then | |
USECOLOR = true | |
end | |
end | |
end | |
---------------------------------------- | |
function writeln(...) | |
write(...) | |
write("\n") | |
end | |
function readnum(prompt) | |
local line | |
repeat | |
write(prompt, "? ") | |
line = io.read() | |
if not line then os.exit() end | |
line = tonumber(line) | |
until type(line)=="number" | |
return floor(line) | |
end | |
function readline(prompt) | |
write(prompt, "? ") | |
local line = io.read() | |
if not line then os.exit() end | |
return line | |
end | |
function clean(number) | |
return string.format("%.2f", tonumber(number)) | |
end | |
---------------------------------------- | |
function stringmerge(...) | |
local s = '' | |
for i = 1, select('#', ...) do | |
s = s .. tostring((select(i, ...))) | |
end | |
return s | |
end | |
function makecolor(id) | |
if not USECOLOR then | |
return stringmerge | |
else | |
local escape = string.char(27) .. '[' .. tostring(id) .. 'm' | |
local reset = string.char(27) .. '[0m' | |
return function(...) | |
return escape .. stringmerge(...) .. reset | |
end | |
end | |
end | |
black = makecolor(30) | |
red = makecolor(31) | |
green = makecolor(32) | |
yellow = makecolor(33) | |
blue = makecolor(34) | |
magenta = makecolor(35) | |
cyan = makecolor(36) | |
white = makecolor(37) | |
---------------------------------------- | |
function create_city() | |
local city = { | |
total_dead = 0, | |
starvation_average = 0, | |
year = 0, | |
population = 95, | |
bushels = 2800, | |
harvest = 3000, | |
yield = 3, | |
acres = 1000, | |
pests = 200, | |
bushels_fed = 0, | |
crops_planted = 0, | |
invitations = 5, | |
deaths = 0, | |
plague_happened = false, | |
} | |
return city | |
end | |
function barge_out(input) | |
if input < 0 then | |
writeln(red("HAMURABI: I CANNOT DO WHAT YOU WISH.\n", | |
"GET YOURSELF ANOTHER STEWARD!!!!!")) | |
return true | |
end | |
end | |
function enough_bushels(city, n) | |
if n <= city.bushels then | |
return true | |
else | |
writeln("HAMURABI: THINK AGAIN. YOU HAVE ONLY ", | |
city.bushels, " BUSHELS OF GRAIN. NOW THEN,") | |
return false | |
end | |
end | |
function enough_acres(city, n) | |
if n <= city.acres then | |
return true | |
else | |
writeln("HAMURABI: THINK AGAIN. YOU OWN ONLY ", | |
city.acres," ACRES. NOW THEN,") | |
return false | |
end | |
end | |
function enough_people(city, n) | |
if n <= city.population then | |
return true | |
else | |
writeln("BUT YOU HAVE ONLY ", | |
city.population," PEOPLE TO TEND THE FIELDS! NOW THEN,") | |
return false | |
end | |
end | |
function trade_bushels(city) | |
local price = 17 + floor(random(0, 10)) | |
writeln("LAND IS TRADING AT ", price, " BUSHELS PER ACRE.") | |
-- Attempt to buy acres | |
local input | |
repeat | |
input = readnum("HOW MANY ACRES DO YOU WISH TO BUY") | |
if barge_out(input) then return end | |
until enough_bushels(city, price * input) | |
if input > 0 then | |
city.acres = city.acres + input | |
city.bushels = city.bushels - (price * input) | |
return true | |
end | |
-- No buys so sell acres | |
repeat | |
input = readnum("HOW MANY ACRES DO YOU WISH TO SELL") | |
if barge_out(input) then return end | |
until enough_acres(city, input) | |
city.acres = city.acres - input | |
city.bushels = city.bushels + (price * input) | |
return true | |
end | |
function feed_people(city) | |
local input | |
repeat | |
input = readnum("HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE") | |
if barge_out(input) then return end | |
until enough_bushels(city, input) | |
city.bushels = city.bushels - input | |
city.bushels_fed = input | |
return true | |
end | |
function plant_crops(city) | |
local input | |
repeat | |
input = readnum("HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED") | |
if barge_out(input) then return end | |
until enough_acres(city, input) and | |
enough_bushels(city, floor(input/2)) and | |
enough_people(city, floor(input/10)) | |
city.bushels = city.bushels - floor(input/2) | |
city.crops_planted = input | |
return true | |
end | |
function declare_fink() | |
writeln(red("DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY\n", | |
"BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE\n", | |
"ALSO BEEN DECLARED NATIONAL FINK!!!!\n")) | |
end | |
function do_year(city) | |
writeln(yellow("\nHAMURABI: I BEG TO REPORT TO YOU")) | |
writeln("IN YEAR ", city.year, ", ", | |
red(city.deaths, " PEOPLE STARVED, "), | |
green(city.invitations, " CAME TO THE CITY.")) | |
city.population = city.population + city.invitations | |
if city.plague_happened then | |
writeln(red("A HORRIBLE PLAGUE STRUCK! HALF THE PEOPLE DIED.")) | |
city.population = floor(city.population / 2) | |
city.plague_happened = false | |
end | |
writeln("POPULATION IS NOW ", city.population) | |
writeln("THE CITY NOW OWNS ", city.acres, " ACRES.") | |
writeln("YOU HARVESTED ", city.yield, " BUSHELS PER ACRE.") | |
writeln(red("THE RATS ATE ", city.pests, " BUSHELS.")) | |
writeln("YOU NOW HAVE ", city.bushels, " BUSHELS IN STORE.") | |
if city.year < 11 then | |
local good | |
good = trade_bushels(city) | |
if not good then return end | |
good = feed_people(city) | |
if not good then return end | |
good = plant_crops(city) | |
if not good then return end | |
-- Bountiful Harvest | |
city.yield = random(1, 5) | |
city.harvest = city.yield * city.crops_planted | |
-- Rats | |
local pestilence = math.random(0, 5) | |
if pestilence == 2 or pestilence == 4 then | |
city.pests = floor(city.bushels / pestilence) | |
else | |
city.pests = 0 | |
end | |
-- Total bushels | |
city.bushels = city.bushels - city.pests + city.harvest | |
-- How babbies are formed | |
local babies = math.random(0, 5) | |
city.invitations = floor(babies*(20*city.acres+city.bushels) / city.population/100 +1) | |
-- Plague | |
city.plague_happened = (random(0, 99)<15) | |
-- Full Tummies | |
local well_fed = floor(city.bushels_fed/20) | |
-- Impeachments | |
if city.population > well_fed then | |
city.deaths = city.population - well_fed | |
if city.deaths > (0.45 * city.population) then | |
writeln(red("YOU STARVED ", city.deaths, " PEOPLE IN ONE YEAR!!!")) | |
declare_fink() | |
return | |
end | |
city.starvation_average = (city.year-1)*city.starvation_average + | |
city.deaths*100/city.population/city.year | |
city.population = well_fed | |
city.total_dead = city.total_dead + city.deaths | |
else | |
city.deaths = 0 | |
end | |
return true | |
else | |
writeln("IN YOUR 10-YEAR TERM OF OFFICE, ", | |
clean(city.starvation_average), " PERCENT OF THE\n", | |
"POPULATION STARVED PER YEAR ON THE AVERAGE, I.E. A TOTAL OF\n", | |
city.total_dead, " PEOPLE DIED!!") | |
local score = city.acres / city.population | |
writeln("YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH ", | |
clean(score), "ACRES PER PERSON.\n") | |
if (city.starvation_average > 33) or (score < 7) then | |
declare_fink() | |
elseif (city.starvation_average > 10) or (score < 9) then | |
writeln(red("YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV.\n", | |
"THE PEOPLE (REMIANING) FIND YOU AN UNPLEASANT RULER, AND,\n", | |
"FRANKLY, HATE YOUR GUTS!!\n")) | |
elseif (city.starvation_average > 3) or (score < 10) then | |
writeln(green("YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT\n", | |
"REALLY WASN'T TOO BAD AT ALL. ", | |
floor(city.population*0.8*random()), " PEOPLE\n", | |
"WOULD DEARLY LIKE TO SEE YOU ASSASSINATED BUT WE ALL HAVE OUR\n", | |
"TRIVIAL PROBLEMS.\n")) | |
else | |
writeln(cyan("A FANTASTIC PERFORMANCE!!! CHARLEMANGE, DISRAELI, AND\n", | |
"JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!\n")) | |
end | |
end | |
end | |
---------------------------------------- | |
function play_game() | |
local city = create_city() | |
-- Main Loop | |
local good | |
repeat | |
city.year = city.year + 1 | |
good = do_year(city) | |
until not good | |
end | |
---------------------------------------- | |
do | |
math.randomseed(os.time()) | |
writeln(cyan("HAMURABI\n\n"), | |
"TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA\n", | |
"FOR A TEN-YEAR TERM OF OFFICE.") | |
local input | |
repeat | |
play_game() | |
writeln("") | |
input = readline("PLAY AGAIN") | |
until input==nil or not (input:match("^%s*[Yy]")) | |
writeln("\nSO LONG FOR NOW.") | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There is an error in the starvation average calculation which can be remedied with an additional set of parentheses.