Public release!

This commit is contained in:
David Meyer 2020-07-15 20:07:44 +09:00
parent b5c64002cd
commit 3c4f4501ab
2 changed files with 72 additions and 65 deletions

BIN
hammurabi Executable file

Binary file not shown.

View File

@ -4,43 +4,6 @@
* Copyright 2020 David Meyer <papa@sdf.org> +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 <u.h>
#include <libc.h>
#include <stdio.h>
@ -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