/* pf.tc - 10/26-29/2007 - implemented lrb char shore(9),health(9),canoe,move(4),ngoing,afloat int hfactor(6),sinkrate,paddle(9) /* Conducts the game. pf [ setup while(stillplaying()) [ whosgoing trip shoreacts ] wrapup ] /* Sets up initial conditions. setup [ hfactor(0)=10 hfactor(1)=9 hfactor(2)=hfactor(3)=8 hfactor(4)=7 paddle(1)=paddle(2)=12 paddle(3)=paddle(4)=9 paddle(5)=7 paddle(6)=5 paddle(7)=paddle(8)=paddle(9)=4 sinkrate=25 ps"seed? " seed=last=gn ] /* Game is still going if any player on shore is alive. stillplaying [ int p while((p=p+1)<=9) if((shore(p)==0)*(health(p)<5)) return 1 ] /* Conducts dialog, determining which players make next trip. whosgoing [ char j,p,i char dup pl"";pl"move " while(1) [ j=getchar if(j=='.') [ /* Trip command. i=0 /* At least one paddler required. while((i=i+1)<=ngoing) if(health(move(i))<5)return ps" nobody to paddle " ] else if(j=='-') [ /* Unload command. ngoing=0 ps" canoe emptied"; pl"" ] else if(j=='s') [ /* Print board. status ps"move " ] else if((j>='1')*(j<='9')) [ /* Put player in canoe. p=j-'0' dup=0 i=0 while((i=i+1)<=ngoing) if(p==move(i)) dup=1 if(dup) ps" already in boat " else if(shore(p)!=canoe) ps" on other shore " else if(ngoing>=4) ps" canoe full " else move(ngoing=ngoing+1)=p ] ] ] /* status prints the board. status [ char k(0),p pl"";pl"" ps "near shore far shore" pl"";pl"" while((p=p+1)<=9) [ if(shore(p)) ps " " pn p;ps " ";pname p;ps" " if(health(p)) [ k="minor att major att minor unattmajor unattdead " k=k+11*(health(p)-1) pft k,k+10 ] pl"" ] if(canoe)ps " " ps " canoe" pl" " if(canoe)ps " " char i while((i=i+1)<=ngoing)pn move(i) pl"" ] /* Conducts a trip across the river. trip [ char i int speed,dist,full afloat=1 while((i=i+1)<=ngoing) speed=speed+paddle(move(i))*hfactor(health(move(i))) speed=speed/(4*ngoing) /* Yards per unit of time. while((dist=dist+speed)<100) [ full=full+sinkrate if(afloat*(full>100)) [ pl"The boat is swamped ..." capsize break ] if(afloat) [ pl"Canoe has";pn 100-dist;ps" yards to go, and is" pn full;ps"% full" if(random(1,4)==1)onefish ] ] i=0 /* The far shore is reached. while((i=i+1)<=ngoing) shore(move(i))=1-shore(move(i)) canoe=1-canoe /* Swap shores of players in canoe, and canoe. ngoing=0 /* Everybody out. pl"trip to " if(canoe)ps"far";else ps"near" ps" shore is complete." ] /* A fish jumped in the boat. This is what happens. onefish [ char p pl"A piranha fish has jumped into the boat. He is swimming" pl"around. He is looking at the toe of the " pname(p=move(random(1,ngoing))) ps"." if(health(p)>4) pl"Oh, well. He's dead anyway ..." else if(p>6) [ pl"The missionary is calm. He is staring back at the" pl"fish. The fish just jumped back into the river." ] else if(p<3) [ pl"The cannibal has speared the fish." if(random(0,1)) [ pl"Unfortunately he made a hole in the" pl"boat, increasing its sink rate 10%." sinkrate=sinkrate+sinkrate/10 ] ] else if(p<5) [ pl"The hunter has panicked. He is rocking tbe boat ..." capsize ] else if(p==5) [ if(random(0,1)) [ pl"The doctor is quick. He shoots the fish full of" pl"a drug." ] else [ pl"The doctor has panicked. He is rocking the boooooat!" capsize ] ] else [ pl"The nurse has panicked. She is rocking the boat." pl"Everybody is yelling at her. Yell - yell - yell." if(random(0,1)) pl"She is calm now, and sits down." else [ pl"She falls out of the boat. She is swimming." swim 6 ] ] ] /* Player p swims to shore. swim char p [ if(health(p)>4) [ pl"Player";pn p;ps" floats ashore." ] else if(random(0,1)) [ pl"Player";pn p;ps" makes it." ] else [ pl"BYTE!! BYTE!! Player";pn p if(random(0,2)) [ if(health(p)==2) health(p)=4 else if(health(p)<2) health(p)=3 ] else if(health(p)<4) health(p)=4 if(health(p)==3) ps" fortunately escapes with minor wounds." else ps " major wounds acquired." ] ] /* The canoe is capsized. capsize [ char p pl"CAPSIZE!! Everybody swim FAST!! The fish are coming .." while((p=p+1)<=ngoing) swim move(p) afloat=0 ] /* When on shore, some players get mended. shoreacts [ char p while((p=p+1)<=9) [ if(shore(p)==shore(5)) [ /* Doctor with at most minor wounds can attend all if(health(5)<4) if(health(5)!=2) /* wounds. if((health(p)==3)+(health(p)==4)) [ health(p)=health(p)-2 pl"";pn p;ps " attended by doctor." ] ] if(shore(p)==shore(6)) [ if(health(6)<4) if(health(6)!=2) if(health(p)==3) [ health(p)=1 pl"";pn p;ps" attended by nurse." ] else if(health(p)==4) /* And also major wounds w/ the doctor's advice. if(shore(5)==shore(6)) if(health(5)<5) [ health(p)=2 pl"";pn p;ps" attended by nurse" ] ] if(health(p)==0) [] /* All done if healthy. else if(random(0,2)) [] /* All done for .67 of sick. else if(health(p)<3) [ /* But some get sicker. if(random(0,2)==0) [ if((health(p)=health(p)+1)==3) health(p)=5 pl"";pn p;ps" is much worse" if(health(p)==5) ps", in fact dead." ] ] else if(health(p)<5) [ health(p)=health(p)+1 pl"";pn p;ps" is much worse" if(health(p)==5) ps", in fact dead." ] ] ] /* Computes score. wrapup [ int s,h,p s=1000 /* Perfect score. while((p=p+1)<=9) [ h=health(p) if(h==5) s=s-100 if(h==4) s=s-30 if(h==3) s=s-15 if(h==2) s=s-10 if(h==1) s=s-5 ] pl"";pl"" status ps"Your score is";pn s ] /* Prints the player's name pname char p [ if(p<3) ps "cannibal" else if(p<5) ps "hunter" else if(p<6) ps "doctor" else if(p<7) ps "nurse" else ps "missionary" ] /* random number generator int last, seed random int low, high [ int range if(last==0) last=seed=99 range=high-low+1 if (last>=16384) last=last-1 /* to get around tc arithmetic bug last=last*seed if(last<0) last= 0-last return low + (last/7) % range ]