# A Hammurabi game (ver 0.0.1)
# written by Zhishen (Jason) Wen, MCIT, Penn CIS, Sept. 2012
import random, string
def hammurabi():
# hammurabi main function
# initialize variables
starved = 0
immigrants = 5
population = 100
harvest = 3000 # bushels
bushels_per_acre = 3 # amount harvested
rats_ate = 200 # bushels
bushels_in_storage = 2800
acres_owned = 1000
cost_per_acre = 19 # bushels per acre
plague_deaths = 0
print_introductory_message()
# begin a ten year loop and print the outcome of each year
for year in range(1, 11):
print "O great Hammurabi!"
print "You are in year", year, "of your ten year rule."
print "In the previous year", starved, "people starved to death."
print "In the previous year", immigrants, "people entered the kingdom."
print "The population is now", str(population) + "."
print "We harvested", harvest, "bushels at", bushels_per_acre, "bushels per" \
" acre."
print "Rats destroyed", rats_ate, "bushels, leaving", bushels_in_storage, "" \
"bushels in storage."
print "The city owns", acres_owned, "acres of land."
print "Land is currently worth", cost_per_acre, "bushels per acre."
print "There were", plague_deaths, "deaths from the plague."
print
# ask a series of questions
acres_bought = ask_to_buy_land(bushels_in_storage, cost_per_acre)
if acres_bought:
acres_owned += acres_bought
bushels_in_storage -= acres_bought * cost_per_acre
else:
# do not ask user to sell land if s/he is buying land
acres_sold = ask_to_sell_land(acres_owned, cost_per_acre)
acres_owned -= acres_sold
bushels_in_storage += acres_sold * cost_per_acre
bushels_fed = ask_to_feed_people(bushels_in_storage, population)
bushels_in_storage -= bushels_fed
acres_planted = ask_to_plant_land(population, bushels_in_storage)
bushels_in_storage -= acres_planted * 2
# determine the consequences
plague_deaths = do_plague(population)
population -= plague_deaths
starved = get_starved_num(population, bushels_fed)
do_dismissal_for_starv(starved, population, year)
population -= starved
immigrants = get_immigrts_num(acres_owned, bushels_in_storage,
population, starved)
population += immigrants
bushels_per_acre = get_unit_havst()
harvest = get_havst_bushels(acres_planted, bushels_per_acre)
rats_ate = do_rat_infestation(harvest)
bushels_in_storage += harvest - rats_ate
cost_per_acre = get_land_price()
print
# print out a final summary
summarize_result(acres_owned, bushels_in_storage, population, starved)
# the end of hammurabi main function
# definitions of other functions
def print_introductory_message():
print """Congratulations, you are the newest ruler of ancient Samaria, elected
for a ten year term of office. Your duties are to dispense food, direct
farming, and buy and sell land as needed to support your people. Watch
out for rat infestations and the plague! Grain is the general currency,
measured in bushels. The following will help you in your decisions:
* Each person needs at least 20 bushels of grain per year to survive.
* Each person can farm at most 10 acres of land.
* It takes 2 bushels of grain to farm an acre of land.
* The market price for land fluctuates yearly.
Rule wisely and you will be showered with appreciation at the end of
your term. Rule poorly and you will be kicked out of office!"""
def ask_to_buy_land(bushels, cost):
# ask user how many acres of land to buy
acres = get_int("How many acres of land will you buy? (0 to DECLINE)\n")
while acres * cost > bushels:
print "O great Hammurabi, we have but", bushels, "bushels of grain!"
print acres, "acres are too many to afford to buy!"
acres = get_int("Again, how much land will you buy? (0 to DECLINE)\n"
"[HINT: The maximum of current purchasing power is " + str(
bushels / cost) + " acres.]\n")
return acres
def ask_to_sell_land(curr_acres, cost):
# ask user how many acres of land to sell
acres = get_int("How many acres of land will you sell?\n")
while acres > curr_acres:
print "O great Hammurabi, we have but", curr_acres, "acres of land!"
print acres, "acres exceed our land limit!"
acres = get_int("Again, how much land will you sell?\n[HINT: Current land "
"price is " + str(cost) + ".]\n")
return acres
def ask_to_feed_people(curr_bushels, num_of_people):
# ask user how many bushels of grain to feed to the people
bushels = get_int("How many bushels of grain will you feed to the people?\n")
while bushels > curr_bushels:
print "O great Hammurabi, we have but", curr_bushels, "bushels" \
" of grain!", bushels, "bushels exceed our grain reserves!"
bushels = get_int("Again, how much grain will you feed to the people?\n[H"
"INT: In order for everyone to survive, current populat"
"ion needs at least total amount of " +
str(num_of_people * 20) +" bushels.]\n")
return bushels
def ask_to_plant_land(num_of_people, bushels):
# ask user how many acres of land to plant with seed
acres = get_int("How many acres of land will you plant with seed?\n")
while True:
if acres > num_of_people * 10:
print "O great Hammurabi, we have but", num_of_people, "people that can " \
"farm the land!"
print acres, "acres are too many for us! We still need more people to do" \
" the job!"
acres = get_int("Please factor our manpower. Again, how much land will y"
"ou plant?\n[HINT: The maximum possible acres of current"
" total labor force that can afford to farm is " +
str(num_of_people * 10) + " acres.]\n")
continue
if bushels < acres * 2:
print "O great Hammurabi, we have but", bushels, "bushels to spend farmi" \
"ng the land!"
print acres, "acres are too many for us! We lack enough bushels to start" \
" our farming!"
acres = get_int("Please factor our funds. Again, how much land will you "
"plant with seed?\n[HINT: The maximum possible acres of "
"current total funds to spend farming is " +
str(bushels / 2) + " acres.]\n")
continue
break
return acres
def do_plague(num_of_people):
# simulate whether or not a plague happened and return a consequence
if random.randint(0, 99) < 15:
print "***O great Hammurabi, unluckily a horrible PLAGUE" \
" happened!", num_of_people / 2, "people died***"
return num_of_people / 2
else:
print "***Thank God! No plague this year***"
return 0
def get_starved_num(num_of_people, grain_fed):
# get the number of people starved this year
num_of_the_starved = num_of_people - grain_fed / 20
if num_of_the_starved > 0:
print "***O great Hammurabi, unfortunately this year we " \
"have", num_of_the_starved, "PEOPLE STARVED***"
return num_of_the_starved
else:
print "***O brilliant Hammurabi! This year we have NO people starved***"
return 0
def do_dismissal_for_starv(num_of_the_starved, num_of_people, yr):
# judge whether or not the user should be dismissed according
# to the numbers of people starved
if num_of_the_starved > 0.45 * num_of_people:
print "***O great Hammurabi, we really regret to inform you that this " \
"year", num_of_the_starved, "people have been starved, which represent " \
"more than 45% of total population in your Samaria kingdom. According t" \
"o our laws, you're now unfortunately given an immediate dismissal requ" \
"est***"
game_ends(yr)
def get_immigrts_num(acres, bushels, num_of_people, num_of_the_starved):
# get the number of immigrants to our country this year
if num_of_the_starved:
print "***O great Hammurabi, due to starvation, NO IMMIGRANTS this year" \
" come to our kingdom***"
return 0
else:
num_of_immigrts = (20 * acres + bushels) / (100 * num_of_people) + 1
print "***O great Hammurabi, this year", num_of_immigrts, "immigrants c" \
"ome to our kingdom***"
return num_of_immigrts
def get_havst_bushels(acres, unit_havst):
# get bushels of grain harvested this year
bushels_havst = acres * unit_havst
print "***O great Hammurabi, this year we harvest", bushels_havst, "bushels" \
" of grain***"
return bushels_havst
def get_unit_havst():
# get bushels per acre yielded
return random.randint(1, 8)
def do_rat_infestation(havst):
# simulate whether or not a rat infestation happened and return a consequence
if random.randint(0, 99) < 40:
bushels_destroyed = random.randint(10, 30) * havst / 100
print "***O great Hammurabi, unluckily a horrible RAT INFESTATION happe" \
"ned!", bushels_destroyed, "bushels of grain were destroyed***"
return bushels_destroyed
else:
print "***Thank God! No rat infestation occurred this year***"
return 0
def get_land_price():
# get the price of land next year
land_price = random.randint(17, 23)
print "***O great Hammurabi, the price of land will be", land_price, "bushe" \
"ls per acre next year***"
return land_price
def summarize_result(acres, bushels, num_of_people, num_of_the_starved):
# print a summary regarding your play evaluated by acres of land,
# bushels of grain, total population, and number of the starved
print "===================== C O N G R A T U L A T I O N S !======================"
print " Hammurabi your highness, you've successfully gone through your ten"
print " year term of office."
print " In the end of your term of reign, the Samaria Kingdom:"
print
print " * owns", acres, "acres of wealthy land;"
print " * owns", bushels, "bushels of grain in storage;"
print " * has a total population of", str(num_of_people) + ";"
print " * has", num_of_the_starved, "people starved."
print
print eval_acres(acres)
print eval_bushels(bushels)
print eval_population(num_of_people)
print eval_starved(num_of_the_starved)
print "=================== G A M E ===== A C C O M P L I S H E D ================="
print
print " *** THANK YOU FOR PLAYING HAMMURABI! ***"
def eval_acres(acres):
# evaluate acres of land you own
if acres > 1550:
strg = "O great Hammurabi, you've done very well in keeping the realm of our k" \
"ingdom increasing. Fantastic!"
elif acres > 1000:
strg = "O great Hammurabi, you've well maintained our land size as it was ten " \
"years ago, though our domain expanded little!"
elif acres > 500:
strg = "O great Hammurabi, you've lost some of our land! That's a pity. You co" \
"uld have done better!"
else:
strg = "O great Hammurabi, our fruitful land has been shrinked dramatically un" \
"der your rule. That's really not good!"
return strg
def eval_bushels(bushels):
# evaluate bushels of grain you own
if bushels > 18000:
strg = "Nice job! You have earned a lot to feed and finance our homeland. That" \
"'s really cool!"
elif bushels > 10000:
strg = "Steady increase of bushels. Our country is wealthy!"
elif bushels > 2800:
strg = "Fine policies, but haven't earned much. We need more bushels to thrive!"
else:
strg = "Oops, you haven't handled your financial task well. So much grain lost!"
return strg
def eval_population(num_of_people):
# evaluate total number of people you have
if num_of_people > 200:
strg = "There are more than twice people now living in Samaria as ten years ago."
elif num_of_people > 130:
strg = "During your term of office, population here increases pretty steadily."
elif num_of_people > 95:
strg = "During the ten years, total number of people in Samaria changed little."
else:
strg = "In the end of your reign, total population decreased."
return strg
def eval_starved(num_of_the_starved):
# evaluate number of people starved
if num_of_the_starved > 70:
strg = "In the end of your term more than 70 citizens starved to death. That's" \
" an extremely serious problem!"
elif num_of_the_starved > 30:
strg = "In the end of your term at least 30 people died from starvation. Every" \
" citizen's basic living requirements should be met!"
elif num_of_the_starved > 0:
strg = "In the end of your term, still some people starved to die. This could " \
"have been avoided by a reasonable farming policy."
else:
strg = "That's great because now no one starved in our country!"
return strg
def game_ends(yr):
print "========================== G A M E ===== O V E R =========================="
print " O great Hammurabi, we're truly regretful that in year", yr, "of"
print " your ten year rule, you lost your imperial authority."
print
print " *** THANK YOU FOR PLAYING HAMMURABI! ***"
quit()
def get_int(message):
# print the message as prompt, and ask the user to enter an unsigned integer
answer = None
while answer == None:
try:
answer = int(input(message))
except:
print "[Please re-enter a valid number. Signed int will be transformed t" \
"o unsigned automatically.]"
return abs(answer)