2020-06-14 06:04:08 +00:00
/*
* hammurabi - ancient Sumerian city - state resource management game
*
* Copyright 2020 David Meyer < papa @ sdf . org > + JMJ
*
*/
# include <u.h>
# include <libc.h>
# include <stdio.h>
2020-06-19 16:19:33 +00:00
/* Constants */
2020-06-14 06:04:08 +00:00
# define MAXYEARS 10
# define INITPOP 100
# define INITGRAIN 2800
# define INITLAND 1000
2020-06-19 16:19:33 +00:00
/* Types */
2020-06-14 06:04:08 +00:00
typedef enum { FALSE , TRUE } Boolean ;
2020-06-15 14:24:12 +00:00
typedef enum { BUY , SELL , FEED , PLANT , RESET , EXEC , CALC , QUIT } Plancmd ;
2020-06-14 06:04:08 +00:00
2020-06-19 16:19:33 +00:00
/* Message texts */
2020-07-15 11:07:44 +00:00
char MSGDANCE [ ] =
" |vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv| \n \
| ( } _ _ _ _ _ _ _ _ _ _ _ _ _ _ { ) | \ n \
| \ \ / \ \ / \ \ ( } / ( } \ \ ( } / ( } \ \ ( ) / { ) \ \ { ) / { ) \ \ { ) / \ \ / \ \ / | \ n \
| | \ \ | _ _ / | \ \ _ | _ _ / | \ \ _ \ \ / _ / | \ \ _ _ | _ / | \ \ _ _ | / | | \ n \
| | _ \ \ _ | \ \ / \ \ | \ \ / \ \ / \ \ / \ \ / | / \ \ / | _ / _ | | \ n \
| vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv | \ n \
" ;
2020-06-14 06:04:08 +00:00
char MSGHELP [ ] =
2020-07-15 11:07:44 +00:00
" \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 \
2020-06-14 06:04:08 +00:00
" ;
2020-06-19 16:19:33 +00:00
char MSGMENU [ ] =
2020-07-01 14:56:44 +00:00
" \n \
2020-07-02 15:00:40 +00:00
[ 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 \
2020-07-15 11:07:44 +00:00
[ S ] ell land for grain \ n \
2020-06-19 16:19:33 +00:00
" ;
2020-07-01 14:56:44 +00:00
char MSGPLTOT [ ] =
2020-07-02 15:00:40 +00:00
" ------------------------------- | ------------------------------- \n " ;
2020-07-01 14:56:44 +00:00
2020-06-14 06:04:08 +00:00
char MSGSPLASH [ ] =
" ___ ___ ___. .__ \n \
/ | \ \ _____ _____ _____ __ ______________ \ \ _ | __ | __ | \ n \
/ ~ \ \ __ \ \ / \ \ / \ \ | | \ \ _ __ \ \ __ \ \ | __ \ \ | | \ n \
\ \ Y / / __ \ \ | Y Y \ \ Y Y \ \ | / | | \ \ / / __ \ \ | \ \ _ \ \ \ \ | \ n \
\ \ ___ | _ / ( ____ / __ | _ | / __ | _ | / ____ / | __ | ( ____ / ___ / __ | \ n \
\ \ / \ \ / \ \ / \ \ / \ \ / \ \ / \ n \
2020-06-21 14:52:06 +00:00
The ancient game of , . __ . , resource management \ n \
2020-06-14 06:04:08 +00:00
/ , ' , . ` . \ \ \ n \
2020-06-21 14:52:06 +00:00
Version 1.0 ____ | : | db | : | ____ by David Meyer \ n \
for Plan 9 ___ / / \ " \" \" |:|88|:| \" \" \" \\ \\ ___ <papa@sdf.org> \n \
2020-06-14 06:04:08 +00:00
_____ / / \ " :=_=_=_=|--|=_=_=_=: \" \\ \\ _____ \n \
__ / . - . _ / / __ | L_L_L_L | - - | L_L_L_L | __ \ \ \ \ _ . - . \ \ __ \ n \
/ / \ " ||m|:.-. .-. .-.,.__.,.-. .-. .-.:|m|| \" \\ \\ \n \
/ / | | 8 | | : : L_L_L_ / . ' , . ` . \ \ _L_L_L : : | | 8 | | \ \ \ \ \ n \
/ ' = = = = = = = \ " L.='.::'`:|:|db|:|:'`::.`=.L \" =======` \\ \n \
| . - - - . . - - . | _ : = = ' | : | 88 | : | ` = = : _ | . - - . . - - - . | \ n \
| | : | _ . = ' / = = = = = = = | : - - : | = = = = = = = \ \ ` = . _ | : | | \ n \
| | _ , = ' | | = = . = . = = | : - - : | = = . = . = = | | ` = . _ | | \ n \
| _ : = ' _______ | | | | | | | : - - : | | | | | | | _______ ` = : _ | \ n \
| | | | | | | : - - : | | | | | | | \ n \
' ' - - - - - - - | : - - : | - - - - - - - ' ' \ n \
' : = = : ' \ n \
" ;
2020-06-19 16:19:33 +00:00
/* Honorifics */
2020-06-14 06:04:08 +00:00
# define MAXHONOR 9
char * HONORIFIC [ ] = { " Great " , " Mighty " , " Wise " , " Benevolent " , " Merciful " , " Just " , " Sublime " ,
" Glorious " , " Serene " , " Majestic " } ;
2020-06-19 16:19:33 +00:00
/* Function prototypes */
2020-06-15 14:24:12 +00:00
void completedterm ( void ) ;
2020-07-13 14:55:18 +00:00
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 ) ;
2020-06-19 16:19:33 +00:00
int inputbuy ( void ) ;
int inputfood ( void ) ;
2020-06-15 14:24:12 +00:00
int inputiexpr ( void ) ;
2020-06-19 16:19:33 +00:00
int inputplant ( void ) ;
int inputsell ( void ) ;
2020-07-13 14:55:18 +00:00
int landafterplan ( void ) ;
2020-06-19 16:19:33 +00:00
void microcalc ( void ) ;
2020-07-13 14:55:18 +00:00
int peoplefed ( void ) ;
2020-06-19 16:19:33 +00:00
Plancmd planmenu ( void ) ;
2020-06-14 06:04:08 +00:00
Boolean planyear ( void ) ;
2020-07-13 14:55:18 +00:00
int popnet ( void ) ;
2020-06-15 14:24:12 +00:00
void printdeposed ( void ) ;
2020-06-14 06:04:08 +00:00
void printgreeting ( void ) ;
2020-07-15 11:07:44 +00:00
void printinitrept ( void ) ;
2020-06-14 06:04:08 +00:00
void printyearrept ( void ) ;
2020-07-13 14:55:18 +00:00
int salegrain ( void ) ;
2020-06-14 06:04:08 +00:00
Boolean scanyes ( char * prompt ) ;
2020-06-19 16:19:33 +00:00
/* Constant variables */
int CONSCTL ;
/* Game state */
2020-06-14 06:04:08 +00:00
int Year = 0 ;
2020-06-19 16:19:33 +00:00
int Pop = INITPOP ;
2020-06-14 06:04:08 +00:00
int Grain = INITGRAIN ;
int Land = INITLAND ;
2020-07-13 14:55:18 +00:00
/* Total statistics */
int TotStarved = 0 ;
int TotStarvePct = 0 ;
2020-06-14 06:04:08 +00:00
2020-06-19 16:19:33 +00:00
/* Annual plan */
2020-07-13 14:55:18 +00:00
int PlanFood , PlanSale , PlanPlant ;
2020-06-14 06:04:08 +00:00
2020-06-19 16:19:33 +00:00
/* Annual events */
2020-07-13 14:55:18 +00:00
int EvtYield , EvtLandPr , EvtBrthImm , EvtPlague , EvtRatsEat , EvtStarve ;
/* Beginning of year stats */
int PrevPop , PrevGrain , PrevLand ;
2020-06-14 06:04:08 +00:00
2020-07-13 14:55:18 +00:00
/* Derived values */
int GrainAfterPlan , LandAfterPlan , GrainHarvest ;
2020-06-14 06:04:08 +00:00
void
main ( void )
{
2020-07-13 14:55:18 +00:00
int popfed , starvepct ;
Boolean gameover = FALSE ;
2020-06-19 16:19:33 +00:00
CONSCTL = open ( " /dev/consctl " , OWRITE ) ;
if ( CONSCTL = = - 1 ) exits ( " can't open CONSCTL: %r \n " ) ;
2020-06-14 06:04:08 +00:00
srand ( time ( 0 ) ) ;
print ( MSGSPLASH ) ;
if ( scanyes ( " Would you like instructions? " ) = = TRUE ) print ( MSGHELP ) ;
2020-07-15 11:07:44 +00:00
print ( MSGDANCE ) ;
2020-06-14 06:04:08 +00:00
2020-07-13 14:55:18 +00:00
EvtLandPr = evtlandpr ( ) ;
2020-07-15 11:07:44 +00:00
printgreeting ( ) ;
printinitrept ( ) ;
2020-06-14 06:04:08 +00:00
2020-06-15 14:24:12 +00:00
do
2020-06-14 06:04:08 +00:00
{
2020-06-15 14:24:12 +00:00
+ + Year ;
2020-07-13 14:55:18 +00:00
if ( planyear ( ) = = FALSE ) gameover = TRUE ;
2020-06-15 14:24:12 +00:00
else
2020-06-14 06:04:08 +00:00
{
2020-07-13 14:55:18 +00:00
PrevPop = Pop ;
PrevGrain = Grain ; Grain = GrainAfterPlan ;
PrevLand = Land ; Land = LandAfterPlan ;
EvtYield = evtyield ( ) ;
EvtRatsEat = evtratseat ( ) ;
GrainHarvest = grainharvest ( ) ;
Grain = Grain + GrainHarvest - EvtRatsEat ;
EvtBrthImm = evtbrthimm ( ) ;
popfed = peoplefed ( ) ;
EvtStarve = evtstarve ( ) ;
TotStarved = TotStarved + EvtStarve ;
starvepct = 100 * EvtStarve / Pop ;
2020-06-15 14:24:12 +00:00
if ( starvepct > 45 )
{
printgreeting ( ) ;
2020-07-13 14:55:18 +00:00
print ( " You have starved %d of your subjects in one year! \n " , EvtStarve ) ;
2020-06-15 14:24:12 +00:00
printdeposed ( ) ;
2020-07-13 14:55:18 +00:00
gameover = TRUE ;
2020-06-15 14:24:12 +00:00
}
else
{
2020-07-13 14:55:18 +00:00
TotStarvePct = TotStarvePct + starvepct ;
Pop = Pop + EvtBrthImm - EvtStarve ;
EvtPlague = evtplague ( ) ;
Pop = Pop - EvtPlague ;
2020-06-15 14:24:12 +00:00
printgreeting ( ) ;
printyearrept ( ) ;
2020-06-14 06:04:08 +00:00
2020-06-15 14:24:12 +00:00
if ( Year = = MAXYEARS ) completedterm ( ) ;
2020-06-21 14:52:06 +00:00
else
{
2020-07-13 14:55:18 +00:00
EvtLandPr = evtlandpr ( ) ;
2020-06-21 14:52:06 +00:00
}
2020-06-15 14:24:12 +00:00
}
2020-06-14 06:04:08 +00:00
}
2020-07-13 14:55:18 +00:00
} while ( Year < MAXYEARS & & gameover = = FALSE ) ;
2020-07-15 11:07:44 +00:00
print ( " \n " ) ;
print ( MSGDANCE ) ;
2020-06-14 06:04:08 +00:00
exits ( 0 ) ;
}
2020-06-15 14:24:12 +00:00
void
completedterm ( void )
{
2020-07-13 14:55:18 +00:00
int avgstarvepct = TotStarvePct / MAXYEARS ;
2020-06-19 16:19:33 +00:00
int landperperson = Land / Pop ;
int likeassassination = Pop * 0.8 * frand ( ) ;
2020-06-15 14:24:12 +00:00
printgreeting ( ) ;
2020-07-15 11:07:44 +00:00
print ( " In your %d-year reign, %d people died of starvation, an average of %d people \n per year. \n " , MAXYEARS , TotStarved , avgstarvepct ) ;
2020-06-15 14:24:12 +00:00
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 ( ) ;
2020-07-15 11:07:44 +00:00
else if ( avgstarvepct > 10 | | landperperson < 9 ) print ( " Your heavy-handed performance smacks of Nero and Ivan IV. Your (surviving) \n people find you an unpleasant ruler, and, frankly, hate your guts! \n " ) ;
2020-06-15 14:24:12 +00:00
else if ( avgstarvepct > 3 | | landperperson < 10 )
{
print ( " Your performance could have been better, but wasn't too bad. " ) ;
2020-07-15 11:07:44 +00:00
if ( likeassassination > 0 ) print ( " %d %s would like to see you assassinated, but we all have our trivial \n problems. \n " , likeassassination , ( likeassassination = = 1 ? " person " : " people " ) ) ;
2020-06-15 14:24:12 +00:00
}
2020-07-15 11:07:44 +00:00
else print ( " A fantastic performance! Charlemagne, Disraeli, and Jefferson combined could not \n have done better! \n " ) ;
2020-06-15 14:24:12 +00:00
}
2020-07-13 14:55:18 +00:00
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 ) ;
}
2020-06-19 16:19:33 +00:00
int
inputbuy ( void )
{
int buy , grainbal , price ;
Boolean valid = FALSE ;
2020-07-13 14:55:18 +00:00
grainbal = Grain - PlanFood - ( PlanPlant / 2 ) ;
2020-06-19 16:19:33 +00:00
do
{
2020-07-13 14:55:18 +00:00
print ( " \n The price of land is %d bushels per acre. \n " , EvtLandPr ) ;
2020-06-19 16:19:33 +00:00
print ( " How many acres do you wish to buy? " ) ;
buy = inputiexpr ( ) ;
2020-07-13 14:55:18 +00:00
price = buy * EvtLandPr ;
2020-06-19 16:19:33 +00:00
if ( buy < 0 )
print ( " Sire, it is impossible to buy a negative amount of land. \n If 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 ;
2020-07-13 14:55:18 +00:00
grainbal = Grain + ( PlanSale * EvtLandPr ) - ( PlanPlant / 2 ) ;
2020-06-19 16:19:33 +00:00
do
{
2020-07-02 15:00:40 +00:00
print ( " \n How much grain do you wish to give your people for food? " ) ;
2020-06-19 16:19:33 +00:00
food = inputiexpr ( ) ;
if ( food < 0 )
print ( " Sire, it is impossible to give the people a negative amount of grain. \n Enter \" 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 ;
}
2020-06-15 14:24:12 +00:00
int
inputiexpr ( void )
{
char buf [ 80 ] ;
int buflen = 80 ;
int result = 0 ;
int ch , rix , wix , p , o , n [ 40 ] ;
char op [ 39 ] ;
if ( fgets ( buf , buflen , stdin ) ! = NULL )
{
if ( buf [ strlen ( buf ) - 1 ] ! = ' \n ' ) while ( ( ch = getchar ( ) ) ! = ' \n ' & & ch ! = EOF ) ;
rix = wix = 0 ;
while ( buf [ rix ] ! = ' \0 ' )
{
if ( strchr ( " 0123456789+-*/ " , buf [ rix ] ) ! = 0 )
{
if ( rix > wix ) buf [ wix ] = buf [ rix ] ;
+ + wix ;
}
+ + rix ;
}
buf [ wix ] = ' \0 ' ;
p = sscanf ( buf , " %d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d " ,
& n [ 0 ] , & op [ 0 ] , & n [ 1 ] , & op [ 1 ] , & n [ 2 ] , & op [ 2 ] , & n [ 3 ] , & op [ 3 ] , & n [ 4 ] , & op [ 4 ] , & n [ 5 ] , & op [ 5 ] , & n [ 6 ] , & op [ 6 ] , & n [ 7 ] , & op [ 7 ] , & n [ 8 ] , & op [ 8 ] , & n [ 9 ] , & op [ 9 ] ,
& n [ 10 ] , & op [ 10 ] , & n [ 11 ] , & op [ 11 ] , & n [ 12 ] , & op [ 12 ] , & n [ 13 ] , & op [ 13 ] , & n [ 14 ] , & op [ 14 ] , & n [ 15 ] , & op [ 15 ] , & n [ 16 ] , & op [ 16 ] , & n [ 17 ] , & op [ 17 ] , & n [ 18 ] , & op [ 18 ] , & n [ 19 ] , & op [ 19 ] ,
& n [ 20 ] , & op [ 20 ] , & n [ 21 ] , & op [ 21 ] , & n [ 22 ] , & op [ 22 ] , & n [ 23 ] , & op [ 23 ] , & n [ 24 ] , & op [ 24 ] , & n [ 25 ] , & op [ 25 ] , & n [ 26 ] , & op [ 26 ] , & n [ 27 ] , & op [ 27 ] , & n [ 28 ] , & op [ 28 ] , & n [ 29 ] , & op [ 29 ] ,
& n [ 30 ] , & op [ 30 ] , & n [ 31 ] , & op [ 31 ] , & n [ 32 ] , & op [ 32 ] , & n [ 33 ] , & op [ 33 ] , & n [ 34 ] , & op [ 34 ] , & n [ 35 ] , & op [ 35 ] , & n [ 36 ] , & op [ 36 ] , & n [ 37 ] , & op [ 37 ] , & n [ 38 ] , & op [ 38 ] , & n [ 39 ] ) ;
if ( p > 0 )
{
result = n [ 0 ] ;
for ( o = 0 ; o < ( int ) ( p / 2 ) ; + + o )
{
switch ( op [ o ] )
{
case ' + ' :
result = result + n [ o + 1 ] ;
break ;
case ' - ' :
result = result - n [ o + 1 ] ;
break ;
case ' * ' :
result = result * n [ o + 1 ] ;
break ;
case ' / ' :
result = result / n [ o + 1 ] ;
break ;
}
}
}
}
return result ;
}
2020-06-19 16:19:33 +00:00
int
inputplant ( void )
{
int grainbal , landbal , plant ;
Boolean valid = FALSE ;
2020-07-13 14:55:18 +00:00
grainbal = Grain - PlanFood + ( PlanSale * EvtLandPr ) ;
landbal = Land - PlanSale ;
2020-06-19 16:19:33 +00:00
do
{
2020-07-02 15:00:40 +00:00
print ( " \n How many acres do you wish to plant? " ) ;
2020-06-19 16:19:33 +00:00
plant = inputiexpr ( ) ;
if ( plant < 0 )
print ( " Sire, it is impossible to plant a negative amount of land. \n Enter \" 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 ;
2020-07-13 14:55:18 +00:00
landbal = Land - PlanPlant ;
2020-06-19 16:19:33 +00:00
do
{
2020-07-13 14:55:18 +00:00
print ( " \n The price of land is %d bushels per acre. \n " , EvtLandPr ) ;
2020-06-19 16:19:33 +00:00
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. \n If 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 ;
}
2020-07-13 14:55:18 +00:00
int
landafterplan ( void )
{
return ( Land - PlanSale ) ;
}
2020-06-19 16:19:33 +00:00
void
microcalc ( void )
{
}
2020-07-13 14:55:18 +00:00
int
peoplefed ( void )
{
return ( PlanFood / 20 ) ;
}
2020-06-19 16:19:33 +00:00
Plancmd
planmenu ( void )
{
int cmdch = 0 ;
Plancmd cmd ;
2020-07-01 14:56:44 +00:00
print ( " \n Plan for Year %d \n " , Year ) ;
2020-07-13 14:55:18 +00:00
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 ) ;
2020-07-02 15:00:40 +00:00
print ( " \n Population: %d (need food: %d; can farm: %d) \n " , Pop , Pop * 20 , Pop * 10 ) ;
2020-07-01 14:56:44 +00:00
2020-06-19 16:19:33 +00:00
print ( MSGMENU ) ;
if ( write ( CONSCTL , " rawon " , 5 ) ! = 5 ) exits ( " \n can't turn off echo \n " ) ;
while ( cmdch = = 0 )
{
2020-07-02 15:00:40 +00:00
print ( " What is your choice? [fpbserq] " ) ;
2020-06-19 16:19:33 +00:00
cmdch = getchar ( ) ;
if ( cmdch = = EOF ) exits ( " \n error 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 ( " \n can't turn on echo \n " ) ;
return cmd ;
}
2020-06-14 06:04:08 +00:00
Boolean
planyear ( void )
{
2020-06-15 14:24:12 +00:00
Boolean play = TRUE ;
Plancmd cmd ;
2020-07-13 14:55:18 +00:00
PlanFood = PlanSale = PlanPlant = 0 ;
2020-06-15 14:24:12 +00:00
do
{
cmd = planmenu ( ) ;
switch ( cmd )
{
case BUY :
2020-07-13 14:55:18 +00:00
PlanSale = - 1 * inputbuy ( ) ;
2020-06-15 14:24:12 +00:00
break ;
case SELL :
2020-07-13 14:55:18 +00:00
PlanSale = inputsell ( ) ;
2020-06-15 14:24:12 +00:00
break ;
case FEED :
2020-07-13 14:55:18 +00:00
PlanFood = inputfood ( ) ;
2020-06-15 14:24:12 +00:00
break ;
case PLANT :
2020-07-13 14:55:18 +00:00
PlanPlant = inputplant ( ) ;
2020-06-15 14:24:12 +00:00
break ;
case RESET :
2020-07-13 14:55:18 +00:00
PlanFood = PlanSale = PlanPlant = 0 ;
2020-06-15 14:24:12 +00:00
break ;
case EXEC :
2020-07-02 15:00:40 +00:00
print ( " \n So it shall be written, so it shall be done. \n " ) ;
2020-06-15 14:24:12 +00:00
break ;
case CALC :
2020-06-21 14:52:06 +00:00
// microcalc();
2020-06-15 14:24:12 +00:00
break ;
case QUIT :
play = FALSE ;
break ;
}
2020-07-13 14:55:18 +00:00
if ( cmd ! = QUIT )
{
GrainAfterPlan = grainafterplan ( ) ;
LandAfterPlan = landafterplan ( ) ;
}
2020-06-15 14:24:12 +00:00
} while ( cmd ! = EXEC & & cmd ! = QUIT ) ;
return play ;
}
2020-07-13 14:55:18 +00:00
int
popnet ( void )
{
return ( Pop + EvtBrthImm - EvtStarve ) ;
}
2020-06-15 14:24:12 +00:00
void
printdeposed ( void )
{
print ( " Due to this extreme mismanagement you have not only been deposed and executed, but you have also been declared National Fink! \n " ) ;
2020-06-14 06:04:08 +00:00
}
void
printgreeting ( void )
{
2020-07-02 15:00:40 +00:00
print ( " \n O %s One, I beg to report, \n " , HONORIFIC [ nrand ( MAXHONOR + 1 ) ] ) ;
2020-06-14 06:04:08 +00:00
}
void
2020-07-13 14:55:18 +00:00
printEvtLandPr ( void )
2020-06-14 06:04:08 +00:00
{
2020-07-13 14:55:18 +00:00
print ( " The price of land is %d bushels of grain per acre. \n " , EvtLandPr ) ;
2020-06-14 06:04:08 +00:00
}
void
2020-07-15 11:07:44 +00:00
printinitrept ( void )
2020-06-14 06:04:08 +00:00
{
2020-07-15 11:07:44 +00:00
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 " ) ;
2020-06-14 06:04:08 +00:00
}
void
printyearrept ( void )
{
2020-07-15 11:07:44 +00:00
if ( EvtPlague > 0 ) print ( " A horrible plague struck! Half the people died! \n " ) ;
2020-07-13 14:55:18 +00:00
print ( " ______________________________________________________________________ \n " ) ;
print ( " ( YEAR %2d @ \n " , Year ) ;
print ( " | Harvest yield %1d bushels per acre | Population last year %6d | \n " , EvtYield , PrevPop ) ;
2020-07-15 11:07:44 +00:00
print ( " (}_ _ | Grain reserve %6d | Births and immigrants %6d | \n " , GrainAfterPlan , EvtBrthImm ) ;
2020-07-13 14:55:18 +00:00
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 ( " | " ) ;
2020-07-15 11:07:44 +00:00
if ( EvtPlague > 0 ) print ( " %-20s%6d | \n " , " Plague deaths " , EvtPlague ) ;
2020-07-13 14:55:18 +00:00
else print ( " | \n " ) ;
print ( " | \\ | -------------------------------- | -------------------------------- | \n " ) ;
print ( " |_ \\ _ | Balance %6d | Current population %6d | \n " , Grain , Pop ) ;
print ( " | | \n " ) ;
2020-07-15 11:07:44 +00:00
print ( " | Land %6d | \n " , Land ) ;
2020-07-13 14:55:18 +00:00
print ( " |_____________________________________________________________________| \n " ) ;
2020-07-15 11:07:44 +00:00
print ( " (______________________________________________________________________@ \n " ) ;
2020-07-13 14:55:18 +00:00
}
int
salegrain ( void )
{
return ( PlanSale * EvtLandPr ) ;
2020-06-14 06:04:08 +00:00
}
Boolean
scanyes ( char * prompt )
{
int in = 0 ;
2020-06-19 16:19:33 +00:00
if ( write ( CONSCTL , " rawon " , 5 ) ! = 5 ) exits ( " \n can't turn off echo \n " ) ;
2020-06-14 06:04:08 +00:00
while ( in ! = ' y ' & & in ! = ' n ' )
{
2020-07-01 14:56:44 +00:00
print ( " %s [yn] " , prompt ) ;
2020-06-14 06:04:08 +00:00
in = getchar ( ) ;
if ( in = = EOF ) exits ( " \n error reading terminal input \n " ) ;
print ( " %c \n " , in ) ;
}
2020-06-19 16:19:33 +00:00
if ( write ( CONSCTL , " rawoff " , 6 ) ! = 6 ) exits ( " \n can't turn on echo \n " ) ;
2020-06-14 06:04:08 +00:00
print ( " \n " ) ;
return ( in = = ' y ' ? TRUE : FALSE ) ;
}