Work through 6/19

This commit is contained in:
David Meyer 2020-06-20 01:19:33 +09:00
parent 20c7837859
commit 287e6fa0f5
1 changed files with 209 additions and 28 deletions

View File

@ -8,14 +8,17 @@
#include <libc.h>
#include <stdio.h>
/* Constants */
#define MAXYEARS 10
#define INITPOP 100
#define INITGRAIN 2800
#define INITLAND 1000
/* Types */
typedef enum {FALSE, TRUE} Boolean;
typedef enum {BUY, SELL, FEED, PLANT, RESET, EXEC, CALC, QUIT} Plancmd;
/* Message texts */
char MSGDIV[] =
"------------------------------<<<<>>>>-----------------------------------\n";
@ -27,6 +30,19 @@ One person can farm ten acres of land.\n\
One person needs to eat 20 bushels of grain per year to stay healthy.\n\
";
char MSGMENU[]=
"You may use your grain to ...\n\
(F)eed your people,\n\
(P)lant crops on your land, or\n\
(B)uy more land. \n\
Or ...\n\
(S)ell land to increase your grain.\n\
You may also ...\n\
(E)xecute your current plan,\n\
(R)eset your current plan and start over, or\n\
(Q)uit the game.\n\
";
char MSGSPLASH[] =
" ___ ___ ___. .__ \n\
/ | \\_____ _____ _____ __ ______________ \\_ |__ |__|\n\
@ -52,12 +68,20 @@ char MSGSPLASH[] =
':==:'\n\
";
/* Honorifics */
#define MAXHONOR 9
char *HONORIFIC[] = {"Great", "Mighty", "Wise", "Benevolent", "Merciful", "Just", "Sublime",
"Glorious", "Serene", "Majestic"};
/* Function prototypes */
void completedterm(void);
int inputbuy(void);
int inputfood(void);
int inputiexpr(void);
int inputplant(void);
int inputsell(void);
void microcalc(void);
Plancmd planmenu(void);
Boolean planyear(void);
void printdeposed(void);
void printgreeting(void);
@ -67,25 +91,30 @@ void printyearrept(void);
Boolean scanyes(char *prompt);
void setlandprice(void);
/* Constant variables */
int CONSCTL;
/* Game state */
int Year = 0;
int Population = INITPOP;
int Pop = INITPOP;
int Grain = INITGRAIN;
int Land = INITLAND;
int StarvedTot = 0;
int StarvedPctTot = 0;
int consctl;
/* Annual plan */
int foodgrain, landsale, plantland;
/* Annual events */
int harvyield, landprice, newpop, plaguedeath, popfed, ratgrain, starvedeath, starvepct;
int totstarved = 0, totstarvepct = 0;
Boolean terminated = FALSE;
void
main(void)
{
consctl = open("/dev/consctl", OWRITE);
if(consctl == -1) exits("can't open consctl: %r\n");
CONSCTL = open("/dev/consctl", OWRITE);
if(CONSCTL == -1) exits("can't open CONSCTL: %r\n");
srand(time(0));
print(MSGSPLASH);
@ -122,11 +151,11 @@ main(void)
}
Grain = Grain + (plantland * harvyield) - ratgrain;
newpop = (nrand(5) + 1) * (20 * Land + Grain) / Population / 100 + 1;
newpop = (nrand(5) + 1) * (20 * Land + Grain) / Pop / 100 + 1;
popfed = foodgrain / 20;
starvedeath = ((popfed < Population) ? (Population - popfed) : 0);
totstarved = totstarved + starvedeath;
starvepct = 100 * starvedeath / Population;
starvedeath = ((popfed < Pop) ? (Pop - popfed) : 0);
StarvedTot = StarvedTot + starvedeath;
starvepct = 100 * starvedeath / Pop;
if(starvepct > 45)
{
printgreeting();
@ -136,10 +165,10 @@ main(void)
}
else
{
totstarvepct = totstarvepct + starvepct;
Population = Population + newpop - starvedeath;
plaguedeath = ((nrand(100) < 15) ? (Population / 2) : 0);
Population = Population - plaguedeath;
StarvedPctTot = StarvedPctTot + starvepct;
Pop = Pop + newpop - starvedeath;
plaguedeath = ((nrand(100) < 15) ? (Pop / 2) : 0);
Pop = Pop - plaguedeath;
printgreeting();
printyearrept();
@ -155,11 +184,11 @@ main(void)
void
completedterm(void)
{
int avgstarvepct = totstarvepct / MAXYEARS;
int landperperson = Land / Population;
int likeassassination = Population * 0.8 * frand();
int avgstarvepct = StarvedPctTot / MAXYEARS;
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 per year.\n", MAXYEARS, StarvedTot, 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!");
@ -171,6 +200,49 @@ completedterm(void)
else print("A fantastic performance! Charlemagne, Disraeli, and Jefferson combined could not have done better!");
}
int
inputbuy(void)
{
int buy, grainbal, price;
Boolean valid = FALSE;
grainbal = Grain - foodgrain - (plantland / 2);
do
{
print("The price of land is %d bushels per acre.\n", landprice);
print("How many acres do you wish to buy? ");
buy = inputiexpr();
price = buy * landprice;
if(buy < 0)
print("Sire, it is impossible to buy a negative amount of land.\nIf you wish to sell land, enter \"0\", then select (S)ell from the menu.\n");
else if(price > grainbal)
print("Sire, %d acres of land costs %d bushels of grain, and you have only %d bushels.\n",
buy, price, grainbal);
else valid = TRUE;
} while(valid == FALSE);
return buy;
}
int
inputfood(void)
{
int food, grainbal;
Boolean valid = FALSE;
grainbal = Grain + (landsale * landprice) - (plantland / 2);
do
{
print("How much grain do you wish to give your people for food? ");
food = inputiexpr();
if(food < 0)
print("Sire, it is impossible to give the people a negative amount of grain.\nEnter \"0\" to return to the menu.\n");
else if(food > grainbal)
print("Sire, you only have %d bushels of grain in the granaries.\n", grainbal);
else valid = TRUE;
} while(valid == FALSE);
return food;
}
int
inputiexpr(void)
{
@ -225,38 +297,147 @@ inputiexpr(void)
return result;
}
int
inputplant(void)
{
int grainbal, landbal, plant;
Boolean valid = FALSE;
grainbal = Grain - foodgrain + (landsale * landprice);
landbal = Land + landsale;
do
{
print("How many acres do you wish to plant? ");
plant = inputiexpr();
if(plant < 0)
print("Sire, it is impossible to plant a negative amount of land.\nEnter \"0\" to return to the menu.\n");
else if(plant > landbal) print("Sire, you have only %d acres of lands.\n", landbal);
else if((plant / 2) > grainbal)
print("Sire, you have only %d bushels of grain in the granaries.\n", grainbal);
else if(plant > (10 * Pop)) print("Sire, you have only enough people to plant %d acres.\n", 10 * Pop);
else valid = TRUE;
} while(valid == FALSE);
return plant;
}
int
inputsell(void)
{
int landbal, sell, price;
Boolean valid = FALSE;
landbal = Land - plantland;
do
{
print("The price of land is %d bushels per acre.\n", landprice);
print("How many acres do you wish to sell? ");
sell = inputiexpr();
if(sell < 0)
print("Sire, it is impossible to sell a negative amount of land.\nIf you wish to buy land, enter \"0\", then select (B)uy from the menu.\n");
else if(sell > landbal) print("Sire, you have only %d acres of land.\n", landbal);
else valid = TRUE;
} while(valid == FALSE);
return sell;
}
void
microcalc(void)
{
}
Plancmd
planmenu(void)
{
int cmdch = 0;
Plancmd cmd;
if(foodgrain > 0 || landsale != 0 || plantland > 0)
{
print("You are currently planning ...\n");
if(foodgrain > 0)
print("to provide %d bushels of grain to feed the people\n", foodgrain);
if(plantland > 0)
print("to plant %d acres of land using %d bushels of grain for seed\n",
plantland, plantland / 2);
if(landsale > 0)
print("to sell %d acres of land for %d bushels of grain\n", landsale,
landsale * landprice);
if(landsale < 0)
print("to buy %d acres of land for %d bushels of grain\n", landsale * -1,
landsale * landprice * -1);
}
print(MSGMENU);
if(write(CONSCTL, "rawon", 5) != 5) exits("\ncan't turn off echo\n");
while(cmdch == 0)
{
print("What is your choice? [fpbserq] ");
cmdch = getchar();
if(cmdch == EOF) exits("\nerror reading terminal input\n");
print("%c\n", cmdch);
switch(cmdch)
{
case 'b':
cmd = BUY;
break;
case 'e':
cmd = EXEC;
break;
case 'f':
cmd = FEED;
break;
case 'p':
cmd = PLANT;
break;
case 'q':
cmd = QUIT;
break;
case 'r':
cmd = RESET;
break;
case 's':
cmd = SELL;
break;
default:
cmdch = 0;
}
}
if(write(CONSCTL, "rawoff", 6) != 6) exits("\ncan't turn on echo\n");
return cmd;
}
Boolean
planyear(void)
{
Boolean play = TRUE;
Plancmd cmd;
foodgrain = landsale = planland = 0;
foodgrain = landsale = plantland = 0;
do
{
cmd = planmenu();
switch(cmd)
{
case BUY:
landsale = -1 * inputbuy();
break;
case SELL:
landsale = inputsell();
break;
case FEED:
foodgrain = inputfood();
break;
case PLANT:
plantland = inputplant();
break;
case RESET:
foodgrain = landsale = planland = 0;
foodgrain = landsale = plantland = 0;
break;
case EXEC:
break;
case CALC:
ezintcalc();
microcalc();
break;
case QUIT:
play = FALSE;
@ -288,7 +469,7 @@ printlandprice(void)
void
printstatus(void)
{
print("The population is %d.\n", Population);
print("The population is %d.\n", Pop);
print("You own %d acres.\n", Land);
print("You have %d bushels of grain.\n", Grain);
}
@ -309,7 +490,7 @@ scanyes(char *prompt)
{
int in = 0;
if(write(consctl, "rawon", 5) != 5) exits("\ncan't turn off echo\n");
if(write(CONSCTL, "rawon", 5) != 5) exits("\ncan't turn off echo\n");
while(in != 'y' && in != 'n')
{
print("%s [y/n] ", prompt);
@ -317,7 +498,7 @@ scanyes(char *prompt)
if(in == EOF) exits("\nerror reading terminal input\n");
print("%c\n", in);
}
if(write(consctl, "rawoff", 6) != 6) exits("\ncan't turn on echo\n");
if(write(CONSCTL, "rawoff", 6) != 6) exits("\ncan't turn on echo\n");
print("\n");
return (in == 'y' ? TRUE : FALSE);
}