diff --git a/hammurabi b/hammurabi new file mode 100755 index 0000000..e86576c Binary files /dev/null and b/hammurabi differ diff --git a/hammurabi.c b/hammurabi.c index ffbe622..53a7989 100644 --- a/hammurabi.c +++ b/hammurabi.c @@ -4,43 +4,6 @@ * Copyright 2020 David Meyer +JMJ * */ -/* -Hammurabi To-Dos - -6/21 - -v Complete splash message: version, author, one-liner -- Write man page (for TWENEX release?) -- Complete/format help text: add introduction, credit to Ahl, separate intro and help -- Add help choice to annual plan menu -v Divider line is off-center -- Reformat menu to stand out -- plan summary should include grain and land balances -v BUG: buying land resulted in REDUCTION of land held -- Refactor and document main loop - -/}_ _ -\/\/ -|\ -|\ -|_\_ - - ____________________ -( @ -| | -| | -| | -|___________________| -(___________________@ - -.______________________________________________________________________________. -| _ _ _ _ _ _ _ _ _ _ | -| /} \/}/ /} \/}/ /} \/}/ /} \/}/ /} \/}/ /} | -|_/|\_ |_ _/|\_ |_ _/|\_ |_ _/|\_ |_ _/|\_ |_ _/|\_| -| / \ | \ / \ | \ / \ | \ / \ | \ / \ | \ / \ | -|vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv| - - -*/ #include #include #include @@ -56,15 +19,54 @@ typedef enum {FALSE, TRUE} Boolean; typedef enum {BUY, SELL, FEED, PLANT, RESET, EXEC, CALC, QUIT} Plancmd; /* Message texts */ -char MSGDIV[] = -" ----------------- <<<<>>>> --------------------\n"; +char MSGDANCE[] = +"|vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv|\n\ +|(}_ _ _ _ _ _ _ _ _ _ _ _ _ _{)|\n\ +|\\/\\/ \\(}/ (} \\(}/ (} \\()/ {) \\{)/ {) \\{)/ \\/\\/|\n\ +||\\ |_ _/|\\_ |_ _/|\\_ \\/ _/|\\_ _| _/|\\_ _| /||\n\ +||_\\_ | \\ / \\ | \\ / \\ /\\ / \\ / | / \\ / | _/_||\n\ +|vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv|\n\ +"; char MSGHELP[] = -"Help text here\n\ -Land price varies between 17 and 26 bushels of grain per acre.\n\ -Planting two acres requires one bushel of grain.\n\ -One person can farm ten acres of land.\n\ -One person needs to eat 20 bushels of grain per year to stay healthy.\n\ +"\n\ +You are the ruler of an ancient Sumerian city-state. I, your Grand\n\ +Vizier, will assist you during your ten-year reign to govern your _ _{)\n\ +realm. \\/\\/\n\ + /|\n\ +At the beginning of each year, you will plan the employment of your /|\n\ +city's resources to buy or sell land, allocate land and grain to plant _/_|\n\ +new crops, and allocate grain to feed your people. Some guidelines:\n\ +\n\ + * Land price varies between 17 and 26 bushels of grain per acre.\n\ + * Planting crops requires one bushel of grain to seed two acres.\n\ + * One person can farm ten acres of land.\n\ + * One person needs to eat 20 bushels of grain per year to stay alive.\n\ +\n\ +On the planning menu, press one of the bracketed characters to [F]eed\n\ +your people, [P]lant crops, or [B]uy or [S]ell land. When you are\n\ +satisfied with the plan, press [E] to execute it. You may also\n\ +[R]eset the current plan and start over, or [Q]uit the game.\n\ +\n\ +When prompted for a numeric value (to buy, sell, or plant land, or\n\ +allocate grain for food), you may enter an integer value, or an\n\ +arithmetic expression composed of integers and the operators \"+\", \"-\",\n\ +\"*\", or \"/\" for addition, subtraction, multiplication, and division.\n\ +The expression will be evaluated with integer arithmetic in the order\n\ +the operators appear from left to right, and the value of the\n\ +expression will be used for your input.\n\ +\n\ +After the year's plan has been executed, I will report to you the\n\ +year's events, harvest, births and immigration, and deaths from\n\ +starvation and plague, and the results.\n\ +\n\ +At the end of your reign, history will judge you based on the average\n\ +portion of the population you starved, and your city's growth in land\n\ +per person. If in any year you starve more than 45 percent of the\n\ +population, the survivors will rise up and depose you immediately.\n\ +\n\ +Hammurabi is based on the game HAMURABI by David Ahl.\n\ +\n\ "; char MSGMENU[]= @@ -72,6 +74,7 @@ char MSGMENU[]= [F]eed your people with grain | [E]xecute your current plan\n\ [P]lant crops on your land | [R]eset your current plan and start over\n\ [B]uy more land | [Q]uit the game\n\ + [S]ell land for grain\n\ "; char MSGPLTOT[] = @@ -132,8 +135,7 @@ Boolean planyear(void); int popnet(void); void printdeposed(void); void printgreeting(void); -void printEvtLandPr(void); -void printstatus(void); +void printinitrept(void); void printyearrept(void); int salegrain(void); Boolean scanyes(char *prompt); @@ -175,11 +177,11 @@ main(void) print(MSGSPLASH); if(scanyes("Would you like instructions?") == TRUE) print(MSGHELP); + print(MSGDANCE); - printgreeting(); - printstatus(); EvtLandPr = evtlandpr(); - printEvtLandPr(); + printgreeting(); + printinitrept(); do { @@ -216,18 +218,17 @@ main(void) printgreeting(); printyearrept(); - printstatus(); if(Year == MAXYEARS) completedterm(); else { EvtLandPr = evtlandpr(); - printEvtLandPr(); } } } } while(Year < MAXYEARS && gameover == FALSE); - print(MSGDIV); + print("\n"); + print(MSGDANCE); exits(0); } @@ -238,16 +239,16 @@ completedterm(void) int landperperson = Land / Pop; int likeassassination = Pop * 0.8 * frand(); printgreeting(); - print("In your %d-year reign, %d people died of starvation, an average of %d people per year.\n", MAXYEARS, TotStarved, avgstarvepct); + print("In your %d-year reign, %d people died of starvation, an average of %d people\nper year.\n", MAXYEARS, TotStarved, avgstarvepct); print("You started with %d acres per person and ended with %d acres per person.\n", INITLAND / INITPOP, landperperson); if(avgstarvepct > 33 || landperperson < 7) printdeposed(); - else if(avgstarvepct > 10 || landperperson < 9) print("Your heavy-handed performance smacks of Nero and Ivan IV. Your (surviving) people find you an unpleasant ruler, and, frankly, hate your guts!\n"); + else if(avgstarvepct > 10 || landperperson < 9) print("Your heavy-handed performance smacks of Nero and Ivan IV. Your (surviving)\npeople find you an unpleasant ruler, and, frankly, hate your guts!\n"); else if(avgstarvepct > 3 || landperperson < 10) { print("Your performance could have been better, but wasn't too bad. "); - if(likeassassination > 0) print("%d %s would like to see you assassinated, but we all have our trivial problems.\n", likeassassination, (likeassassination == 1 ? "person" : "people")); + if(likeassassination > 0) print("%d %s would like to see you assassinated, but we all have our trivial\nproblems.\n", likeassassination, (likeassassination == 1 ? "person" : "people")); } - else print("A fantastic performance! Charlemagne, Disraeli, and Jefferson combined could not have done better!\n"); + else print("A fantastic performance! Charlemagne, Disraeli, and Jefferson combined could not\nhave done better!\n"); } int @@ -606,7 +607,6 @@ printdeposed(void) void printgreeting(void) { -// print(MSGDIV); print("\nO %s One, I beg to report,\n", HONORIFIC[nrand(MAXHONOR + 1)]); } @@ -617,34 +617,41 @@ printEvtLandPr(void) } void -printstatus(void) +printinitrept(void) { - print("The population is %d.\n", Pop); - print("You own %d acres.\n", Land); - print("You have %d bushels of grain.\n", Grain); + print(" ______________________________________________________________________\n"); + print(" ( Your Reign Begins @\n"); + print(" (}_ _ | Land %6d acres |\n", Land); + print(" \\/\\/ | Grain %6d bushels |\n", Grain); + print(" |\\ | Population %6d |\n", Pop); + print(" |\\ | |\n"); + print(" |_\\_ | Land price %6d bushels per acre |\n", EvtLandPr); + print(" |_____________________________________________________________________|\n"); + print(" (______________________________________________________________________@\n"); } void printyearrept(void) { + if(EvtPlague > 0) print("A horrible plague struck! Half the people died!\n"); print(" ______________________________________________________________________\n"); print(" ( YEAR %2d @\n", Year); print(" | Harvest yield %1d bushels per acre | Population last year %6d |\n", EvtYield, PrevPop); - print(" (}_ _ | Grain reserve %6d | Births and immigrants %6d |\n", PrevGrain, EvtBrthImm); + print(" (}_ _ | Grain reserve %6d | Births and immigrants %6d |\n", GrainAfterPlan, EvtBrthImm); print(" \\/\\/ | Harvest %6d | ", GrainHarvest); if(EvtStarve > 0) print("Starvation deaths %6d |\n", EvtStarve); else print(" |\n"); print(" |\\ | "); if(EvtRatsEat > 0) print("Eaten by rats %6d | ", EvtRatsEat); else print(" | "); - if(EvtPlague > 0) print("Plague deaths %6d |\n", EvtPlague); + if(EvtPlague > 0) print("%-20s%6d |\n", "Plague deaths", EvtPlague); else print(" |\n"); print(" |\\ | -------------------------------- | -------------------------------- |\n"); print(" |_\\_ | Balance %6d | Current population %6d |\n", Grain, Pop); print(" | |\n"); - print(" | Land %6d Land price %2d |\n", Land, EvtLandPr); + print(" | Land %6d |\n", Land); print(" |_____________________________________________________________________|\n"); - print(" (_____________________________________________________________________@\n"); + print(" (______________________________________________________________________@\n"); } int