Public release!
This commit is contained in:
parent
b5c64002cd
commit
3c4f4501ab
137
hammurabi.c
137
hammurabi.c
|
@ -3,43 +3,6 @@
|
||||||
*
|
*
|
||||||
* Copyright 2020 David Meyer <papa@sdf.org> +JMJ
|
* 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 <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
|
@ -56,15 +19,54 @@ typedef enum {FALSE, TRUE} Boolean;
|
||||||
typedef enum {BUY, SELL, FEED, PLANT, RESET, EXEC, CALC, QUIT} Plancmd;
|
typedef enum {BUY, SELL, FEED, PLANT, RESET, EXEC, CALC, QUIT} Plancmd;
|
||||||
|
|
||||||
/* Message texts */
|
/* Message texts */
|
||||||
char MSGDIV[] =
|
char MSGDANCE[] =
|
||||||
" ----------------- <<<<>>>> --------------------\n";
|
"|vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv|\n\
|
||||||
|
|(}_ _ _ _ _ _ _ _ _ _ _ _ _ _{)|\n\
|
||||||
|
|\\/\\/ \\(}/ (} \\(}/ (} \\()/ {) \\{)/ {) \\{)/ \\/\\/|\n\
|
||||||
|
||\\ |_ _/|\\_ |_ _/|\\_ \\/ _/|\\_ _| _/|\\_ _| /||\n\
|
||||||
|
||_\\_ | \\ / \\ | \\ / \\ /\\ / \\ / | / \\ / | _/_||\n\
|
||||||
|
|vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv|\n\
|
||||||
|
";
|
||||||
|
|
||||||
char MSGHELP[] =
|
char MSGHELP[] =
|
||||||
"Help text here\n\
|
"\n\
|
||||||
Land price varies between 17 and 26 bushels of grain per acre.\n\
|
You are the ruler of an ancient Sumerian city-state. I, your Grand\n\
|
||||||
Planting two acres requires one bushel of grain.\n\
|
Vizier, will assist you during your ten-year reign to govern your _ _{)\n\
|
||||||
One person can farm ten acres of land.\n\
|
realm. \\/\\/\n\
|
||||||
One person needs to eat 20 bushels of grain per year to stay healthy.\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[]=
|
char MSGMENU[]=
|
||||||
|
@ -72,6 +74,7 @@ char MSGMENU[]=
|
||||||
[F]eed your people with grain | [E]xecute your current plan\n\
|
[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\
|
[P]lant crops on your land | [R]eset your current plan and start over\n\
|
||||||
[B]uy more land | [Q]uit the game\n\
|
[B]uy more land | [Q]uit the game\n\
|
||||||
|
[S]ell land for grain\n\
|
||||||
";
|
";
|
||||||
|
|
||||||
char MSGPLTOT[] =
|
char MSGPLTOT[] =
|
||||||
|
@ -132,8 +135,7 @@ Boolean planyear(void);
|
||||||
int popnet(void);
|
int popnet(void);
|
||||||
void printdeposed(void);
|
void printdeposed(void);
|
||||||
void printgreeting(void);
|
void printgreeting(void);
|
||||||
void printEvtLandPr(void);
|
void printinitrept(void);
|
||||||
void printstatus(void);
|
|
||||||
void printyearrept(void);
|
void printyearrept(void);
|
||||||
int salegrain(void);
|
int salegrain(void);
|
||||||
Boolean scanyes(char *prompt);
|
Boolean scanyes(char *prompt);
|
||||||
|
@ -175,11 +177,11 @@ main(void)
|
||||||
|
|
||||||
print(MSGSPLASH);
|
print(MSGSPLASH);
|
||||||
if(scanyes("Would you like instructions?") == TRUE) print(MSGHELP);
|
if(scanyes("Would you like instructions?") == TRUE) print(MSGHELP);
|
||||||
|
print(MSGDANCE);
|
||||||
|
|
||||||
printgreeting();
|
|
||||||
printstatus();
|
|
||||||
EvtLandPr = evtlandpr();
|
EvtLandPr = evtlandpr();
|
||||||
printEvtLandPr();
|
printgreeting();
|
||||||
|
printinitrept();
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -216,18 +218,17 @@ main(void)
|
||||||
|
|
||||||
printgreeting();
|
printgreeting();
|
||||||
printyearrept();
|
printyearrept();
|
||||||
printstatus();
|
|
||||||
|
|
||||||
if(Year == MAXYEARS) completedterm();
|
if(Year == MAXYEARS) completedterm();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EvtLandPr = evtlandpr();
|
EvtLandPr = evtlandpr();
|
||||||
printEvtLandPr();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(Year < MAXYEARS && gameover == FALSE);
|
} while(Year < MAXYEARS && gameover == FALSE);
|
||||||
print(MSGDIV);
|
print("\n");
|
||||||
|
print(MSGDANCE);
|
||||||
exits(0);
|
exits(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,16 +239,16 @@ completedterm(void)
|
||||||
int landperperson = Land / Pop;
|
int landperperson = Land / Pop;
|
||||||
int likeassassination = Pop * 0.8 * frand();
|
int likeassassination = Pop * 0.8 * frand();
|
||||||
printgreeting();
|
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);
|
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();
|
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)
|
else if(avgstarvepct > 3 || landperperson < 10)
|
||||||
{
|
{
|
||||||
print("Your performance could have been better, but wasn't too bad. ");
|
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
|
int
|
||||||
|
@ -606,7 +607,6 @@ printdeposed(void)
|
||||||
void
|
void
|
||||||
printgreeting(void)
|
printgreeting(void)
|
||||||
{
|
{
|
||||||
// print(MSGDIV);
|
|
||||||
print("\nO %s One, I beg to report,\n", HONORIFIC[nrand(MAXHONOR + 1)]);
|
print("\nO %s One, I beg to report,\n", HONORIFIC[nrand(MAXHONOR + 1)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,34 +617,41 @@ printEvtLandPr(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
printstatus(void)
|
printinitrept(void)
|
||||||
{
|
{
|
||||||
print("The population is %d.\n", Pop);
|
print(" ______________________________________________________________________\n");
|
||||||
print("You own %d acres.\n", Land);
|
print(" ( Your Reign Begins @\n");
|
||||||
print("You have %d bushels of grain.\n", Grain);
|
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
|
void
|
||||||
printyearrept(void)
|
printyearrept(void)
|
||||||
{
|
{
|
||||||
|
if(EvtPlague > 0) print("A horrible plague struck! Half the people died!\n");
|
||||||
print(" ______________________________________________________________________\n");
|
print(" ______________________________________________________________________\n");
|
||||||
print(" ( YEAR %2d @\n", Year);
|
print(" ( YEAR %2d @\n", Year);
|
||||||
print(" | Harvest yield %1d bushels per acre | Population last year %6d |\n", EvtYield, PrevPop);
|
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);
|
print(" \\/\\/ | Harvest %6d | ", GrainHarvest);
|
||||||
if(EvtStarve > 0) print("Starvation deaths %6d |\n", EvtStarve);
|
if(EvtStarve > 0) print("Starvation deaths %6d |\n", EvtStarve);
|
||||||
else print(" |\n");
|
else print(" |\n");
|
||||||
print(" |\\ | ");
|
print(" |\\ | ");
|
||||||
if(EvtRatsEat > 0) print("Eaten by rats %6d | ", EvtRatsEat);
|
if(EvtRatsEat > 0) print("Eaten by rats %6d | ", EvtRatsEat);
|
||||||
else print(" | ");
|
else print(" | ");
|
||||||
if(EvtPlague > 0) print("Plague deaths %6d |\n", EvtPlague);
|
if(EvtPlague > 0) print("%-20s%6d |\n", "Plague deaths", EvtPlague);
|
||||||
else print(" |\n");
|
else print(" |\n");
|
||||||
print(" |\\ | -------------------------------- | -------------------------------- |\n");
|
print(" |\\ | -------------------------------- | -------------------------------- |\n");
|
||||||
print(" |_\\_ | Balance %6d | Current population %6d |\n", Grain, Pop);
|
print(" |_\\_ | Balance %6d | Current population %6d |\n", Grain, Pop);
|
||||||
print(" | |\n");
|
print(" | |\n");
|
||||||
print(" | Land %6d Land price %2d |\n", Land, EvtLandPr);
|
print(" | Land %6d |\n", Land);
|
||||||
print(" |_____________________________________________________________________|\n");
|
print(" |_____________________________________________________________________|\n");
|
||||||
print(" (_____________________________________________________________________@\n");
|
print(" (______________________________________________________________________@\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in New Issue
Block a user