diff --git a/hammurabi.c b/hammurabi.c index 42ee713..ffbe622 100644 --- a/hammurabi.c +++ b/hammurabi.c @@ -109,21 +109,34 @@ char *HONORIFIC[] = {"Great", "Mighty", "Wise", "Benevolent", "Merciful", "Just" /* Function prototypes */ void completedterm(void); +int evtbrthimm(void); +int evtlandpr(void); +int evtplague(void); +int evtratseat(void); +int evtstarve(void); +int evtyield(void); +int grainafterplan(void); +int grainafterlandsp(void); +int grainharvest(void); +int graintoplant(void); int inputbuy(void); int inputfood(void); int inputiexpr(void); int inputplant(void); int inputsell(void); +int landafterplan(void); void microcalc(void); +int peoplefed(void); Plancmd planmenu(void); Boolean planyear(void); +int popnet(void); void printdeposed(void); void printgreeting(void); -void printlandprice(void); +void printEvtLandPr(void); void printstatus(void); void printyearrept(void); +int salegrain(void); Boolean scanyes(char *prompt); -void setlandprice(void); /* Constant variables */ int CONSCTL; @@ -133,20 +146,29 @@ int Year = 0; int Pop = INITPOP; int Grain = INITGRAIN; int Land = INITLAND; -int StarvedTot = 0; -int StarvedPctTot = 0; + +/* Total statistics */ +int TotStarved = 0; +int TotStarvePct = 0; /* Annual plan */ -int foodgrain, landsale, plantland; +int PlanFood, PlanSale, PlanPlant; /* Annual events */ -int harvyield, landprice, newpop, plaguedeath, popfed, ratgrain, starvedeath, starvepct; +int EvtYield, EvtLandPr, EvtBrthImm, EvtPlague, EvtRatsEat, EvtStarve; -Boolean terminated = FALSE; +/* Beginning of year stats */ +int PrevPop, PrevGrain, PrevLand; + +/* Derived values */ +int GrainAfterPlan, LandAfterPlan, GrainHarvest; void main(void) { + int popfed, starvepct; + Boolean gameover = FALSE; + CONSCTL = open("/dev/consctl", OWRITE); if(CONSCTL == -1) exits("can't open CONSCTL: %r\n"); srand(time(0)); @@ -156,53 +178,41 @@ main(void) printgreeting(); printstatus(); - setlandprice(); - printlandprice(); + EvtLandPr = evtlandpr(); + printEvtLandPr(); do { ++ Year; - if(planyear() == FALSE) terminated = TRUE; + if(planyear() == FALSE) gameover = TRUE; else { - Grain = Grain + (landsale * landprice) - (plantland / 2) - foodgrain; - Land = Land - landsale; + PrevPop = Pop; + PrevGrain = Grain; Grain = GrainAfterPlan; + PrevLand = Land; Land = LandAfterPlan; + EvtYield = evtyield(); + EvtRatsEat = evtratseat(); + GrainHarvest = grainharvest(); + Grain = Grain + GrainHarvest - EvtRatsEat; - harvyield = nrand(5) + 1; - switch(nrand(5)+1) - { - case 1: - ratgrain = Grain; - break; - case 3: - ratgrain = Grain / 3; - break; - case 5: - ratgrain = Grain / 5; - break; - default: - ratgrain = 0; - } - Grain = Grain + (plantland * harvyield) - ratgrain; - - newpop = (nrand(5) + 1) * (20 * Land + Grain) / Pop / 100 + 1; - popfed = foodgrain / 20; - starvedeath = ((popfed < Pop) ? (Pop - popfed) : 0); - StarvedTot = StarvedTot + starvedeath; - starvepct = 100 * starvedeath / Pop; + EvtBrthImm = evtbrthimm(); + popfed = peoplefed(); + EvtStarve = evtstarve(); + TotStarved = TotStarved + EvtStarve; + starvepct = 100 * EvtStarve / Pop; if(starvepct > 45) { printgreeting(); - print("You have starved %d of your subjects in one year!\n", starvedeath); + print("You have starved %d of your subjects in one year!\n", EvtStarve); printdeposed(); - terminated = TRUE; + gameover = TRUE; } else { - StarvedPctTot = StarvedPctTot + starvepct; - Pop = Pop + newpop - starvedeath; - plaguedeath = ((nrand(100) < 15) ? (Pop / 2) : 0); - Pop = Pop - plaguedeath; + TotStarvePct = TotStarvePct + starvepct; + Pop = Pop + EvtBrthImm - EvtStarve; + EvtPlague = evtplague(); + Pop = Pop - EvtPlague; printgreeting(); printyearrept(); @@ -211,12 +221,12 @@ main(void) if(Year == MAXYEARS) completedterm(); else { - setlandprice(); - printlandprice(); + EvtLandPr = evtlandpr(); + printEvtLandPr(); } } } - } while(Year < MAXYEARS && terminated == FALSE); + } while(Year < MAXYEARS && gameover == FALSE); print(MSGDIV); exits(0); } @@ -224,11 +234,11 @@ main(void) void completedterm(void) { - int avgstarvepct = StarvedPctTot / MAXYEARS; + int avgstarvepct = TotStarvePct / 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, StarvedTot, avgstarvepct); + print("In your %d-year reign, %d people died of starvation, an average of %d people per 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"); @@ -240,19 +250,95 @@ completedterm(void) else print("A fantastic performance! Charlemagne, Disraeli, and Jefferson combined could not have done better!\n"); } +int +evtbrthimm(void) +{ + return ((nrand(5) + 1) * (20 * Land + Grain) / Pop / 100 + 1); +} + +int +evtlandpr(void) +{ + return (nrand(10) + 17); +} + +int +evtplague(void) +{ + return ((nrand(100) < 15) ? (Pop / 2) : 0); +} + +int +evtratseat(void) +{ + int eat; + switch(nrand(5)+1) + { + case 1: + eat = Grain; + break; + case 3: + eat = Grain / 3; + break; + case 5: + eat = Grain / 5; + break; + default: + eat = 0; + } + return eat; +} + +int +evtstarve(void) +{ + int popfed = peoplefed(); + return ((popfed < Pop) ? (Pop - popfed) : 0); +} + +int +evtyield(void) +{ + return (nrand(5) + 1); +} + +int +grainafterplan(void) +{ + return (grainafterlandsp() - graintoplant() - PlanFood); +} + +int +grainafterlandsp(void) +{ + return (Grain + (PlanSale * EvtLandPr)); +} + +int +grainharvest(void) +{ + return (PlanPlant * EvtYield); +} + +int +graintoplant(void) +{ + return (PlanPlant / 2); +} + int inputbuy(void) { int buy, grainbal, price; Boolean valid = FALSE; - grainbal = Grain - foodgrain - (plantland / 2); + grainbal = Grain - PlanFood - (PlanPlant / 2); do { - print("\nThe price of land is %d bushels per acre.\n", landprice); + print("\nThe price of land is %d bushels per acre.\n", EvtLandPr); print("How many acres do you wish to buy? "); buy = inputiexpr(); - price = buy * landprice; + price = buy * EvtLandPr; 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) @@ -269,7 +355,7 @@ inputfood(void) int food, grainbal; Boolean valid = FALSE; - grainbal = Grain + (landsale * landprice) - (plantland / 2); + grainbal = Grain + (PlanSale * EvtLandPr) - (PlanPlant / 2); do { print("\nHow much grain do you wish to give your people for food? "); @@ -343,8 +429,8 @@ inputplant(void) int grainbal, landbal, plant; Boolean valid = FALSE; - grainbal = Grain - foodgrain + (landsale * landprice); - landbal = Land - landsale; + grainbal = Grain - PlanFood + (PlanSale * EvtLandPr); + landbal = Land - PlanSale; do { print("\nHow many acres do you wish to plant? "); @@ -366,10 +452,10 @@ inputsell(void) int landbal, sell, price; Boolean valid = FALSE; - landbal = Land - plantland; + landbal = Land - PlanPlant; do { - print("\nThe price of land is %d bushels per acre.\n", landprice); + print("\nThe price of land is %d bushels per acre.\n", EvtLandPr); print("How many acres do you wish to sell? "); sell = inputiexpr(); if(sell < 0) @@ -380,12 +466,24 @@ inputsell(void) return sell; } +int +landafterplan(void) +{ + return (Land - PlanSale); +} + void microcalc(void) { } +int +peoplefed(void) +{ + return (PlanFood / 20); +} + Plancmd planmenu(void) { @@ -393,20 +491,19 @@ planmenu(void) Plancmd cmd; print("\n Plan for Year %d\n", Year); - print(" Grain in storage %7d | Land (price %2d) %7d\n", Grain, landprice, Land); - if(landsale > 0) - print(" From land sale %7d | Sell %7d\n", landsale * landprice, landsale); - if(landsale < 0) - print(" For land purchase%7d | Purchase %7d\n", landsale * landprice * -1, landsale * -1); - if(landsale != 0) - print("%s Net %7d | Net %7d\n", MSGPLTOT, Grain + (landsale * landprice), Land - landsale); - if(foodgrain > 0) print(" Provide for food %7d |\n", foodgrain); - if(plantland > 0) - print(" Provide for seed %7d | Plant %7d\n", plantland / 2, plantland); - if(foodgrain > 0 || plantland > 0) - print("%s Balance %7d | Fallow acres %7d\n", MSGPLTOT, - Grain + (landsale * landprice) - foodgrain - (plantland / 2), - Land - landsale - plantland); + print(" Grain in storage %7d | Land (price %2d) %7d\n", Grain, EvtLandPr, Land); + if(PlanSale > 0) + print(" From land sale %7d | Sell %7d\n", salegrain(), PlanSale); + if(PlanSale < 0) + print(" For land purchase%7d | Purchase %7d\n", salegrain() * -1, PlanSale * -1); + if(PlanSale != 0) + print("%s Net %7d | Net %7d\n", MSGPLTOT, grainafterlandsp(), LandAfterPlan); + if(PlanFood > 0) print(" Provide for food %7d |\n", PlanFood); + if(PlanPlant > 0) + print(" Provide for seed %7d | Plant %7d\n", graintoplant(), PlanPlant); + if(PlanFood > 0 || PlanPlant > 0) + print("%s Balance %7d | Fallow acres %7d\n", MSGPLTOT, GrainAfterPlan, + Land - PlanSale - PlanPlant); print("\n Population: %d (need food: %d; can farm: %d)\n", Pop, Pop * 20, Pop * 10); print(MSGMENU); @@ -454,26 +551,26 @@ planyear(void) Boolean play = TRUE; Plancmd cmd; - foodgrain = landsale = plantland = 0; + PlanFood = PlanSale = PlanPlant = 0; do { cmd = planmenu(); switch(cmd) { case BUY: - landsale = -1 * inputbuy(); + PlanSale = -1 * inputbuy(); break; case SELL: - landsale = inputsell(); + PlanSale = inputsell(); break; case FEED: - foodgrain = inputfood(); + PlanFood = inputfood(); break; case PLANT: - plantland = inputplant(); + PlanPlant = inputplant(); break; case RESET: - foodgrain = landsale = plantland = 0; + PlanFood = PlanSale = PlanPlant = 0; break; case EXEC: print("\nSo it shall be written, so it shall be done.\n"); @@ -485,10 +582,21 @@ planyear(void) play = FALSE; break; } + if(cmd != QUIT) + { + GrainAfterPlan = grainafterplan(); + LandAfterPlan = landafterplan(); + } } while(cmd != EXEC && cmd != QUIT); return play; } +int +popnet(void) +{ + return (Pop + EvtBrthImm - EvtStarve); +} + void printdeposed(void) { @@ -503,9 +611,9 @@ printgreeting(void) } void -printlandprice(void) +printEvtLandPr(void) { - print("The price of land is %d bushels of grain per acre.\n", landprice); + print("The price of land is %d bushels of grain per acre.\n", EvtLandPr); } void @@ -519,29 +627,30 @@ printstatus(void) void printyearrept(void) { - print(" ____________________________________________________________________\n"); - print(" ( YEAR %2d @\n", Year); - print(" | Harvest yield %1d bushels per acre | (Land price %2d bushels per acre) |\n", harvyield, landprice); - print(" /}_ _ | In Year %d\n", Year); - print(" \\/\\/ | %d bushels were harvested per acre, for a total harvest of %d bushels\n", - harvyield, plantland * harvyield); - print(" |\\ |"); - if(ratgrain > 0) print(" Rats ate %d bushels of grain.", ratgrain); - print("\n |\\ |"); - if(newpop > 0) print(" The population increased by %d.", newpop); - print("\n |_\\_ |"); - if(starvedeath > 0) print(" %d people starved!", starvedeath); - print("\n |"); - if(plaguedeath > 0) print(" A horrible plague struck! %d people have died!", plaguedeath); - print("\n |________________________________________________50\n"); - print(" (________________________________________________50\n"); - print("In Year %d,\n", Year); - print("%d bushels were harvested per acre, for a total harvest of %d bushels.\n", - harvyield, plantland * harvyield); - if(ratgrain > 0) print("Rats ate %d bushels of grain.\n", ratgrain); - if(newpop > 0) print("The population increased by %d.\n", newpop); - if(starvedeath > 0) print("%d people starved!\n", starvedeath); - if(plaguedeath > 0) print("A horrible plague struck! %d people have died!\n", plaguedeath); + 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(" \\/\\/ | 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); + 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(" |_____________________________________________________________________|\n"); + print(" (_____________________________________________________________________@\n"); +} + +int +salegrain(void) +{ + return (PlanSale * EvtLandPr); } Boolean @@ -562,9 +671,3 @@ scanyes(char *prompt) return (in == 'y' ? TRUE : FALSE); } -void -setlandprice(void) -{ - landprice = nrand(10) + 17; -} -